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 /// Make sure GV is visible from both modules. Delete is true if it is
00025 /// being deleted from this module.
00026 /// This also makes sure GV cannot be dropped so that references from
00027 /// the split module remain valid.
00028 static void makeVisible(GlobalValue &GV, bool Delete) {
00029   bool Local = GV.hasLocalLinkage();
00030   if (Local)
00031     GV.setVisibility(GlobalValue::HiddenVisibility);
00032 
00033   if (Local || Delete) {
00034     GV.setLinkage(GlobalValue::ExternalLinkage);
00035     return;
00036   }
00037 
00038   if (!GV.hasLinkOnceLinkage()) {
00039     assert(!GV.isDiscardableIfUnused());
00040     return;
00041   }
00042 
00043   // Map linkonce* to weak* so that llvm doesn't drop this GV.
00044   switch(GV.getLinkage()) {
00045   default:
00046     llvm_unreachable("Unexpected linkage");
00047   case GlobalValue::LinkOnceAnyLinkage:
00048     GV.setLinkage(GlobalValue::WeakAnyLinkage);
00049     return;
00050   case GlobalValue::LinkOnceODRLinkage:
00051     GV.setLinkage(GlobalValue::WeakODRLinkage);
00052     return;
00053   }
00054 }
00055 
00056 namespace {
00057   /// @brief A pass to extract specific functions and their dependencies.
00058   class GVExtractorPass : public ModulePass {
00059     SetVector<GlobalValue *> Named;
00060     bool deleteStuff;
00061   public:
00062     static char ID; // Pass identification, replacement for typeid
00063 
00064     /// FunctionExtractorPass - If deleteFn is true, this pass deletes as the
00065     /// specified function. Otherwise, it deletes as much of the module as
00066     /// possible, except for the function specified.
00067     ///
00068     explicit GVExtractorPass(std::vector<GlobalValue*>& GVs, bool deleteS = true)
00069       : ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS) {}
00070 
00071     bool runOnModule(Module &M) override {
00072       // Visit the global inline asm.
00073       if (!deleteStuff)
00074         M.setModuleInlineAsm("");
00075 
00076       // For simplicity, just give all GlobalValues ExternalLinkage. A trickier
00077       // implementation could figure out which GlobalValues are actually
00078       // referenced by the Named set, and which GlobalValues in the rest of
00079       // the module are referenced by the NamedSet, and get away with leaving
00080       // more internal and private things internal and private. But for now,
00081       // be conservative and simple.
00082 
00083       // Visit the GlobalVariables.
00084       for (Module::global_iterator I = M.global_begin(), E = M.global_end();
00085            I != E; ++I) {
00086         bool Delete =
00087           deleteStuff == (bool)Named.count(I) && !I->isDeclaration();
00088         if (!Delete) {
00089           if (I->hasAvailableExternallyLinkage())
00090             continue;
00091           if (I->getName() == "llvm.global_ctors")
00092             continue;
00093         }
00094 
00095   makeVisible(*I, Delete);
00096 
00097         if (Delete)
00098           I->setInitializer(0);
00099       }
00100 
00101       // Visit the Functions.
00102       for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
00103         bool Delete =
00104           deleteStuff == (bool)Named.count(I) && !I->isDeclaration();
00105         if (!Delete) {
00106           if (I->hasAvailableExternallyLinkage())
00107             continue;
00108         }
00109 
00110   makeVisible(*I, Delete);
00111 
00112         if (Delete)
00113           I->deleteBody();
00114       }
00115 
00116       // Visit the Aliases.
00117       for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
00118            I != E;) {
00119         Module::alias_iterator CurI = I;
00120         ++I;
00121 
00122   bool Delete = deleteStuff == (bool)Named.count(CurI);
00123   makeVisible(*CurI, Delete);
00124 
00125         if (Delete) {
00126           Type *Ty =  CurI->getType()->getElementType();
00127 
00128           CurI->removeFromParent();
00129           llvm::Value *Declaration;
00130           if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
00131             Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage,
00132                                            CurI->getName(), &M);
00133 
00134           } else {
00135             Declaration =
00136               new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage,
00137                                  0, CurI->getName());
00138 
00139           }
00140           CurI->replaceAllUsesWith(Declaration);
00141           delete CurI;
00142         }
00143       }
00144 
00145       return true;
00146     }
00147   };
00148 
00149   char GVExtractorPass::ID = 0;
00150 }
00151 
00152 ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue*>& GVs, 
00153                                          bool deleteFn) {
00154   return new GVExtractorPass(GVs, deleteFn);
00155 }