1 //===- CanonicalizeAliases.cpp - ThinLTO Support: Canonicalize Aliases ----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Currently this file implements partial alias canonicalization, to 10 // flatten chains of aliases (also done by GlobalOpt, but not on for 11 // O0 compiles). E.g. 12 // @a = alias i8, i8 *@b 13 // @b = alias i8, i8 *@g 14 // 15 // will be converted to: 16 // @a = alias i8, i8 *@g <-- @a is now an alias to base object @g 17 // @b = alias i8, i8 *@g 18 // 19 // Eventually this file will implement full alias canonicalation, so that 20 // all aliasees are private anonymous values. E.g. 21 // @a = alias i8, i8 *@g 22 // @g = global i8 0 23 // 24 // will be converted to: 25 // @0 = private global 26 // @a = alias i8, i8* @0 27 // @g = alias i8, i8* @0 28 // 29 // This simplifies optimization and ThinLTO linking of the original symbols. 30 //===----------------------------------------------------------------------===// 31 32 #include "llvm/Transforms/Utils/CanonicalizeAliases.h" 33 #include "llvm/IR/Operator.h" 34 #include "llvm/IR/ValueHandle.h" 35 #include "llvm/InitializePasses.h" 36 #include "llvm/Pass.h" 37 38 using namespace llvm; 39 40 namespace { 41 42 static Constant *canonicalizeAlias(Constant *C, bool &Changed) { 43 if (auto *GA = dyn_cast<GlobalAlias>(C)) { 44 auto *NewAliasee = canonicalizeAlias(GA->getAliasee(), Changed); 45 if (NewAliasee != GA->getAliasee()) { 46 GA->setAliasee(NewAliasee); 47 Changed = true; 48 } 49 return NewAliasee; 50 } 51 52 auto *CE = dyn_cast<ConstantExpr>(C); 53 if (!CE) 54 return C; 55 56 std::vector<Constant *> Ops; 57 for (Use &U : CE->operands()) 58 Ops.push_back(canonicalizeAlias(cast<Constant>(U), Changed)); 59 return CE->getWithOperands(Ops); 60 } 61 62 /// Convert aliases to canonical form. 63 static bool canonicalizeAliases(Module &M) { 64 bool Changed = false; 65 for (auto &GA : M.aliases()) 66 canonicalizeAlias(&GA, Changed); 67 return Changed; 68 } 69 70 // Legacy pass that canonicalizes aliases. 71 class CanonicalizeAliasesLegacyPass : public ModulePass { 72 73 public: 74 /// Pass identification, replacement for typeid 75 static char ID; 76 77 /// Specify pass name for debug output 78 StringRef getPassName() const override { return "Canonicalize Aliases"; } 79 80 explicit CanonicalizeAliasesLegacyPass() : ModulePass(ID) {} 81 82 bool runOnModule(Module &M) override { return canonicalizeAliases(M); } 83 }; 84 char CanonicalizeAliasesLegacyPass::ID = 0; 85 86 } // anonymous namespace 87 88 PreservedAnalyses CanonicalizeAliasesPass::run(Module &M, 89 ModuleAnalysisManager &AM) { 90 if (!canonicalizeAliases(M)) 91 return PreservedAnalyses::all(); 92 93 return PreservedAnalyses::none(); 94 } 95 96 INITIALIZE_PASS_BEGIN(CanonicalizeAliasesLegacyPass, "canonicalize-aliases", 97 "Canonicalize aliases", false, false) 98 INITIALIZE_PASS_END(CanonicalizeAliasesLegacyPass, "canonicalize-aliases", 99 "Canonicalize aliases", false, false) 100 101 namespace llvm { 102 ModulePass *createCanonicalizeAliasesPass() { 103 return new CanonicalizeAliasesLegacyPass(); 104 } 105 } // namespace llvm 106