106 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===- CanonicalizeAliases.cpp - ThinLTO Support: Canonicalize Aliases ----===//
 | |
| //
 | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| // See https://llvm.org/LICENSE.txt for license information.
 | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // Currently this file implements partial alias canonicalization, to
 | |
| // flatten chains of aliases (also done by GlobalOpt, but not on for
 | |
| // O0 compiles). E.g.
 | |
| //  @a = alias i8, i8 *@b
 | |
| //  @b = alias i8, i8 *@g
 | |
| //
 | |
| // will be converted to:
 | |
| //  @a = alias i8, i8 *@g  <-- @a is now an alias to base object @g
 | |
| //  @b = alias i8, i8 *@g
 | |
| //
 | |
| // Eventually this file will implement full alias canonicalation, so that
 | |
| // all aliasees are private anonymous values. E.g.
 | |
| //  @a = alias i8, i8 *@g
 | |
| //  @g = global i8 0
 | |
| //
 | |
| // will be converted to:
 | |
| //  @0 = private global
 | |
| //  @a = alias i8, i8* @0
 | |
| //  @g = alias i8, i8* @0
 | |
| //
 | |
| // This simplifies optimization and ThinLTO linking of the original symbols.
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "llvm/Transforms/Utils/CanonicalizeAliases.h"
 | |
| #include "llvm/IR/Operator.h"
 | |
| #include "llvm/IR/ValueHandle.h"
 | |
| #include "llvm/InitializePasses.h"
 | |
| #include "llvm/Pass.h"
 | |
| 
 | |
| using namespace llvm;
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| static Constant *canonicalizeAlias(Constant *C, bool &Changed) {
 | |
|   if (auto *GA = dyn_cast<GlobalAlias>(C)) {
 | |
|     auto *NewAliasee = canonicalizeAlias(GA->getAliasee(), Changed);
 | |
|     if (NewAliasee != GA->getAliasee()) {
 | |
|       GA->setAliasee(NewAliasee);
 | |
|       Changed = true;
 | |
|     }
 | |
|     return NewAliasee;
 | |
|   }
 | |
| 
 | |
|   auto *CE = dyn_cast<ConstantExpr>(C);
 | |
|   if (!CE)
 | |
|     return C;
 | |
| 
 | |
|   std::vector<Constant *> Ops;
 | |
|   for (Use &U : CE->operands())
 | |
|     Ops.push_back(canonicalizeAlias(cast<Constant>(U), Changed));
 | |
|   return CE->getWithOperands(Ops);
 | |
| }
 | |
| 
 | |
| /// Convert aliases to canonical form.
 | |
| static bool canonicalizeAliases(Module &M) {
 | |
|   bool Changed = false;
 | |
|   for (auto &GA : M.aliases())
 | |
|     canonicalizeAlias(&GA, Changed);
 | |
|   return Changed;
 | |
| }
 | |
| 
 | |
| // Legacy pass that canonicalizes aliases.
 | |
| class CanonicalizeAliasesLegacyPass : public ModulePass {
 | |
| 
 | |
| public:
 | |
|   /// Pass identification, replacement for typeid
 | |
|   static char ID;
 | |
| 
 | |
|   /// Specify pass name for debug output
 | |
|   StringRef getPassName() const override { return "Canonicalize Aliases"; }
 | |
| 
 | |
|   explicit CanonicalizeAliasesLegacyPass() : ModulePass(ID) {}
 | |
| 
 | |
|   bool runOnModule(Module &M) override { return canonicalizeAliases(M); }
 | |
| };
 | |
| char CanonicalizeAliasesLegacyPass::ID = 0;
 | |
| 
 | |
| } // anonymous namespace
 | |
| 
 | |
| PreservedAnalyses CanonicalizeAliasesPass::run(Module &M,
 | |
|                                                ModuleAnalysisManager &AM) {
 | |
|   if (!canonicalizeAliases(M))
 | |
|     return PreservedAnalyses::all();
 | |
| 
 | |
|   return PreservedAnalyses::none();
 | |
| }
 | |
| 
 | |
| INITIALIZE_PASS_BEGIN(CanonicalizeAliasesLegacyPass, "canonicalize-aliases",
 | |
|                       "Canonicalize aliases", false, false)
 | |
| INITIALIZE_PASS_END(CanonicalizeAliasesLegacyPass, "canonicalize-aliases",
 | |
|                     "Canonicalize aliases", false, false)
 | |
| 
 | |
| namespace llvm {
 | |
| ModulePass *createCanonicalizeAliasesPass() {
 | |
|   return new CanonicalizeAliasesLegacyPass();
 | |
| }
 | |
| } // namespace llvm
 |