Skip to content

Commit

Permalink
llvm-reduce: Improve delta pass flag handling
Browse files Browse the repository at this point in the history
Verify all the requested passes exist before trying to run any.
For long reductions, it was really annoying for it to get halfway through
and then I come back later to an incomplete reduction.

Also add a new skip-delta-passes flag. Most of the time I want to opt out
of specific reductions, rather than run a select few.
  • Loading branch information
arsenm committed Oct 13, 2022
1 parent 0ec3ac9 commit c3bc72c
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 12 deletions.
22 changes: 22 additions & 0 deletions 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" }
78 changes: 66 additions & 12 deletions llvm/tools/llvm-reduce/DeltaManager.cpp
Expand Up @@ -48,12 +48,20 @@

using namespace llvm;

using SmallStringSet = SmallSet<StringRef, 8>;

extern cl::OptionCategory LLVMReduceOptions;
static cl::opt<std::string>
static cl::list<std::string>
DeltaPasses("delta-passes",
cl::desc("Delta passes to run, separated by commas. By "
"default, run all delta passes."),
cl::cat(LLVMReduceOptions));
cl::cat(LLVMReduceOptions), cl::CommaSeparated);

static cl::list<std::string>
SkipDeltaPasses("skip-delta-passes",
cl::desc("Delta passes to not run, separated by commas. By "
"default, run all delta passes."),
cl::cat(LLVMReduceOptions), cl::CommaSeparated);

#define DELTA_PASSES \
do { \
Expand Down Expand Up @@ -97,8 +105,12 @@ static cl::opt<std::string>
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 {
Expand All @@ -119,8 +131,10 @@ static void runDeltaPassName(TestRunner &Tester, StringRef PassName) {
DELTA_PASSES;
}
#undef DELTA_PASS
errs() << "unknown pass \"" << PassName << "\"\n";
exit(1);

// We should have errored on unrecognized passes before trying to run
// anything.
llvm_unreachable("unknown delta pass");
}

void llvm::printDeltaPasses(raw_ostream &OS) {
Expand All @@ -133,19 +147,59 @@ void llvm::printDeltaPasses(raw_ostream &OS) {
#undef DELTA_PASS
}

// Built a set of available delta passes.
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
}

/// Verify all requested or skipped passes are valid names, and return them in a
/// set.
static SmallStringSet handlePassList(const TestRunner &Tester,
const cl::list<std::string> &PassList) {
SmallStringSet AllPasses;
collectPassNames(Tester, AllPasses);

SmallStringSet PassSet;
for (StringRef PassName : PassList) {
if (!AllPasses.count(PassName)) {
errs() << "unknown pass \"" << PassName << "\"\n";
exit(1);
}

PassSet.insert(PassName);
}

return PassSet;
}

void llvm::runDeltaPasses(TestRunner &Tester, int MaxPassIterations) {
uint64_t OldComplexity = Tester.getProgram().getComplexityScore();

SmallStringSet RunPassSet, SkipPassSet;

if (!DeltaPasses.empty())
RunPassSet = handlePassList(Tester, DeltaPasses);

if (!SkipDeltaPasses.empty())
SkipPassSet = handlePassList(Tester, SkipDeltaPasses);

for (int Iter = 0; Iter < MaxPassIterations; ++Iter) {
if (DeltaPasses.empty()) {
runAllDeltaPasses(Tester);
runAllDeltaPasses(Tester, SkipPassSet);
} else {
StringRef Passes = DeltaPasses;
while (!Passes.empty()) {
auto Split = Passes.split(",");
runDeltaPassName(Tester, Split.first);
Passes = Split.second;
for (StringRef PassName : DeltaPasses) {
if (!SkipPassSet.count(PassName))
runDeltaPassName(Tester, PassName);
}
}

uint64_t NewComplexity = Tester.getProgram().getComplexityScore();
if (NewComplexity >= OldComplexity)
break;
Expand Down

0 comments on commit c3bc72c

Please sign in to comment.