LLVM  mainline
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           // Make this a declaration and drop it's comdat.
00098           I->setInitializer(nullptr);
00099           I->setComdat(nullptr);
00100         }
00101       }
00102 
00103       // Visit the Functions.
00104       for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
00105         bool Delete =
00106             deleteStuff == (bool)Named.count(&*I) && !I->isDeclaration();
00107         if (!Delete) {
00108           if (I->hasAvailableExternallyLinkage())
00109             continue;
00110         }
00111 
00112         makeVisible(*I, Delete);
00113 
00114         if (Delete) {
00115           // Make this a declaration and drop it's comdat.
00116           I->deleteBody();
00117           I->setComdat(nullptr);
00118         }
00119       }
00120 
00121       // Visit the Aliases.
00122       for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
00123            I != E;) {
00124         Module::alias_iterator CurI = I;
00125         ++I;
00126 
00127         bool Delete = deleteStuff == (bool)Named.count(&*CurI);
00128         makeVisible(*CurI, Delete);
00129 
00130         if (Delete) {
00131           Type *Ty =  CurI->getValueType();
00132 
00133           CurI->removeFromParent();
00134           llvm::Value *Declaration;
00135           if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
00136             Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage,
00137                                            CurI->getName(), &M);
00138 
00139           } else {
00140             Declaration =
00141               new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage,
00142                                  nullptr, CurI->getName());
00143 
00144           }
00145           CurI->replaceAllUsesWith(Declaration);
00146           delete &*CurI;
00147         }
00148       }
00149 
00150       return true;
00151     }
00152   };
00153 
00154   char GVExtractorPass::ID = 0;
00155 }
00156 
00157 ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue *> &GVs,
00158                                          bool deleteFn) {
00159   return new GVExtractorPass(GVs, deleteFn);
00160 }