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