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