CanonicalizeAliases.cpp revision 360784
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 38using namespace llvm; 39 40namespace { 41 42static 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. 63static 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. 71class CanonicalizeAliasesLegacyPass : public ModulePass { 72 73public: 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}; 84char CanonicalizeAliasesLegacyPass::ID = 0; 85 86} // anonymous namespace 87 88PreservedAnalyses CanonicalizeAliasesPass::run(Module &M, 89 ModuleAnalysisManager &AM) { 90 if (!canonicalizeAliases(M)) 91 return PreservedAnalyses::all(); 92 93 return PreservedAnalyses::none(); 94} 95 96INITIALIZE_PASS_BEGIN(CanonicalizeAliasesLegacyPass, "canonicalize-aliases", 97 "Canonicalize aliases", false, false) 98INITIALIZE_PASS_END(CanonicalizeAliasesLegacyPass, "canonicalize-aliases", 99 "Canonicalize aliases", false, false) 100 101namespace llvm { 102ModulePass *createCanonicalizeAliasesPass() { 103 return new CanonicalizeAliasesLegacyPass(); 104} 105} // namespace llvm 106