Home | History | Annotate | Line # | Download | only in Utils
      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