forked from OSchip/llvm-project
[llvm-extract] Add -keep-const-init commandline option
Summary: This adds -keep-const-init option to llvm-extract which preserves initializers of used global constants. For example: ``` $ cat a.ll @g = constant i32 0 define i32 @f() { %v = load i32, i32* @g ret i32 %v } $ llvm-extract --func=f a.ll -S -o - @g = external constant i32 define i32 @f() { .. } $ llvm-extract --func=f a.ll -keep-const-init -S -o - @g = constant i32 0 define i32 @f() { .. } ``` This option is useful in checking whether a function that uses a constant global is optimized correctly. Reviewers: jsji, MaskRay, david2050 Reviewed By: MaskRay Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D73833
This commit is contained in:
parent
47f309d963
commit
578d2e2cb1
|
@ -55,6 +55,10 @@ OPTIONS
|
||||||
bitcode. All global variables matching the regular expression will be
|
bitcode. All global variables matching the regular expression will be
|
||||||
extracted. May be specified multiple times.
|
extracted. May be specified multiple times.
|
||||||
|
|
||||||
|
**--keep-const-init**
|
||||||
|
|
||||||
|
Preserve the values of constant globals.
|
||||||
|
|
||||||
**-help**
|
**-help**
|
||||||
|
|
||||||
Print a summary of command line options.
|
Print a summary of command line options.
|
||||||
|
|
|
@ -84,10 +84,12 @@ ModulePass *createEliminateAvailableExternallyPass();
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// createGVExtractionPass - If deleteFn is true, this pass deletes
|
/// createGVExtractionPass - If deleteFn is true, this pass deletes
|
||||||
/// the specified global values. Otherwise, it deletes as much of the module as
|
/// 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<GlobalValue*>& GVs, bool
|
ModulePass *createGVExtractionPass(std::vector<GlobalValue*>& GVs, bool
|
||||||
deleteFn = false);
|
deleteFn = false, bool keepConstInit = false);
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// This pass performs iterative function importing from other modules.
|
/// This pass performs iterative function importing from other modules.
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace {
|
||||||
class GVExtractorPass : public ModulePass {
|
class GVExtractorPass : public ModulePass {
|
||||||
SetVector<GlobalValue *> Named;
|
SetVector<GlobalValue *> Named;
|
||||||
bool deleteStuff;
|
bool deleteStuff;
|
||||||
|
bool keepConstInit;
|
||||||
public:
|
public:
|
||||||
static char ID; // Pass identification, replacement for typeid
|
static char ID; // Pass identification, replacement for typeid
|
||||||
|
|
||||||
|
@ -61,8 +62,9 @@ namespace {
|
||||||
/// Otherwise, it deletes as much of the module as possible, except for the
|
/// Otherwise, it deletes as much of the module as possible, except for the
|
||||||
/// global values specified.
|
/// global values specified.
|
||||||
explicit GVExtractorPass(std::vector<GlobalValue*> &GVs,
|
explicit GVExtractorPass(std::vector<GlobalValue*> &GVs,
|
||||||
bool deleteS = true)
|
bool deleteS = true, bool keepConstInit = false)
|
||||||
: ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS) {}
|
: ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS),
|
||||||
|
keepConstInit(keepConstInit) {}
|
||||||
|
|
||||||
bool runOnModule(Module &M) override {
|
bool runOnModule(Module &M) override {
|
||||||
if (skipModule(M))
|
if (skipModule(M))
|
||||||
|
@ -83,7 +85,8 @@ namespace {
|
||||||
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
|
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
bool Delete =
|
bool Delete =
|
||||||
deleteStuff == (bool)Named.count(&*I) && !I->isDeclaration();
|
deleteStuff == (bool)Named.count(&*I) && !I->isDeclaration() &&
|
||||||
|
(!I->isConstant() || !keepConstInit);
|
||||||
if (!Delete) {
|
if (!Delete) {
|
||||||
if (I->hasAvailableExternallyLinkage())
|
if (I->hasAvailableExternallyLinkage())
|
||||||
continue;
|
continue;
|
||||||
|
@ -156,6 +159,6 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue *> &GVs,
|
ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue *> &GVs,
|
||||||
bool deleteFn) {
|
bool deleteFn, bool keepConstInit) {
|
||||||
return new GVExtractorPass(GVs, deleteFn);
|
return new GVExtractorPass(GVs, deleteFn, keepConstInit);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
; RUN: llvm-extract -func foo -keep-const-init -S < %s | FileCheck %s
|
||||||
|
; RUN: llvm-extract -func foo -S < %s | FileCheck %s --check-prefix=CHECK2
|
||||||
|
|
||||||
|
; CHECK: @cv = constant i32 0
|
||||||
|
; CHECK2: @cv = external constant i32
|
||||||
|
|
||||||
|
@cv = constant i32 0
|
||||||
|
|
||||||
|
define i32 @foo() {
|
||||||
|
%v = load i32, i32* @cv
|
||||||
|
ret i32 %v
|
||||||
|
}
|
|
@ -53,6 +53,10 @@ static cl::opt<bool> DeleteFn("delete",
|
||||||
cl::desc("Delete specified Globals from Module"),
|
cl::desc("Delete specified Globals from Module"),
|
||||||
cl::cat(ExtractCat));
|
cl::cat(ExtractCat));
|
||||||
|
|
||||||
|
static cl::opt<bool> KeepConstInit("keep-const-init",
|
||||||
|
cl::desc("Keep initializers of constants"),
|
||||||
|
cl::cat(ExtractCat));
|
||||||
|
|
||||||
static cl::opt<bool>
|
static cl::opt<bool>
|
||||||
Recursive("recursive", cl::desc("Recursively extract all called functions"),
|
Recursive("recursive", cl::desc("Recursively extract all called functions"),
|
||||||
cl::cat(ExtractCat));
|
cl::cat(ExtractCat));
|
||||||
|
@ -333,7 +337,7 @@ int main(int argc, char **argv) {
|
||||||
{
|
{
|
||||||
std::vector<GlobalValue *> Gvs(GVs.begin(), GVs.end());
|
std::vector<GlobalValue *> Gvs(GVs.begin(), GVs.end());
|
||||||
legacy::PassManager Extract;
|
legacy::PassManager Extract;
|
||||||
Extract.add(createGVExtractionPass(Gvs, DeleteFn));
|
Extract.add(createGVExtractionPass(Gvs, DeleteFn, KeepConstInit));
|
||||||
Extract.run(*M);
|
Extract.run(*M);
|
||||||
|
|
||||||
// Now that we have all the GVs we want, mark the module as fully
|
// Now that we have all the GVs we want, mark the module as fully
|
||||||
|
|
Loading…
Reference in New Issue