--- /dev/null
+; 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
+}
#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<std::string>
+ 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
//===----------------------------------------------------------------------===//
#include "DeltaManager.h"
+#include "TestRunner.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Verifier.h"
static cl::opt<bool> Version("v", cl::desc("Alias for -version"), cl::Hidden,
cl::cat(Options));
+static cl::opt<bool>
+ PrintDeltaPasses("print-delta-passes",
+ cl::desc("Print list of delta passes, passable to "
+ "--delta-passes as a comma separated list"));
+
static cl::opt<std::string> InputFilename(cl::Positional, cl::Required,
cl::desc("<input llvm ll/bc file>"),
cl::cat(Options));
cl::ParseCommandLineOptions(Argc, Argv, "LLVM automatic testcase reducer.\n");
+ if (PrintDeltaPasses) {
+ printDeltaPasses(errs());
+ return 0;
+ }
+
LLVMContext Context;
std::unique_ptr<Module> OriginalProgram =
parseInputFile(InputFilename, Context);