LLVM API Documentation
00001 //===-- ExtractGV.cpp - Global Value extraction pass ----------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This pass extracts global values 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Transforms/IPO.h" 00015 #include "llvm/ADT/SetVector.h" 00016 #include "llvm/IR/Constants.h" 00017 #include "llvm/IR/Instructions.h" 00018 #include "llvm/IR/LLVMContext.h" 00019 #include "llvm/IR/Module.h" 00020 #include "llvm/Pass.h" 00021 #include <algorithm> 00022 using namespace llvm; 00023 00024 /// Make sure GV is visible from both modules. Delete is true if it is 00025 /// being deleted from this module. 00026 /// This also makes sure GV cannot be dropped so that references from 00027 /// the split module remain valid. 00028 static void makeVisible(GlobalValue &GV, bool Delete) { 00029 bool Local = GV.hasLocalLinkage(); 00030 if (Local || Delete) { 00031 GV.setLinkage(GlobalValue::ExternalLinkage); 00032 if (Local) 00033 GV.setVisibility(GlobalValue::HiddenVisibility); 00034 return; 00035 } 00036 00037 if (!GV.hasLinkOnceLinkage()) { 00038 assert(!GV.isDiscardableIfUnused()); 00039 return; 00040 } 00041 00042 // Map linkonce* to weak* so that llvm doesn't drop this GV. 00043 switch(GV.getLinkage()) { 00044 default: 00045 llvm_unreachable("Unexpected linkage"); 00046 case GlobalValue::LinkOnceAnyLinkage: 00047 GV.setLinkage(GlobalValue::WeakAnyLinkage); 00048 return; 00049 case GlobalValue::LinkOnceODRLinkage: 00050 GV.setLinkage(GlobalValue::WeakODRLinkage); 00051 return; 00052 } 00053 } 00054 00055 namespace { 00056 /// @brief A pass to extract specific functions and their dependencies. 00057 class GVExtractorPass : public ModulePass { 00058 SetVector<GlobalValue *> Named; 00059 bool deleteStuff; 00060 public: 00061 static char ID; // Pass identification, replacement for typeid 00062 00063 /// FunctionExtractorPass - If deleteFn is true, this pass deletes as the 00064 /// specified function. Otherwise, it deletes as much of the module as 00065 /// possible, except for the function specified. 00066 /// 00067 explicit GVExtractorPass(std::vector<GlobalValue*>& GVs, bool deleteS = true) 00068 : ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS) {} 00069 00070 bool runOnModule(Module &M) override { 00071 // Visit the global inline asm. 00072 if (!deleteStuff) 00073 M.setModuleInlineAsm(""); 00074 00075 // For simplicity, just give all GlobalValues ExternalLinkage. A trickier 00076 // implementation could figure out which GlobalValues are actually 00077 // referenced by the Named set, and which GlobalValues in the rest of 00078 // the module are referenced by the NamedSet, and get away with leaving 00079 // more internal and private things internal and private. But for now, 00080 // be conservative and simple. 00081 00082 // Visit the GlobalVariables. 00083 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 00084 I != E; ++I) { 00085 bool Delete = 00086 deleteStuff == (bool)Named.count(I) && !I->isDeclaration(); 00087 if (!Delete) { 00088 if (I->hasAvailableExternallyLinkage()) 00089 continue; 00090 if (I->getName() == "llvm.global_ctors") 00091 continue; 00092 } 00093 00094 makeVisible(*I, Delete); 00095 00096 if (Delete) 00097 I->setInitializer(nullptr); 00098 } 00099 00100 // Visit the Functions. 00101 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 00102 bool Delete = 00103 deleteStuff == (bool)Named.count(I) && !I->isDeclaration(); 00104 if (!Delete) { 00105 if (I->hasAvailableExternallyLinkage()) 00106 continue; 00107 } 00108 00109 makeVisible(*I, Delete); 00110 00111 if (Delete) 00112 I->deleteBody(); 00113 } 00114 00115 // Visit the Aliases. 00116 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); 00117 I != E;) { 00118 Module::alias_iterator CurI = I; 00119 ++I; 00120 00121 bool Delete = deleteStuff == (bool)Named.count(CurI); 00122 makeVisible(*CurI, Delete); 00123 00124 if (Delete) { 00125 Type *Ty = CurI->getType()->getElementType(); 00126 00127 CurI->removeFromParent(); 00128 llvm::Value *Declaration; 00129 if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) { 00130 Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage, 00131 CurI->getName(), &M); 00132 00133 } else { 00134 Declaration = 00135 new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, 00136 nullptr, CurI->getName()); 00137 00138 } 00139 CurI->replaceAllUsesWith(Declaration); 00140 delete CurI; 00141 } 00142 } 00143 00144 return true; 00145 } 00146 }; 00147 00148 char GVExtractorPass::ID = 0; 00149 } 00150 00151 ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue*>& GVs, 00152 bool deleteFn) { 00153 return new GVExtractorPass(GVs, deleteFn); 00154 }