ExtractGV.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. //===-- ExtractGV.cpp - Global Value extraction pass ----------------------===//
  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. // This pass extracts global values
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/Transforms/IPO/ExtractGV.h"
  13. #include "llvm/IR/Module.h"
  14. #include "llvm/IR/PassManager.h"
  15. #include <algorithm>
  16. using namespace llvm;
  17. /// Make sure GV is visible from both modules. Delete is true if it is
  18. /// being deleted from this module.
  19. /// This also makes sure GV cannot be dropped so that references from
  20. /// the split module remain valid.
  21. static void makeVisible(GlobalValue &GV, bool Delete) {
  22. bool Local = GV.hasLocalLinkage();
  23. if (Local || Delete) {
  24. GV.setLinkage(GlobalValue::ExternalLinkage);
  25. if (Local)
  26. GV.setVisibility(GlobalValue::HiddenVisibility);
  27. return;
  28. }
  29. if (!GV.hasLinkOnceLinkage()) {
  30. assert(!GV.isDiscardableIfUnused());
  31. return;
  32. }
  33. // Map linkonce* to weak* so that llvm doesn't drop this GV.
  34. switch(GV.getLinkage()) {
  35. default:
  36. llvm_unreachable("Unexpected linkage");
  37. case GlobalValue::LinkOnceAnyLinkage:
  38. GV.setLinkage(GlobalValue::WeakAnyLinkage);
  39. return;
  40. case GlobalValue::LinkOnceODRLinkage:
  41. GV.setLinkage(GlobalValue::WeakODRLinkage);
  42. return;
  43. }
  44. }
  45. /// If deleteS is true, this pass deletes the specified global values.
  46. /// Otherwise, it deletes as much of the module as possible, except for the
  47. /// global values specified.
  48. ExtractGVPass::ExtractGVPass(std::vector<GlobalValue *> &GVs, bool deleteS,
  49. bool keepConstInit)
  50. : Named(GVs.begin(), GVs.end()), deleteStuff(deleteS),
  51. keepConstInit(keepConstInit) {}
  52. PreservedAnalyses ExtractGVPass::run(Module &M, ModuleAnalysisManager &) {
  53. // Visit the global inline asm.
  54. if (!deleteStuff)
  55. M.setModuleInlineAsm("");
  56. // For simplicity, just give all GlobalValues ExternalLinkage. A trickier
  57. // implementation could figure out which GlobalValues are actually
  58. // referenced by the Named set, and which GlobalValues in the rest of
  59. // the module are referenced by the NamedSet, and get away with leaving
  60. // more internal and private things internal and private. But for now,
  61. // be conservative and simple.
  62. // Visit the GlobalVariables.
  63. for (GlobalVariable &GV : M.globals()) {
  64. bool Delete = deleteStuff == (bool)Named.count(&GV) &&
  65. !GV.isDeclaration() && (!GV.isConstant() || !keepConstInit);
  66. if (!Delete) {
  67. if (GV.hasAvailableExternallyLinkage())
  68. continue;
  69. if (GV.getName() == "llvm.global_ctors")
  70. continue;
  71. }
  72. makeVisible(GV, Delete);
  73. if (Delete) {
  74. // Make this a declaration and drop it's comdat.
  75. GV.setInitializer(nullptr);
  76. GV.setComdat(nullptr);
  77. }
  78. }
  79. // Visit the Functions.
  80. for (Function &F : M) {
  81. bool Delete = deleteStuff == (bool)Named.count(&F) && !F.isDeclaration();
  82. if (!Delete) {
  83. if (F.hasAvailableExternallyLinkage())
  84. continue;
  85. }
  86. makeVisible(F, Delete);
  87. if (Delete) {
  88. // Make this a declaration and drop it's comdat.
  89. F.deleteBody();
  90. F.setComdat(nullptr);
  91. }
  92. }
  93. // Visit the Aliases.
  94. for (GlobalAlias &GA : llvm::make_early_inc_range(M.aliases())) {
  95. bool Delete = deleteStuff == (bool)Named.count(&GA);
  96. makeVisible(GA, Delete);
  97. if (Delete) {
  98. Type *Ty = GA.getValueType();
  99. GA.removeFromParent();
  100. llvm::Value *Declaration;
  101. if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
  102. Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage,
  103. GA.getAddressSpace(), GA.getName(), &M);
  104. } else {
  105. Declaration = new GlobalVariable(
  106. M, Ty, false, GlobalValue::ExternalLinkage, nullptr, GA.getName());
  107. }
  108. GA.replaceAllUsesWith(Declaration);
  109. delete &GA;
  110. }
  111. }
  112. return PreservedAnalyses::none();
  113. }