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