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/Constants.h" 34 #include "llvm/InitializePasses.h" 35 #include "llvm/Pass.h" 36 37 using namespace llvm; 38 39 namespace { 40 41 static Constant *canonicalizeAlias(Constant *C, bool &Changed) { 42 if (auto *GA = dyn_cast<GlobalAlias>(C)) { 43 auto *NewAliasee = canonicalizeAlias(GA->getAliasee(), Changed); 44 if (NewAliasee != GA->getAliasee()) { 45 GA->setAliasee(NewAliasee); 46 Changed = true; 47 } 48 return NewAliasee; 49 } 50 51 auto *CE = dyn_cast<ConstantExpr>(C); 52 if (!CE) 53 return C; 54 55 std::vector<Constant *> Ops; 56 for (Use &U : CE->operands()) 57 Ops.push_back(canonicalizeAlias(cast<Constant>(U), Changed)); 58 return CE->getWithOperands(Ops); 59 } 60 61 /// Convert aliases to canonical form. 62 static bool canonicalizeAliases(Module &M) { 63 bool Changed = false; 64 for (auto &GA : M.aliases()) 65 canonicalizeAlias(&GA, Changed); 66 return Changed; 67 } 68 } // anonymous namespace 69 70 PreservedAnalyses CanonicalizeAliasesPass::run(Module &M, 71 ModuleAnalysisManager &AM) { 72 if (!canonicalizeAliases(M)) 73 return PreservedAnalyses::all(); 74 75 return PreservedAnalyses::none(); 76 } 77