ExtractGV.cpp 5.0 KB

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