| //===-- ExtractGV.cpp - Global Value extraction pass ----------------------===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This pass extracts global values | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/Instructions.h" | |
| #include "llvm/LLVMContext.h" | |
| #include "llvm/Module.h" | |
| #include "llvm/Pass.h" | |
| #include "llvm/Constants.h" | |
| #include "llvm/Transforms/IPO.h" | |
| #include "llvm/ADT/SetVector.h" | |
| #include <algorithm> | |
| using namespace llvm; | |
| namespace { | |
| /// @brief A pass to extract specific functions and their dependencies. | |
| class GVExtractorPass : public ModulePass { | |
| SetVector<GlobalValue *> Named; | |
| bool deleteStuff; | |
| public: | |
| static char ID; // Pass identification, replacement for typeid | |
| /// FunctionExtractorPass - If deleteFn is true, this pass deletes as the | |
| /// specified function. Otherwise, it deletes as much of the module as | |
| /// possible, except for the function specified. | |
| /// | |
| explicit GVExtractorPass(std::vector<GlobalValue*>& GVs, bool deleteS = true) | |
| : ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS) {} | |
| bool runOnModule(Module &M) { | |
| // Visit the global inline asm. | |
| if (!deleteStuff) | |
| M.setModuleInlineAsm(""); | |
| // For simplicity, just give all GlobalValues ExternalLinkage. A trickier | |
| // implementation could figure out which GlobalValues are actually | |
| // referenced by the Named set, and which GlobalValues in the rest of | |
| // the module are referenced by the NamedSet, and get away with leaving | |
| // more internal and private things internal and private. But for now, | |
| // be conservative and simple. | |
| // Visit the GlobalVariables. | |
| for (Module::global_iterator I = M.global_begin(), E = M.global_end(); | |
| I != E; ++I) { | |
| if (deleteStuff == (bool)Named.count(I) && !I->isDeclaration()) { | |
| I->setInitializer(0); | |
| } else { | |
| if (I->hasAvailableExternallyLinkage()) | |
| continue; | |
| if (I->getName() == "llvm.global_ctors") | |
| continue; | |
| } | |
| if (I->hasLocalLinkage()) | |
| I->setVisibility(GlobalValue::HiddenVisibility); | |
| I->setLinkage(GlobalValue::ExternalLinkage); | |
| } | |
| // Visit the Functions. | |
| for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { | |
| if (deleteStuff == (bool)Named.count(I) && !I->isDeclaration()) { | |
| I->deleteBody(); | |
| } else { | |
| if (I->hasAvailableExternallyLinkage()) | |
| continue; | |
| } | |
| if (I->hasLocalLinkage()) | |
| I->setVisibility(GlobalValue::HiddenVisibility); | |
| I->setLinkage(GlobalValue::ExternalLinkage); | |
| } | |
| return true; | |
| } | |
| }; | |
| char GVExtractorPass::ID = 0; | |
| } | |
| ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue*>& GVs, | |
| bool deleteFn) { | |
| return new GVExtractorPass(GVs, deleteFn); | |
| } |