ExtractGV.cpp 5.0 KB

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