CanonicalizeAliases.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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 canonicalation, 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. #include "llvm/Transforms/Utils/CanonicalizeAliases.h"
  32. #include "llvm/IR/Operator.h"
  33. #include "llvm/IR/ValueHandle.h"
  34. #include "llvm/InitializePasses.h"
  35. #include "llvm/Pass.h"
  36. using namespace llvm;
  37. namespace {
  38. static Constant *canonicalizeAlias(Constant *C, bool &Changed) {
  39. if (auto *GA = dyn_cast<GlobalAlias>(C)) {
  40. auto *NewAliasee = canonicalizeAlias(GA->getAliasee(), Changed);
  41. if (NewAliasee != GA->getAliasee()) {
  42. GA->setAliasee(NewAliasee);
  43. Changed = true;
  44. }
  45. return NewAliasee;
  46. }
  47. auto *CE = dyn_cast<ConstantExpr>(C);
  48. if (!CE)
  49. return C;
  50. std::vector<Constant *> Ops;
  51. for (Use &U : CE->operands())
  52. Ops.push_back(canonicalizeAlias(cast<Constant>(U), Changed));
  53. return CE->getWithOperands(Ops);
  54. }
  55. /// Convert aliases to canonical form.
  56. static bool canonicalizeAliases(Module &M) {
  57. bool Changed = false;
  58. for (auto &GA : M.aliases())
  59. canonicalizeAlias(&GA, Changed);
  60. return Changed;
  61. }
  62. // Legacy pass that canonicalizes aliases.
  63. class CanonicalizeAliasesLegacyPass : public ModulePass {
  64. public:
  65. /// Pass identification, replacement for typeid
  66. static char ID;
  67. /// Specify pass name for debug output
  68. StringRef getPassName() const override { return "Canonicalize Aliases"; }
  69. explicit CanonicalizeAliasesLegacyPass() : ModulePass(ID) {}
  70. bool runOnModule(Module &M) override { return canonicalizeAliases(M); }
  71. };
  72. char CanonicalizeAliasesLegacyPass::ID = 0;
  73. } // anonymous namespace
  74. PreservedAnalyses CanonicalizeAliasesPass::run(Module &M,
  75. ModuleAnalysisManager &AM) {
  76. if (!canonicalizeAliases(M))
  77. return PreservedAnalyses::all();
  78. return PreservedAnalyses::none();
  79. }
  80. INITIALIZE_PASS_BEGIN(CanonicalizeAliasesLegacyPass, "canonicalize-aliases",
  81. "Canonicalize aliases", false, false)
  82. INITIALIZE_PASS_END(CanonicalizeAliasesLegacyPass, "canonicalize-aliases",
  83. "Canonicalize aliases", false, false)
  84. namespace llvm {
  85. ModulePass *createCanonicalizeAliasesPass() {
  86. return new CanonicalizeAliasesLegacyPass();
  87. }
  88. } // namespace llvm