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 namespace { 25 /// @brief A pass to extract specific functions and their dependencies. 26 class GVExtractorPass : public ModulePass { 27 SetVector<GlobalValue *> Named; 28 bool deleteStuff; 29 public: 30 static char ID; // Pass identification, replacement for typeid 31 32 /// FunctionExtractorPass - If deleteFn is true, this pass deletes as the 33 /// specified function. Otherwise, it deletes as much of the module as 34 /// possible, except for the function specified. 35 /// 36 explicit GVExtractorPass(std::vector<GlobalValue*>& GVs, bool deleteS = true) 37 : ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS) {} 38 39 bool runOnModule(Module &M) { 40 // Visit the global inline asm. 41 if (!deleteStuff) 42 M.setModuleInlineAsm(""); 43 44 // For simplicity, just give all GlobalValues ExternalLinkage. A trickier 45 // implementation could figure out which GlobalValues are actually 46 // referenced by the Named set, and which GlobalValues in the rest of 47 // the module are referenced by the NamedSet, and get away with leaving 48 // more internal and private things internal and private. But for now, 49 // be conservative and simple. 50 51 // Visit the GlobalVariables. 52 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 53 I != E; ++I) { 54 bool Delete = 55 deleteStuff == (bool)Named.count(I) && !I->isDeclaration(); 56 if (!Delete) { 57 if (I->hasAvailableExternallyLinkage()) 58 continue; 59 if (I->getName() == "llvm.global_ctors") 60 continue; 61 } 62 63 bool Local = I->isDiscardableIfUnused(); 64 if (Local) 65 I->setVisibility(GlobalValue::HiddenVisibility); 66 67 if (Local || Delete) 68 I->setLinkage(GlobalValue::ExternalLinkage); 69 70 if (Delete) 71 I->setInitializer(0); 72 } 73 74 // Visit the Functions. 75 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 76 bool Delete = 77 deleteStuff == (bool)Named.count(I) && !I->isDeclaration(); 78 if (!Delete) { 79 if (I->hasAvailableExternallyLinkage()) 80 continue; 81 } 82 83 bool Local = I->isDiscardableIfUnused(); 84 if (Local) 85 I->setVisibility(GlobalValue::HiddenVisibility); 86 87 if (Local || Delete) 88 I->setLinkage(GlobalValue::ExternalLinkage); 89 90 if (Delete) 91 I->deleteBody(); 92 } 93 94 // Visit the Aliases. 95 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); 96 I != E;) { 97 Module::alias_iterator CurI = I; 98 ++I; 99 100 if (CurI->isDiscardableIfUnused()) { 101 CurI->setVisibility(GlobalValue::HiddenVisibility); 102 CurI->setLinkage(GlobalValue::ExternalLinkage); 103 } 104 105 if (deleteStuff == (bool)Named.count(CurI)) { 106 Type *Ty = CurI->getType()->getElementType(); 107 108 CurI->removeFromParent(); 109 llvm::Value *Declaration; 110 if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) { 111 Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage, 112 CurI->getName(), &M); 113 114 } else { 115 Declaration = 116 new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, 117 0, CurI->getName()); 118 119 } 120 CurI->replaceAllUsesWith(Declaration); 121 delete CurI; 122 } 123 } 124 125 return true; 126 } 127 }; 128 129 char GVExtractorPass::ID = 0; 130 } 131 132 ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue*>& GVs, 133 bool deleteFn) { 134 return new GVExtractorPass(GVs, deleteFn); 135 } 136