| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- //===-- ExtractGV.cpp - Global Value extraction pass ----------------------===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- //
- // This pass extracts global values
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/Transforms/IPO.h"
- #include "llvm/ADT/SetVector.h"
- #include "llvm/IR/Constants.h"
- #include "llvm/IR/Instructions.h"
- #include "llvm/IR/LLVMContext.h"
- #include "llvm/IR/Module.h"
- #include "llvm/Pass.h"
- #include <algorithm>
- using namespace llvm;
- /// Make sure GV is visible from both modules. Delete is true if it is
- /// being deleted from this module.
- /// This also makes sure GV cannot be dropped so that references from
- /// the split module remain valid.
- static void makeVisible(GlobalValue &GV, bool Delete) {
- bool Local = GV.hasLocalLinkage();
- if (Local || Delete) {
- GV.setLinkage(GlobalValue::ExternalLinkage);
- if (Local)
- GV.setVisibility(GlobalValue::HiddenVisibility);
- return;
- }
- if (!GV.hasLinkOnceLinkage()) {
- assert(!GV.isDiscardableIfUnused());
- return;
- }
- // Map linkonce* to weak* so that llvm doesn't drop this GV.
- switch(GV.getLinkage()) {
- default:
- llvm_unreachable("Unexpected linkage");
- case GlobalValue::LinkOnceAnyLinkage:
- GV.setLinkage(GlobalValue::WeakAnyLinkage);
- return;
- case GlobalValue::LinkOnceODRLinkage:
- GV.setLinkage(GlobalValue::WeakODRLinkage);
- return;
- }
- }
- namespace {
- /// @brief A pass to extract specific functions and their dependencies.
- class GVExtractorPass : public ModulePass {
- SetVector<GlobalValue *> Named;
- bool deleteStuff;
- public:
- static char ID; // Pass identification, replacement for typeid
- /// FunctionExtractorPass - If deleteFn is true, this pass deletes as the
- /// specified function. Otherwise, it deletes as much of the module as
- /// possible, except for the function specified.
- ///
- explicit GVExtractorPass(std::vector<GlobalValue*>& GVs, bool deleteS = true)
- : ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS) {}
- bool runOnModule(Module &M) override {
- // Visit the global inline asm.
- if (!deleteStuff)
- M.setModuleInlineAsm("");
- // For simplicity, just give all GlobalValues ExternalLinkage. A trickier
- // implementation could figure out which GlobalValues are actually
- // referenced by the Named set, and which GlobalValues in the rest of
- // the module are referenced by the NamedSet, and get away with leaving
- // more internal and private things internal and private. But for now,
- // be conservative and simple.
- // Visit the GlobalVariables.
- for (Module::global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I) {
- bool Delete =
- deleteStuff == (bool)Named.count(I) && !I->isDeclaration();
- if (!Delete) {
- if (I->hasAvailableExternallyLinkage())
- continue;
- if (I->getName() == "llvm.global_ctors")
- continue;
- }
- makeVisible(*I, Delete);
- if (Delete) {
- // Make this a declaration and drop it's comdat.
- I->setInitializer(nullptr);
- I->setComdat(nullptr);
- }
- }
- // Visit the Functions.
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
- bool Delete =
- deleteStuff == (bool)Named.count(I) && !I->isDeclaration();
- if (!Delete) {
- if (I->hasAvailableExternallyLinkage())
- continue;
- }
- makeVisible(*I, Delete);
- if (Delete) {
- // Make this a declaration and drop it's comdat.
- I->deleteBody();
- I->setComdat(nullptr);
- }
- }
- // Visit the Aliases.
- for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
- I != E;) {
- Module::alias_iterator CurI = I;
- ++I;
- bool Delete = deleteStuff == (bool)Named.count(CurI);
- makeVisible(*CurI, Delete);
- if (Delete) {
- Type *Ty = CurI->getType()->getElementType();
- CurI->removeFromParent();
- llvm::Value *Declaration;
- if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
- Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage,
- CurI->getName(), &M);
- } else {
- Declaration =
- new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage,
- nullptr, CurI->getName());
- }
- CurI->replaceAllUsesWith(Declaration);
- delete CurI;
- }
- }
- return true;
- }
- };
- char GVExtractorPass::ID = 0;
- }
- ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue *> &GVs,
- bool deleteFn) {
- return new GVExtractorPass(GVs, deleteFn);
- }
|