LLVM API Documentation

ExtractGV.cpp
Go to the documentation of this file.
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 }