diff --git a/llvm/test/tools/llvm-reduce/custom-delta-passes.ll b/llvm/test/tools/llvm-reduce/custom-delta-passes.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-reduce/custom-delta-passes.ll @@ -0,0 +1,24 @@ +; RUN: llvm-reduce --delta-passes=module-inline-asm --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: FileCheck --check-prefix=CHECK-NOCHANGE %s < %t +; RUN: llvm-reduce --delta-passes=function-bodies --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: FileCheck --check-prefix=CHECK-CHANGE %s < %t +; RUN: llvm-reduce --delta-passes=function-bodies,module-inline-asm --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: FileCheck --check-prefix=CHECK-CHANGE %s < %t + +; RUN: not llvm-reduce --delta-passes=foo --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t 2>&1 | FileCheck %s --check-prefix=ERROR +; RUN: not llvm-reduce --delta-passes='function-bodies;module-inline-asm' --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t 2>&1 | FileCheck %s --check-prefix=ERROR + +; RUN: llvm-reduce --print-delta-passes --test FileCheck %s 2>&1 | FileCheck %s --check-prefix=PRINT + +; CHECK-INTERESTINGNESS: @f + +; CHECK-NOCHANGE: define {{.*}} @f +; CHECK-CHANGE: declare {{.*}} @f + +; ERROR: unknown + +; PRINT: function-bodies + +define void @f() { + ret void +} diff --git a/llvm/tools/llvm-reduce/DeltaManager.h b/llvm/tools/llvm-reduce/DeltaManager.h --- a/llvm/tools/llvm-reduce/DeltaManager.h +++ b/llvm/tools/llvm-reduce/DeltaManager.h @@ -14,9 +14,11 @@ #ifndef LLVM_TOOLS_LLVM_REDUCE_DELTAMANAGER_H #define LLVM_TOOLS_LLVM_REDUCE_DELTAMANAGER_H -#include "TestRunner.h" - namespace llvm { +class raw_ostream; +class TestRunner; + +void printDeltaPasses(raw_ostream &OS); void runDeltaPasses(TestRunner &Tester); } // namespace llvm diff --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp --- a/llvm/tools/llvm-reduce/DeltaManager.cpp +++ b/llvm/tools/llvm-reduce/DeltaManager.cpp @@ -28,25 +28,65 @@ #include "deltas/ReduceModuleInlineAsm.h" #include "deltas/ReduceOperandBundles.h" #include "deltas/ReduceSpecialGlobals.h" +#include "llvm/Support/CommandLine.h" -namespace llvm { - -// TODO: Add CLI option to run only specified Passes (for unit tests) -void runDeltaPasses(TestRunner &Tester) { - reduceSpecialGlobalsDeltaPass(Tester); - reduceAliasesDeltaPass(Tester); - reduceFunctionBodiesDeltaPass(Tester); - reduceFunctionsDeltaPass(Tester); - reduceBasicBlocksDeltaPass(Tester); - reduceGlobalValuesDeltaPass(Tester); - reduceGlobalsInitializersDeltaPass(Tester); - reduceGlobalsDeltaPass(Tester); - reduceMetadataDeltaPass(Tester); - reduceArgumentsDeltaPass(Tester); - reduceInstructionsDeltaPass(Tester); - reduceOperandBundesDeltaPass(Tester); - reduceAttributesDeltaPass(Tester); - reduceModuleInlineAsmDeltaPass(Tester); - // TODO: Implement the remaining Delta Passes +using namespace llvm; + +static cl::opt + DeltaPasses("delta-passes", + cl::desc("Delta passes to run, separated by commas. By " + "default, run all delta passes.")); + +#define DELTA_PASSES \ + DELTA_PASS("special-globals", reduceSpecialGlobalsDeltaPass) \ + DELTA_PASS("aliases", reduceAliasesDeltaPass) \ + DELTA_PASS("function-bodies", reduceFunctionBodiesDeltaPass) \ + DELTA_PASS("functions", reduceFunctionsDeltaPass) \ + DELTA_PASS("basic-blocks", reduceBasicBlocksDeltaPass) \ + DELTA_PASS("global-values", reduceGlobalValuesDeltaPass) \ + DELTA_PASS("global-initializers", reduceGlobalsInitializersDeltaPass) \ + DELTA_PASS("global-variables", reduceGlobalsDeltaPass) \ + DELTA_PASS("metadata", reduceMetadataDeltaPass) \ + DELTA_PASS("arguments", reduceArgumentsDeltaPass) \ + DELTA_PASS("instructions", reduceInstructionsDeltaPass) \ + DELTA_PASS("operand-bundles", reduceOperandBundesDeltaPass) \ + DELTA_PASS("attributes", reduceAttributesDeltaPass) \ + DELTA_PASS("module-inline-asm", reduceModuleInlineAsmDeltaPass) + +static void runAllDeltaPasses(TestRunner &Tester) { +#define DELTA_PASS(NAME, FUNC) FUNC(Tester); + DELTA_PASSES +#undef DELTA_PASS +} + +static void runDeltaPassName(TestRunner &Tester, StringRef PassName) { +#define DELTA_PASS(NAME, FUNC) \ + if (PassName == NAME) { \ + FUNC(Tester); \ + return; \ + } + DELTA_PASSES +#undef DELTA_PASS + errs() << "unknown pass \"" << PassName << "\""; + exit(1); +} + +void llvm::printDeltaPasses(raw_ostream &OS) { + OS << "Delta passes (pass to `--delta-passes=` as a comma separated list):\n"; +#define DELTA_PASS(NAME, FUNC) OS << " " << NAME << "\n"; + DELTA_PASSES +#undef DELTA_PASS +} + +void llvm::runDeltaPasses(TestRunner &Tester) { + if (DeltaPasses.empty()) { + runAllDeltaPasses(Tester); + } else { + StringRef Passes = DeltaPasses; + while (!Passes.empty()) { + auto Split = Passes.split(","); + runDeltaPassName(Tester, Split.first); + Passes = Split.second; + } + } } -} // namespace llvm diff --git a/llvm/tools/llvm-reduce/llvm-reduce.cpp b/llvm/tools/llvm-reduce/llvm-reduce.cpp --- a/llvm/tools/llvm-reduce/llvm-reduce.cpp +++ b/llvm/tools/llvm-reduce/llvm-reduce.cpp @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// #include "DeltaManager.h" +#include "TestRunner.h" #include "llvm/ADT/SmallString.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Verifier.h" @@ -35,6 +36,11 @@ static cl::opt Version("v", cl::desc("Alias for -version"), cl::Hidden, cl::cat(Options)); +static cl::opt + PrintDeltaPasses("print-delta-passes", + cl::desc("Print list of delta passes, passable to " + "--delta-passes as a comma separated list")); + static cl::opt InputFilename(cl::Positional, cl::Required, cl::desc(""), cl::cat(Options)); @@ -101,6 +107,11 @@ cl::ParseCommandLineOptions(Argc, Argv, "LLVM automatic testcase reducer.\n"); + if (PrintDeltaPasses) { + printDeltaPasses(errs()); + return 0; + } + LLVMContext Context; std::unique_ptr OriginalProgram = parseInputFile(InputFilename, Context);