aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/lib/Transforms/Utils/CanonicalizeAliases.cpp
blob: 295fc6710887e393ce810f28ef516637bb6a626b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//===- 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