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