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