[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