Index: llvm/test/tools/llvm-reduce/skip-delta-passes.ll =================================================================== --- /dev/null +++ llvm/test/tools/llvm-reduce/skip-delta-passes.ll @@ -0,0 +1,22 @@ +; RUN: llvm-reduce --delta-passes=attributes --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: FileCheck -check-prefix=RESULT %s < %t + +; RUN: llvm-reduce --delta-passes=instructions,attributes --skip-delta-passes=instructions --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: FileCheck -check-prefix=RESULT %s < %t + +; RUN: not llvm-reduce --skip-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 + + +; CHECK-INTERESTINGNESS: @foo +; RESULT: define void @foo() { +; RESULT-NEXT: store i32 +; RESULT-NEXT: ret void +; RESULT0-NOT: attributes + +; ERROR: unknown pass "foo" +define void @foo() #0 { + store i32 0, ptr null + ret void +} + +attributes #0 = { "arstarstarst" } Index: llvm/tools/llvm-reduce/DeltaManager.cpp =================================================================== --- llvm/tools/llvm-reduce/DeltaManager.cpp +++ llvm/tools/llvm-reduce/DeltaManager.cpp @@ -48,6 +48,8 @@ using namespace llvm; +using SmallStringSet = SmallSet; + extern cl::OptionCategory LLVMReduceOptions; static cl::opt DeltaPasses("delta-passes", @@ -55,6 +57,12 @@ "default, run all delta passes."), cl::cat(LLVMReduceOptions)); +static cl::opt + SkipDeltaPasses("skip-delta-passes", + cl::desc("Delta passes to not run, separated by commas. By " + "default, run all delta passes."), + cl::cat(LLVMReduceOptions)); + #define DELTA_PASSES \ do { \ DELTA_PASS("functions", reduceFunctionsDeltaPass) \ @@ -97,8 +105,12 @@ DELTA_PASS("register-masks", reduceRegisterMasksMIRDeltaPass) \ } while (false) -static void runAllDeltaPasses(TestRunner &Tester) { -#define DELTA_PASS(NAME, FUNC) FUNC(Tester); +static void runAllDeltaPasses(TestRunner &Tester, + const SmallStringSet &SkipPass) { +#define DELTA_PASS(NAME, FUNC) \ + if (!SkipPass.count(NAME)) { \ + FUNC(Tester); \ + } if (Tester.getProgram().isMIR()) { DELTA_PASSES_MIR; } else { @@ -123,6 +135,17 @@ exit(1); } +static void collectPassNames(const TestRunner &Tester, + SmallStringSet &NameSet) { +#define DELTA_PASS(NAME, FUNC) NameSet.insert(NAME); + if (Tester.getProgram().isMIR()) { + DELTA_PASSES_MIR; + } else { + DELTA_PASSES; + } +#undef DELTA_PASS +} + 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"; @@ -133,19 +156,54 @@ #undef DELTA_PASS } +static void splitCSV(SmallVectorImpl &PassNames, StringRef Passes) { + while (!Passes.empty()) { + auto Split = Passes.split(","); + PassNames.push_back(Split.first); + Passes = Split.second; + } +} + +static void handlePassList(const TestRunner &Tester, + SmallVectorImpl &PassList, + SmallStringSet &PassSet, StringRef PassArg) { + splitCSV(PassList, PassArg); + + SmallStringSet AllPasses; + collectPassNames(Tester, AllPasses); + + for (StringRef PassName : PassList) { + if (!AllPasses.count(PassName)) { + errs() << "unknown pass \"" << PassName << "\"\n"; + exit(1); + } + + PassSet.insert(PassName); + } +} + void llvm::runDeltaPasses(TestRunner &Tester, int MaxPassIterations) { uint64_t OldComplexity = Tester.getProgram().getComplexityScore(); + + SmallStringSet RunPassSet, SkipPassSet; + SmallVector RunPassList, SkipPassList; + + if (!DeltaPasses.empty()) + handlePassList(Tester, RunPassList, RunPassSet, DeltaPasses); + + if (!SkipDeltaPasses.empty()) + handlePassList(Tester, SkipPassList, SkipPassSet, SkipDeltaPasses); + for (int Iter = 0; Iter < MaxPassIterations; ++Iter) { - if (DeltaPasses.empty()) { - runAllDeltaPasses(Tester); + if (RunPassList.empty()) { + runAllDeltaPasses(Tester, SkipPassSet); } else { - StringRef Passes = DeltaPasses; - while (!Passes.empty()) { - auto Split = Passes.split(","); - runDeltaPassName(Tester, Split.first); - Passes = Split.second; + for (StringRef PassName : RunPassList) { + if (!SkipPassSet.count(PassName)) + runDeltaPassName(Tester, PassName); } } + uint64_t NewComplexity = Tester.getProgram().getComplexityScore(); if (NewComplexity >= OldComplexity) break;