Home | History | Annotate | Download | only in IPO
      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"
     15 #include "llvm/LLVMContext.h"
     16 #include "llvm/Module.h"
     17 #include "llvm/Pass.h"
     18 #include "llvm/Constants.h"
     19 #include "llvm/Transforms/IPO.h"
     20 #include "llvm/ADT/SetVector.h"
     21 #include <algorithm>
     22 using namespace llvm;
     23 
     24 namespace {
     25   /// @brief A pass to extract specific functions and their dependencies.
     26   class GVExtractorPass : public ModulePass {
     27     SetVector<GlobalValue *> Named;
     28     bool deleteStuff;
     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     ///
     36     explicit GVExtractorPass(std::vector<GlobalValue*>& GVs, bool deleteS = true)
     37       : ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS) {}
     38 
     39     bool runOnModule(Module &M) {
     40       // Visit the global inline asm.
     41       if (!deleteStuff)
     42         M.setModuleInlineAsm("");
     43 
     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.
     50 
     51       // Visit the GlobalVariables.
     52       for (Module::global_iterator I = M.global_begin(), E = M.global_end();
     53            I != E; ++I) {
     54         if (deleteStuff == (bool)Named.count(I) && !I->isDeclaration()) {
     55           I->setInitializer(0);
     56 	} else {
     57 	  if (I->hasAvailableExternallyLinkage())
     58 	    continue;
     59 	  if (I->getName() == "llvm.global_ctors")
     60 	    continue;
     61 	}
     62 
     63         if (I->hasLocalLinkage())
     64           I->setVisibility(GlobalValue::HiddenVisibility);
     65         I->setLinkage(GlobalValue::ExternalLinkage);
     66       }
     67 
     68       // Visit the Functions.
     69       for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
     70         if (deleteStuff == (bool)Named.count(I) && !I->isDeclaration()) {
     71           I->deleteBody();
     72 	} else {
     73 	  if (I->hasAvailableExternallyLinkage())
     74 	    continue;
     75 	}
     76 
     77         if (I->hasLocalLinkage())
     78           I->setVisibility(GlobalValue::HiddenVisibility);
     79         I->setLinkage(GlobalValue::ExternalLinkage);
     80       }
     81 
     82       return true;
     83     }
     84   };
     85 
     86   char GVExtractorPass::ID = 0;
     87 }
     88 
     89 ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue*>& GVs,
     90                                          bool deleteFn) {
     91   return new GVExtractorPass(GVs, deleteFn);
     92 }
     93