Andrew Lenharth | d245a8a | 2008-03-07 19:51:57 +0000 | [diff] [blame] | 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/Instructions.h" |
Owen Anderson | 14ce9ef | 2009-07-06 01:34:54 +0000 | [diff] [blame] | 15 | #include "llvm/LLVMContext.h" |
Andrew Lenharth | d245a8a | 2008-03-07 19:51:57 +0000 | [diff] [blame] | 16 | #include "llvm/Module.h" |
| 17 | #include "llvm/Pass.h" |
| 18 | #include "llvm/Constants.h" |
| 19 | #include "llvm/Transforms/IPO.h" |
Dan Gohman | b4e3cda | 2010-08-26 00:22:55 +0000 | [diff] [blame] | 20 | #include "llvm/ADT/SetVector.h" |
Ted Kremenek | 58d5e05 | 2008-03-09 18:32:50 +0000 | [diff] [blame] | 21 | #include <algorithm> |
Andrew Lenharth | d245a8a | 2008-03-07 19:51:57 +0000 | [diff] [blame] | 22 | using namespace llvm; |
| 23 | |
| 24 | namespace { |
| 25 | /// @brief A pass to extract specific functions and their dependencies. |
Nick Lewycky | 6726b6d | 2009-10-25 06:33:48 +0000 | [diff] [blame] | 26 | class GVExtractorPass : public ModulePass { |
Dan Gohman | b4e3cda | 2010-08-26 00:22:55 +0000 | [diff] [blame] | 27 | SetVector<GlobalValue *> Named; |
Andrew Lenharth | d245a8a | 2008-03-07 19:51:57 +0000 | [diff] [blame] | 28 | bool deleteStuff; |
Andrew Lenharth | d245a8a | 2008-03-07 19:51:57 +0000 | [diff] [blame] | 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 | /// |
Dan Gohman | b4e3cda | 2010-08-26 00:22:55 +0000 | [diff] [blame] | 36 | explicit GVExtractorPass(std::vector<GlobalValue*>& GVs, bool deleteS = true) |
| 37 | : ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS) {} |
Andrew Lenharth | d245a8a | 2008-03-07 19:51:57 +0000 | [diff] [blame] | 38 | |
| 39 | bool runOnModule(Module &M) { |
Dan Gohman | b4e3cda | 2010-08-26 00:22:55 +0000 | [diff] [blame] | 40 | // Visit the global inline asm. |
| 41 | if (!deleteStuff) |
| 42 | M.setModuleInlineAsm(""); |
Andrew Lenharth | d245a8a | 2008-03-07 19:51:57 +0000 | [diff] [blame] | 43 | |
Dan Gohman | b4e3cda | 2010-08-26 00:22:55 +0000 | [diff] [blame] | 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. |
Andrew Lenharth | d245a8a | 2008-03-07 19:51:57 +0000 | [diff] [blame] | 50 | |
Dan Gohman | b4e3cda | 2010-08-26 00:22:55 +0000 | [diff] [blame] | 51 | // Visit the GlobalVariables. |
| 52 | for (Module::global_iterator I = M.global_begin(), E = M.global_end(); |
Bob Wilson | edf0174 | 2010-09-23 17:25:06 +0000 | [diff] [blame] | 53 | I != E; ++I) { |
| 54 | if (I->hasLocalLinkage()) |
| 55 | I->setVisibility(GlobalValue::HiddenVisibility); |
| 56 | I->setLinkage(GlobalValue::ExternalLinkage); |
| 57 | if (deleteStuff == (bool)Named.count(I) && !I->isDeclaration()) |
| 58 | I->setInitializer(0); |
| 59 | } |
Dan Gohman | b4e3cda | 2010-08-26 00:22:55 +0000 | [diff] [blame] | 60 | |
| 61 | // Visit the Functions. |
Bob Wilson | edf0174 | 2010-09-23 17:25:06 +0000 | [diff] [blame] | 62 | for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { |
| 63 | if (I->hasLocalLinkage()) |
| 64 | I->setVisibility(GlobalValue::HiddenVisibility); |
| 65 | I->setLinkage(GlobalValue::ExternalLinkage); |
| 66 | if (deleteStuff == (bool)Named.count(I) && !I->isDeclaration()) |
| 67 | I->deleteBody(); |
| 68 | } |
Andrew Lenharth | d245a8a | 2008-03-07 19:51:57 +0000 | [diff] [blame] | 69 | |
Andrew Lenharth | d245a8a | 2008-03-07 19:51:57 +0000 | [diff] [blame] | 70 | return true; |
| 71 | } |
| 72 | }; |
| 73 | |
| 74 | char GVExtractorPass::ID = 0; |
| 75 | } |
| 76 | |
| 77 | ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue*>& GVs, |
Dan Gohman | b4e3cda | 2010-08-26 00:22:55 +0000 | [diff] [blame] | 78 | bool deleteFn) { |
| 79 | return new GVExtractorPass(GVs, deleteFn); |
Andrew Lenharth | d245a8a | 2008-03-07 19:51:57 +0000 | [diff] [blame] | 80 | } |