[llvm] 4463b73 - Enable opt-bisect for the new pass manager
Josh Stone via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 9 15:57:56 PST 2020
Author: Josh Stone
Date: 2020-11-09T15:57:48-08:00
New Revision: 4463b73e790fdf8bdbb18ac4ae3432217215daa5
URL: https://github.com/llvm/llvm-project/commit/4463b73e790fdf8bdbb18ac4ae3432217215daa5
DIFF: https://github.com/llvm/llvm-project/commit/4463b73e790fdf8bdbb18ac4ae3432217215daa5.diff
LOG: Enable opt-bisect for the new pass manager
This instruments a should-run-optional-pass callback using the existing
OptBisect class to decide if new passes should be skipped. Passes that
force isRequired never reach this at all, so they are not included in
"BISECT:" output nor its pass count.
The test case is resurrected from r267022, an early version of D19172
that had new pass manager support (later reverted and redone without).
Reviewed By: aeubanks
Differential Revision: https://reviews.llvm.org/D87951
Added:
llvm/test/Other/opt-bisect-new-pass-manager.ll
Modified:
llvm/include/llvm/IR/OptBisect.h
llvm/include/llvm/Passes/StandardInstrumentations.h
llvm/lib/Passes/StandardInstrumentations.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/OptBisect.h b/llvm/include/llvm/IR/OptBisect.h
index 1b2b0bd7acaa..5371d88fbb7d 100644
--- a/llvm/include/llvm/IR/OptBisect.h
+++ b/llvm/include/llvm/IR/OptBisect.h
@@ -68,9 +68,11 @@ class OptBisect : public OptPassGate {
/// isEnabled should return true before calling shouldRunPass
bool isEnabled() const override { return BisectEnabled; }
-private:
+
+protected:
bool checkPass(const StringRef PassName, const StringRef TargetDesc);
+private:
bool BisectEnabled = false;
unsigned LastBisectNum = 0;
};
diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h
index 01fe87bac3da..b811ede5a9f3 100644
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/OptBisect.h"
#include "llvm/IR/PassInstrumentation.h"
#include "llvm/IR/PassTimingInfo.h"
#include "llvm/IR/ValueHandle.h"
@@ -67,6 +68,12 @@ class OptNoneInstrumentation {
bool shouldRun(StringRef PassID, Any IR);
};
+class OptBisectInstrumentation : public OptBisect {
+public:
+ OptBisectInstrumentation() {}
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+};
+
// Debug logging for transformation and analysis passes.
class PrintPassInstrumentation {
public:
@@ -230,6 +237,7 @@ class StandardInstrumentations {
PrintPassInstrumentation PrintPass;
TimePassesHandler TimePasses;
OptNoneInstrumentation OptNone;
+ OptBisectInstrumentation OptBisect;
PreservedCFGCheckerInstrumentation PreservedCFGChecker;
IRChangePrinter PrintChangedIR;
VerifyInstrumentation Verify;
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 85f637421fe4..c639bd151809 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -540,6 +540,46 @@ bool OptNoneInstrumentation::shouldRun(StringRef PassID, Any IR) {
return ShouldRun;
}
+static std::string getBisectDescription(Any IR) {
+ if (any_isa<const Module *>(IR)) {
+ const Module *M = any_cast<const Module *>(IR);
+ assert(M && "module should be valid for printing");
+ return "module (" + M->getName().str() + ")";
+ }
+
+ if (any_isa<const Function *>(IR)) {
+ const Function *F = any_cast<const Function *>(IR);
+ assert(F && "function should be valid for printing");
+ return "function (" + F->getName().str() + ")";
+ }
+
+ if (any_isa<const LazyCallGraph::SCC *>(IR)) {
+ const LazyCallGraph::SCC *C = any_cast<const LazyCallGraph::SCC *>(IR);
+ assert(C && "scc should be valid for printing");
+ return "SCC " + C->getName();
+ }
+
+ if (any_isa<const Loop *>(IR)) {
+ return "loop";
+ }
+
+ llvm_unreachable("Unknown wrapped IR type");
+}
+
+void OptBisectInstrumentation::registerCallbacks(
+ PassInstrumentationCallbacks &PIC) {
+ if (!isEnabled())
+ return;
+
+ std::vector<StringRef> SpecialPasses = {"PassManager", "PassAdaptor"};
+
+ PIC.registerShouldRunOptionalPassCallback(
+ [this, SpecialPasses](StringRef PassID, Any IR) {
+ return isSpecialPass(PassID, SpecialPasses) ||
+ checkPass(PassID, getBisectDescription(IR));
+ });
+}
+
void PrintPassInstrumentation::registerCallbacks(
PassInstrumentationCallbacks &PIC) {
if (!DebugLogging)
@@ -770,6 +810,7 @@ void StandardInstrumentations::registerCallbacks(
PrintPass.registerCallbacks(PIC);
TimePasses.registerCallbacks(PIC);
OptNone.registerCallbacks(PIC);
+ OptBisect.registerCallbacks(PIC);
PreservedCFGChecker.registerCallbacks(PIC);
PrintChangedIR.registerCallbacks(PIC);
if (VerifyEach)
diff --git a/llvm/test/Other/opt-bisect-new-pass-manager.ll b/llvm/test/Other/opt-bisect-new-pass-manager.ll
new file mode 100644
index 000000000000..9ed5edbeeb13
--- /dev/null
+++ b/llvm/test/Other/opt-bisect-new-pass-manager.ll
@@ -0,0 +1,157 @@
+; This file verifies the behavior of the OptBisect class, which is used to
+; diagnose optimization related failures. The tests check various
+; invocations that result in
diff erent sets of optimization passes that
+; are run in
diff erent ways.
+;
+; Because the exact set of optimizations that will be run is expected to
+; change over time, the checks for disabling passes are written in a
+; conservative way that avoids assumptions about which specific passes
+; will be disabled.
+
+; RUN: opt -disable-output -disable-verify \
+; RUN: -passes=inferattrs -opt-bisect-limit=-1 %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-MODULE-PASS
+; CHECK-MODULE-PASS: BISECT: running pass (1) InferFunctionAttrsPass on module
+
+; RUN: opt -disable-output -disable-verify \
+; RUN: -passes=inferattrs -opt-bisect-limit=0 %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-MODULE-PASS
+; CHECK-LIMIT-MODULE-PASS: BISECT: NOT running pass (1) InferFunctionAttrsPass on module
+
+; RUN: opt -disable-output -debug-pass-manager \
+; RUN: -passes=inferattrs -opt-bisect-limit=-1 %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-REQUIRED-PASS
+; CHECK-REQUIRED-PASS-NOT: BISECT: {{.*}} VerifierPass
+; CHECK-REQUIRED-PASS: Running pass: VerifierPass
+; CHECK-REQUIRED-PASS: BISECT: running pass (1) InferFunctionAttrsPass on module
+; CHECK-REQUIRED-PASS-NOT: BISECT: {{.*}} VerifierPass
+; CHECK-REQUIRED-PASS: Running pass: VerifierPass
+
+; RUN: opt -disable-output -debug-pass-manager \
+; RUN: -passes=inferattrs -opt-bisect-limit=0 %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-REQUIRED-PASS
+; CHECK-LIMIT-REQUIRED-PASS-NOT: BISECT: {{.*}} VerifierPass
+; CHECK-LIMIT-REQUIRED-PASS: Running pass: VerifierPass
+; CHECK-LIMIT-REQUIRED-PASS: BISECT: NOT running pass (1) InferFunctionAttrsPass on module
+; CHECK-LIMIT-REQUIRED-PASS-NOT: BISECT: {{.*}} VerifierPass
+; CHECK-LIMIT-REQUIRED-PASS: Running pass: VerifierPass
+
+; RUN: opt -disable-output -disable-verify \
+; RUN: -passes=early-cse -opt-bisect-limit=-1 %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-FUNCTION-PASS
+; CHECK-FUNCTION-PASS: BISECT: running pass (1) EarlyCSEPass on function (f1)
+; CHECK-FUNCTION-PASS: BISECT: running pass (2) EarlyCSEPass on function (f2)
+; CHECK-FUNCTION-PASS: BISECT: running pass (3) EarlyCSEPass on function (f3)
+; CHECK-FUNCTION-PASS: BISECT: running pass (4) EarlyCSEPass on function (f4)
+
+; RUN: opt -disable-output -disable-verify \
+; RUN: -passes=early-cse -opt-bisect-limit=2 %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-FUNCTION-PASS
+; CHECK-LIMIT-FUNCTION-PASS: BISECT: running pass (1) EarlyCSEPass on function (f1)
+; CHECK-LIMIT-FUNCTION-PASS: BISECT: running pass (2) EarlyCSEPass on function (f2)
+; CHECK-LIMIT-FUNCTION-PASS: BISECT: NOT running pass (3) EarlyCSEPass on function (f3)
+; CHECK-LIMIT-FUNCTION-PASS: BISECT: NOT running pass (4) EarlyCSEPass on function (f4)
+
+; RUN: opt -disable-output -disable-verify \
+; RUN: -passes=function-attrs -opt-bisect-limit=-1 %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-CGSCC-PASS
+; CHECK-CGSCC-PASS: BISECT: running pass (1) PostOrderFunctionAttrsPass on SCC (f1)
+; CHECK-CGSCC-PASS: BISECT: running pass (2) PostOrderFunctionAttrsPass on SCC (f2)
+; CHECK-CGSCC-PASS: BISECT: running pass (3) PostOrderFunctionAttrsPass on SCC (f3)
+; CHECK-CGSCC-PASS: BISECT: running pass (4) PostOrderFunctionAttrsPass on SCC (f4)
+
+; RUN: opt -disable-output -disable-verify \
+; RUN: -passes=function-attrs -opt-bisect-limit=3 %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-CGSCC-PASS
+; CHECK-LIMIT-CGSCC-PASS: BISECT: running pass (1) PostOrderFunctionAttrsPass on SCC (f1)
+; CHECK-LIMIT-CGSCC-PASS: BISECT: running pass (2) PostOrderFunctionAttrsPass on SCC (f2)
+; CHECK-LIMIT-CGSCC-PASS: BISECT: running pass (3) PostOrderFunctionAttrsPass on SCC (f3)
+; CHECK-LIMIT-CGSCC-PASS: BISECT: NOT running pass (4) PostOrderFunctionAttrsPass on SCC (f4)
+
+; RUN: opt -disable-output -disable-verify -opt-bisect-limit=-1 \
+; RUN: -passes='inferattrs,cgscc(function-attrs,function(early-cse))' %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-MULTI-PASS
+; CHECK-MULTI-PASS: BISECT: running pass (1) InferFunctionAttrsPass on module
+; CHECK-MULTI-PASS: BISECT: running pass (2) PostOrderFunctionAttrsPass on SCC (f1)
+; CHECK-MULTI-PASS: BISECT: running pass (3) EarlyCSEPass on function (f1)
+; CHECK-MULTI-PASS: BISECT: running pass (4) PostOrderFunctionAttrsPass on SCC (f2)
+; CHECK-MULTI-PASS: BISECT: running pass (5) EarlyCSEPass on function (f2)
+; CHECK-MULTI-PASS: BISECT: running pass (6) PostOrderFunctionAttrsPass on SCC (f3)
+; CHECK-MULTI-PASS: BISECT: running pass (7) EarlyCSEPass on function (f3)
+; CHECK-MULTI-PASS: BISECT: running pass (8) PostOrderFunctionAttrsPass on SCC (f4)
+; CHECK-MULTI-PASS: BISECT: running pass (9) EarlyCSEPass on function (f4)
+
+; RUN: opt -disable-output -disable-verify -opt-bisect-limit=7 \
+; RUN: -passes='inferattrs,cgscc(function-attrs,function(early-cse))' %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-LIMIT-MULTI-PASS
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (1) InferFunctionAttrsPass on module
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (2) PostOrderFunctionAttrsPass on SCC (f1)
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (3) EarlyCSEPass on function (f1)
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (4) PostOrderFunctionAttrsPass on SCC (f2)
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (5) EarlyCSEPass on function (f2)
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (6) PostOrderFunctionAttrsPass on SCC (f3)
+; CHECK-LIMIT-MULTI-PASS: BISECT: running pass (7) EarlyCSEPass on function (f3)
+; CHECK-LIMIT-MULTI-PASS: BISECT: NOT running pass (8) PostOrderFunctionAttrsPass on SCC (f4)
+; CHECK-LIMIT-MULTI-PASS: BISECT: NOT running pass (9) EarlyCSEPass on function (f4)
+
+
+declare i32 @g()
+
+define void @f1() {
+entry:
+ br label %loop.0
+loop.0:
+ br i1 undef, label %loop.0.0, label %loop.1
+loop.0.0:
+ br i1 undef, label %loop.0.0, label %loop.0.1
+loop.0.1:
+ br i1 undef, label %loop.0.1, label %loop.0
+loop.1:
+ br i1 undef, label %loop.1, label %loop.1.bb1
+loop.1.bb1:
+ br i1 undef, label %loop.1, label %loop.1.bb2
+loop.1.bb2:
+ br i1 undef, label %end, label %loop.1.0
+loop.1.0:
+ br i1 undef, label %loop.1.0, label %loop.1
+end:
+ ret void
+}
+
+define i32 @f2() {
+entry:
+ ret i32 0
+}
+
+define i32 @f3() {
+entry:
+ %temp = call i32 @g()
+ %icmp = icmp ugt i32 %temp, 2
+ br i1 %icmp, label %bb.true, label %bb.false
+bb.true:
+ %temp2 = call i32 @f2()
+ ret i32 %temp2
+bb.false:
+ ret i32 0
+}
+
+; This function is here to verify that opt-bisect can skip all passes for
+; functions that contain lifetime intrinsics.
+define void @f4() {
+entry:
+ %i = alloca i32, align 4
+ %tmp = bitcast i32* %i to i8*
+ call void @llvm.lifetime.start(i64 4, i8* %tmp)
+ br label %for.cond
+
+for.cond:
+ br i1 undef, label %for.body, label %for.end
+
+for.body:
+ br label %for.cond
+
+for.end:
+ ret void
+}
+
+declare void @llvm.lifetime.start(i64, i8* nocapture)
More information about the llvm-commits
mailing list