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 namespace { 00025 /// @brief A pass to extract specific functions and their dependencies. 00026 class GVExtractorPass : public ModulePass { 00027 SetVector<GlobalValue *> Named; 00028 bool deleteStuff; 00029 public: 00030 static char ID; // Pass identification, replacement for typeid 00031 00032 /// FunctionExtractorPass - If deleteFn is true, this pass deletes as the 00033 /// specified function. Otherwise, it deletes as much of the module as 00034 /// possible, except for the function specified. 00035 /// 00036 explicit GVExtractorPass(std::vector<GlobalValue*>& GVs, bool deleteS = true) 00037 : ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS) {} 00038 00039 bool runOnModule(Module &M) { 00040 // Visit the global inline asm. 00041 if (!deleteStuff) 00042 M.setModuleInlineAsm(""); 00043 00044 // For simplicity, just give all GlobalValues ExternalLinkage. A trickier 00045 // implementation could figure out which GlobalValues are actually 00046 // referenced by the Named set, and which GlobalValues in the rest of 00047 // the module are referenced by the NamedSet, and get away with leaving 00048 // more internal and private things internal and private. But for now, 00049 // be conservative and simple. 00050 00051 // Visit the GlobalVariables. 00052 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 00053 I != E; ++I) { 00054 bool Delete = 00055 deleteStuff == (bool)Named.count(I) && !I->isDeclaration(); 00056 if (!Delete) { 00057 if (I->hasAvailableExternallyLinkage()) 00058 continue; 00059 if (I->getName() == "llvm.global_ctors") 00060 continue; 00061 } 00062 00063 bool Local = I->isDiscardableIfUnused(); 00064 if (Local) 00065 I->setVisibility(GlobalValue::HiddenVisibility); 00066 00067 if (Local || Delete) 00068 I->setLinkage(GlobalValue::ExternalLinkage); 00069 00070 if (Delete) 00071 I->setInitializer(0); 00072 } 00073 00074 // Visit the Functions. 00075 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 00076 bool Delete = 00077 deleteStuff == (bool)Named.count(I) && !I->isDeclaration(); 00078 if (!Delete) { 00079 if (I->hasAvailableExternallyLinkage()) 00080 continue; 00081 } 00082 00083 bool Local = I->isDiscardableIfUnused(); 00084 if (Local) 00085 I->setVisibility(GlobalValue::HiddenVisibility); 00086 00087 if (Local || Delete) 00088 I->setLinkage(GlobalValue::ExternalLinkage); 00089 00090 if (Delete) 00091 I->deleteBody(); 00092 } 00093 00094 // Visit the Aliases. 00095 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); 00096 I != E;) { 00097 Module::alias_iterator CurI = I; 00098 ++I; 00099 00100 if (CurI->isDiscardableIfUnused()) { 00101 CurI->setVisibility(GlobalValue::HiddenVisibility); 00102 CurI->setLinkage(GlobalValue::ExternalLinkage); 00103 } 00104 00105 if (deleteStuff == (bool)Named.count(CurI)) { 00106 Type *Ty = CurI->getType()->getElementType(); 00107 00108 CurI->removeFromParent(); 00109 llvm::Value *Declaration; 00110 if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) { 00111 Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage, 00112 CurI->getName(), &M); 00113 00114 } else { 00115 Declaration = 00116 new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, 00117 0, CurI->getName()); 00118 00119 } 00120 CurI->replaceAllUsesWith(Declaration); 00121 delete CurI; 00122 } 00123 } 00124 00125 return true; 00126 } 00127 }; 00128 00129 char GVExtractorPass::ID = 0; 00130 } 00131 00132 ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue*>& GVs, 00133 bool deleteFn) { 00134 return new GVExtractorPass(GVs, deleteFn); 00135 }