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