diff --git a/llvm/docs/CommandGuide/llvm-extract.rst b/llvm/docs/CommandGuide/llvm-extract.rst --- a/llvm/docs/CommandGuide/llvm-extract.rst +++ b/llvm/docs/CommandGuide/llvm-extract.rst @@ -55,6 +55,10 @@ bitcode. All global variables matching the regular expression will be extracted. May be specified multiple times. +**--keep-constinit** + + Preserve the values of constant globals. + **-help** Print a summary of command line options. diff --git a/llvm/include/llvm/Transforms/IPO.h b/llvm/include/llvm/Transforms/IPO.h --- a/llvm/include/llvm/Transforms/IPO.h +++ b/llvm/include/llvm/Transforms/IPO.h @@ -84,10 +84,12 @@ //===----------------------------------------------------------------------===// /// createGVExtractionPass - If deleteFn is true, this pass deletes /// the specified global values. Otherwise, it deletes as much of the module as -/// possible, except for the global values specified. +/// possible, except for the global values specified. If keepConstInit is true, +/// the initializers of global constants are not deleted even if they are +/// unused. /// ModulePass *createGVExtractionPass(std::vector& GVs, bool - deleteFn = false); + deleteFn = false, bool keepConstInit = false); //===----------------------------------------------------------------------===// /// This pass performs iterative function importing from other modules. diff --git a/llvm/lib/Transforms/IPO/ExtractGV.cpp b/llvm/lib/Transforms/IPO/ExtractGV.cpp --- a/llvm/lib/Transforms/IPO/ExtractGV.cpp +++ b/llvm/lib/Transforms/IPO/ExtractGV.cpp @@ -54,6 +54,7 @@ class GVExtractorPass : public ModulePass { SetVector Named; bool deleteStuff; + bool keepConstInit; public: static char ID; // Pass identification, replacement for typeid @@ -61,8 +62,9 @@ /// Otherwise, it deletes as much of the module as possible, except for the /// global values specified. explicit GVExtractorPass(std::vector &GVs, - bool deleteS = true) - : ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS) {} + bool deleteS = true, bool keepConstInit = false) + : ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS), + keepConstInit(keepConstInit) {} bool runOnModule(Module &M) override { if (skipModule(M)) @@ -83,7 +85,8 @@ for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { bool Delete = - deleteStuff == (bool)Named.count(&*I) && !I->isDeclaration(); + deleteStuff == (bool)Named.count(&*I) && !I->isDeclaration() && + (!I->isConstant() || !keepConstInit); if (!Delete) { if (I->hasAvailableExternallyLinkage()) continue; @@ -156,6 +159,6 @@ } ModulePass *llvm::createGVExtractionPass(std::vector &GVs, - bool deleteFn) { - return new GVExtractorPass(GVs, deleteFn); + bool deleteFn, bool keepConstInit) { + return new GVExtractorPass(GVs, deleteFn, keepConstInit); } diff --git a/llvm/test/tools/llvm-extract/keep-constinit.ll b/llvm/test/tools/llvm-extract/keep-constinit.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-extract/keep-constinit.ll @@ -0,0 +1,10 @@ +; RUN: llvm-extract -func foo -keep-constinit -S < %s | FileCheck %s + +; CHECK: @cv = constant i32 0 + +@cv = constant i32 0 + +define i32 @foo() { + %v = load i32, i32* @cv + ret i32 %v +} diff --git a/llvm/tools/llvm-extract/llvm-extract.cpp b/llvm/tools/llvm-extract/llvm-extract.cpp --- a/llvm/tools/llvm-extract/llvm-extract.cpp +++ b/llvm/tools/llvm-extract/llvm-extract.cpp @@ -53,6 +53,10 @@ cl::desc("Delete specified Globals from Module"), cl::cat(ExtractCat)); +static cl::opt KeepConstInit("keep-constinit", + cl::desc("Keep initializers of constants"), + cl::cat(ExtractCat)); + static cl::opt Recursive("recursive", cl::desc("Recursively extract all called functions"), cl::cat(ExtractCat)); @@ -333,7 +337,7 @@ { std::vector Gvs(GVs.begin(), GVs.end()); legacy::PassManager Extract; - Extract.add(createGVExtractionPass(Gvs, DeleteFn)); + Extract.add(createGVExtractionPass(Gvs, DeleteFn, KeepConstInit)); Extract.run(*M); // Now that we have all the GVs we want, mark the module as fully