From eae3e5a4946f848905da452991eb6fbf39981d72 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Sun, 26 Jul 2020 00:56:36 +0300 Subject: [PATCH] [Reduce] Argument reduction: do deal with function declarations We can happily turn function definitions into declarations, thus obscuring their argument from being elided by this pass. I don't believe there is a good reason to just ignore declarations. likely even proper llvm intrinsics ones, at worst the input becomes uninteresting. The other question here is that all these transforms are all-or-nothing. In some cases, should we be treating each use separately? The main blocker here seemed to be that llvm::CloneFunctionInto() does `&OldFunc->front()`, which inserts a nullptr into a densemap, which is not happy about it and asserts. --- lib/Transforms/Utils/CloneFunction.cpp | 5 ++++ ...ultiple-use-of-args-in-same-instruction.py | 13 ---------- ...-use-of-global-vars-in-same-instruction.py | 13 ---------- test/Reduce/remove-args-from-declaration.ll | 24 +++++++++++++++++++ ...ultiple-use-of-args-in-same-instruction.ll | 9 +++---- ...-use-of-global-vars-in-same-instruction.ll | 12 +++++----- tools/llvm-reduce/deltas/ReduceArguments.cpp | 4 ++-- 7 files changed, 42 insertions(+), 38 deletions(-) delete mode 100644 test/Reduce/Inputs/remove-multiple-use-of-args-in-same-instruction.py delete mode 100644 test/Reduce/Inputs/remove-multiple-use-of-global-vars-in-same-instruction.py create mode 100644 test/Reduce/remove-args-from-declaration.ll diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp index 788983c1569..957e4028bae 100644 --- a/lib/Transforms/Utils/CloneFunction.cpp +++ b/lib/Transforms/Utils/CloneFunction.cpp @@ -147,6 +147,11 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, TypeMapper, Materializer)); } + // Everything else beyond this point deals with function instructions, + // so if we are dealing with a function declaration, we're done. + if (OldFunc->isDeclaration()) + return; + // When we remap instructions, we want to avoid duplicating inlined // DISubprograms, so record all subprograms we find as we duplicate // instructions and then freeze them in the MD map. diff --git a/test/Reduce/Inputs/remove-multiple-use-of-args-in-same-instruction.py b/test/Reduce/Inputs/remove-multiple-use-of-args-in-same-instruction.py deleted file mode 100644 index 93fa5c0bc29..00000000000 --- a/test/Reduce/Inputs/remove-multiple-use-of-args-in-same-instruction.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys - -FunctionCallPresent = False - -input = open(sys.argv[1], "r") -for line in input: - if "call void @use" in line: - FunctionCallPresent = True - -if FunctionCallPresent: - sys.exit(0) # Interesting! - -sys.exit(1) diff --git a/test/Reduce/Inputs/remove-multiple-use-of-global-vars-in-same-instruction.py b/test/Reduce/Inputs/remove-multiple-use-of-global-vars-in-same-instruction.py deleted file mode 100644 index 93fa5c0bc29..00000000000 --- a/test/Reduce/Inputs/remove-multiple-use-of-global-vars-in-same-instruction.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys - -FunctionCallPresent = False - -input = open(sys.argv[1], "r") -for line in input: - if "call void @use" in line: - FunctionCallPresent = True - -if FunctionCallPresent: - sys.exit(0) # Interesting! - -sys.exit(1) diff --git a/test/Reduce/remove-args-from-declaration.ll b/test/Reduce/remove-args-from-declaration.ll new file mode 100644 index 00000000000..f476495c573 --- /dev/null +++ b/test/Reduce/remove-args-from-declaration.ll @@ -0,0 +1,24 @@ +; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s + +; CHECK-INTERESTINGNESS-LABEL: @interesting( +; CHECK-INTERESTINGNESS-SAME: i32 +; CHECK-FINAL: declare void @interesting(i32) +declare void @interesting(i32 %uninteresting1, i32 %interesting, i32 %uninteresting2) + +; CHECK-INTERESTINGNESS-LABEL: @interesting2( +; CHECK-INTERESTINGNESS-SAME: i32 +; CHECK-FINAL: declare void @interesting2(i32) +declare void @interesting2(i32 %uninteresting1, i32 %interesting, i32 %uninteresting2) + +; CHECK-INTERESTINGNESS-LABEL: @callee( +; CHECK-INTERESTINGNESS-SAME: i32 %interesting +; CHECK-FINAL: define void @callee(i32 %interesting) { +define void @callee(i32 %uninteresting1, i32 %interesting, i32 %uninteresting2) { +; CHECK-INTERESTINGNESS: call void @interesting2( +; CHECK-INTERESTINGNESS-SAME: i32 %interesting +; CHECK-FINAL: call void @interesting2(i32 %interesting) + call void @interesting2(i32 %uninteresting1, i32 %interesting, i32 %uninteresting2) +; CHECK-ALL: ret void + ret void +} diff --git a/test/Reduce/remove-multiple-use-of-args-in-same-instruction.ll b/test/Reduce/remove-multiple-use-of-args-in-same-instruction.ll index 21a638f1e6b..cd23d6e6160 100644 --- a/test/Reduce/remove-multiple-use-of-args-in-same-instruction.ll +++ b/test/Reduce/remove-multiple-use-of-args-in-same-instruction.ll @@ -1,14 +1,15 @@ ; Test that llvm-reduce can remove uninteresting function arguments from function definitions as well as their calls. ; -; RUN: llvm-reduce --test %python --test-arg %p/Inputs/remove-multiple-use-of-args-in-same-instruction.py %s -o %t -; RUN: cat %t | FileCheck -implicit-check-not=uninteresting %s +; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s +; CHECK-ALL: declare void @use(i32, i32, i32) declare void @use(i32, i32, i32) -; CHECK-LABEL: @interesting(i32 %uninteresting1, i32 %uninteresting2, i32 %uninteresting3 +; CHECK-ALL: @interesting(i32 %uninteresting1, i32 %uninteresting2, i32 %uninteresting3 define void @interesting(i32 %uninteresting1, i32 %uninteresting2, i32 %uninteresting3) { entry: - ; CHECK: call void @use(i32 %uninteresting1, i32 %uninteresting2, i32 %uninteresting3) + ; CHECK-ALL: call void @use(i32 %uninteresting1, i32 %uninteresting2, i32 %uninteresting3) call void @use(i32 %uninteresting1, i32 %uninteresting2, i32 %uninteresting3) call void @use(i32 %uninteresting1, i32 %uninteresting2, i32 %uninteresting3) call void @use(i32 %uninteresting1, i32 %uninteresting2, i32 %uninteresting3) diff --git a/test/Reduce/remove-multiple-use-of-global-vars-in-same-instruction.ll b/test/Reduce/remove-multiple-use-of-global-vars-in-same-instruction.ll index 4400bc818e5..6d62bd2938d 100644 --- a/test/Reduce/remove-multiple-use-of-global-vars-in-same-instruction.ll +++ b/test/Reduce/remove-multiple-use-of-global-vars-in-same-instruction.ll @@ -1,11 +1,11 @@ ; Test that llvm-reduce can remove uninteresting function arguments from function definitions as well as their calls. ; -; RUN: llvm-reduce --test %python --test-arg %p/Inputs/remove-multiple-use-of-global-vars-in-same-instruction.py %s -o %t -; RUN: cat %t | FileCheck -implicit-check-not=uninteresting %s +; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s -; CHECK: @uninteresting1 = global -; CHECK: @uninteresting2 = global -; CHECK: @uninteresting3 = global +; CHECK-ALL: @uninteresting1 = global +; CHECK-ALL: @uninteresting2 = global +; CHECK-ALL: @uninteresting3 = global @uninteresting1 = global i32 0, align 4 @uninteresting2 = global i32 0, align 4 @uninteresting3 = global i32 0, align 4 @@ -15,7 +15,7 @@ declare void @use(i32*, i32*, i32*) ; CHECK-LABEL: @interesting() define void @interesting() { entry: - ; CHECK: call void @use(i32* @uninteresting1, i32* @uninteresting2, i32* @uninteresting3) + ; CHECK-ALL: call void @use(i32* @uninteresting1, i32* @uninteresting2, i32* @uninteresting3) call void @use(i32* @uninteresting1, i32* @uninteresting2, i32* @uninteresting3) call void @use(i32* @uninteresting1, i32* @uninteresting2, i32* @uninteresting3) call void @use(i32* @uninteresting1, i32* @uninteresting2, i32* @uninteresting3) diff --git a/tools/llvm-reduce/deltas/ReduceArguments.cpp b/tools/llvm-reduce/deltas/ReduceArguments.cpp index 1eafc2c560d..9488d71b71c 100644 --- a/tools/llvm-reduce/deltas/ReduceArguments.cpp +++ b/tools/llvm-reduce/deltas/ReduceArguments.cpp @@ -48,7 +48,7 @@ static void extractArgumentsFromModule(std::vector ChunksToKeep, std::vector Funcs; // Get inside-chunk arguments, as well as their parent function for (auto &F : *Program) - if (!F.isDeclaration()) { + if (!F.arg_empty()) { Funcs.push_back(&F); for (auto &A : F.args()) if (O.shouldKeep()) @@ -108,7 +108,7 @@ static int countArguments(Module *Program) { outs() << "Param Index Reference:\n"; int ArgsCount = 0; for (auto &F : *Program) - if (!F.isDeclaration() && F.arg_size()) { + if (!F.arg_empty()) { outs() << " " << F.getName() << "\n"; for (auto &A : F.args()) outs() << "\t" << ++ArgsCount << ": " << A.getName() << "\n";