1 //===- CanonicalizeAliases.cpp - ThinLTO Support: Canonicalize Aliases ----===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Currently this file implements partial alias canonicalization, to 11 // flatten chains of aliases (also done by GlobalOpt, but not on for 12 // O0 compiles). E.g. 13 // @a = alias i8, i8 *@b 14 // @b = alias i8, i8 *@g 15 // 16 // will be converted to: 17 // @a = alias i8, i8 *@g <-- @a is now an alias to base object @g 18 // @b = alias i8, i8 *@g 19 // 20 // Eventually this file will implement full alias canonicalation, so that 21 // all aliasees are private anonymous values. E.g. 22 // @a = alias i8, i8 *@g 23 // @g = global i8 0 24 // 25 // will be converted to: 26 // @0 = private global 27 // @a = alias i8, i8* @0 28 // @g = alias i8, i8* @0 29 // 30 // This simplifies optimization and ThinLTO linking of the original symbols. 31 //===----------------------------------------------------------------------===// 32 33 #include "llvm/Transforms/Utils/CanonicalizeAliases.h" 34 35 #include "llvm/IR/Operator.h" 36 #include "llvm/IR/ValueHandle.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