Skip to content

Commit d8f531c

Browse files
committed
[NewPM] Don't run before pass instrumentation on required passes
This allows those instrumentation to log when they decide to skip a pass. This provides extra helpful info for optnone functions and also will help with opt-bisect. Have OptNoneInstrumentation print when it skips due to seeing optnone. Reviewed By: asbirlea Differential Revision: https://reviews.llvm.org/D90545
1 parent 31a0b28 commit d8f531c

File tree

5 files changed

+56
-29
lines changed

5 files changed

+56
-29
lines changed

llvm/include/llvm/IR/PassInstrumentation.h

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,9 @@ class PassInstrumentationCallbacks {
8888
PassInstrumentationCallbacks(const PassInstrumentationCallbacks &) = delete;
8989
void operator=(const PassInstrumentationCallbacks &) = delete;
9090

91-
template <typename CallableT> void registerBeforePassCallback(CallableT C) {
92-
BeforePassCallbacks.emplace_back(std::move(C));
91+
template <typename CallableT>
92+
void registerShouldRunOptionalPassCallback(CallableT C) {
93+
ShouldRunOptionalPassCallbacks.emplace_back(std::move(C));
9394
}
9495

9596
template <typename CallableT>
@@ -124,16 +125,25 @@ class PassInstrumentationCallbacks {
124125
private:
125126
friend class PassInstrumentation;
126127

127-
SmallVector<llvm::unique_function<BeforePassFunc>, 4> BeforePassCallbacks;
128+
/// These are only run on passes that are not required. They return false when
129+
/// an optional pass should be skipped.
130+
SmallVector<llvm::unique_function<BeforePassFunc>, 4>
131+
ShouldRunOptionalPassCallbacks;
132+
/// These are run on passes that are skipped.
128133
SmallVector<llvm::unique_function<BeforeSkippedPassFunc>, 4>
129134
BeforeSkippedPassCallbacks;
135+
/// These are run on passes that are about to be run.
130136
SmallVector<llvm::unique_function<BeforeNonSkippedPassFunc>, 4>
131137
BeforeNonSkippedPassCallbacks;
138+
/// These are run on passes that have just run.
132139
SmallVector<llvm::unique_function<AfterPassFunc>, 4> AfterPassCallbacks;
140+
/// These are run passes that have just run on invalidated IR.
133141
SmallVector<llvm::unique_function<AfterPassInvalidatedFunc>, 4>
134142
AfterPassInvalidatedCallbacks;
143+
/// These are run on analyses that are about to be run.
135144
SmallVector<llvm::unique_function<BeforeAnalysisFunc>, 4>
136145
BeforeAnalysisCallbacks;
146+
/// These are run on analyses that have been run.
137147
SmallVector<llvm::unique_function<AfterAnalysisFunc>, 4>
138148
AfterAnalysisCallbacks;
139149
};
@@ -173,16 +183,19 @@ class PassInstrumentation {
173183

174184
/// BeforePass instrumentation point - takes \p Pass instance to be executed
175185
/// and constant reference to IR it operates on. \Returns true if pass is
176-
/// allowed to be executed.
186+
/// allowed to be executed. These are only run on optional pass since required
187+
/// passes must always be run. This allows these callbacks to print info when
188+
/// they want to skip a pass.
177189
template <typename IRUnitT, typename PassT>
178190
bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const {
179191
if (!Callbacks)
180192
return true;
181193

182194
bool ShouldRun = true;
183-
for (auto &C : Callbacks->BeforePassCallbacks)
184-
ShouldRun &= C(Pass.name(), llvm::Any(&IR));
185-
ShouldRun = ShouldRun || isRequired(Pass);
195+
if (!isRequired(Pass)) {
196+
for (auto &C : Callbacks->ShouldRunOptionalPassCallbacks)
197+
ShouldRun &= C(Pass.name(), llvm::Any(&IR));
198+
}
186199

187200
if (ShouldRun) {
188201
for (auto &C : Callbacks->BeforeNonSkippedPassCallbacks)

llvm/include/llvm/Passes/StandardInstrumentations.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,12 @@ class PrintIRInstrumentation {
5959

6060
class OptNoneInstrumentation {
6161
public:
62+
OptNoneInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
6263
void registerCallbacks(PassInstrumentationCallbacks &PIC);
6364

6465
private:
65-
bool skip(StringRef PassID, Any IR);
66+
bool DebugLogging;
67+
bool shouldRun(StringRef PassID, Any IR);
6668
};
6769

6870
// Debug logging for transformation and analysis passes.
@@ -236,7 +238,8 @@ class StandardInstrumentations {
236238

237239
public:
238240
StandardInstrumentations(bool DebugLogging, bool VerifyEach = false)
239-
: PrintPass(DebugLogging), Verify(DebugLogging), VerifyEach(VerifyEach) {}
241+
: PrintPass(DebugLogging), OptNone(DebugLogging), Verify(DebugLogging),
242+
VerifyEach(VerifyEach) {}
240243

241244
void registerCallbacks(PassInstrumentationCallbacks &PIC);
242245

llvm/lib/Passes/StandardInstrumentations.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -347,10 +347,8 @@ void IRChangePrinter::registerCallbacks(PassInstrumentationCallbacks &PIC) {
347347
if (!PrintChanged)
348348
return;
349349

350-
PIC.registerBeforePassCallback([this](StringRef P, Any IR) {
351-
saveIRBeforePass(IR, P);
352-
return true;
353-
});
350+
PIC.registerBeforeNonSkippedPassCallback(
351+
[this](StringRef P, Any IR) { saveIRBeforePass(IR, P); });
354352

355353
PIC.registerAfterPassCallback(
356354
[this](StringRef P, Any IR, const PreservedAnalyses &) {
@@ -521,11 +519,11 @@ void PrintIRInstrumentation::registerCallbacks(
521519

522520
void OptNoneInstrumentation::registerCallbacks(
523521
PassInstrumentationCallbacks &PIC) {
524-
PIC.registerBeforePassCallback(
525-
[this](StringRef P, Any IR) { return this->skip(P, IR); });
522+
PIC.registerShouldRunOptionalPassCallback(
523+
[this](StringRef P, Any IR) { return this->shouldRun(P, IR); });
526524
}
527525

528-
bool OptNoneInstrumentation::skip(StringRef PassID, Any IR) {
526+
bool OptNoneInstrumentation::shouldRun(StringRef PassID, Any IR) {
529527
if (!EnableOptnone)
530528
return true;
531529
const Function *F = nullptr;
@@ -534,7 +532,12 @@ bool OptNoneInstrumentation::skip(StringRef PassID, Any IR) {
534532
} else if (any_isa<const Loop *>(IR)) {
535533
F = any_cast<const Loop *>(IR)->getHeader()->getParent();
536534
}
537-
return !(F && F->hasOptNone());
535+
bool ShouldRun = !(F && F->hasOptNone());
536+
if (!ShouldRun && DebugLogging) {
537+
errs() << "Skipping pass " << PassID << " on " << F->getName()
538+
<< " due to optnone attribute\n";
539+
}
540+
return ShouldRun;
538541
}
539542

540543
void PrintPassInstrumentation::registerCallbacks(

llvm/test/Feature/optnone-opt.ll

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,21 @@
44
; RUN: opt -O3 -S -debug -enable-new-pm=0 %s 2>&1 | FileCheck %s --check-prefix=O1 --check-prefix=O2O3
55
; RUN: opt -dce -gvn-hoist -loweratomic -S -debug -enable-new-pm=0 %s 2>&1 | FileCheck %s --check-prefix=MORE
66
; RUN: opt -indvars -licm -loop-deletion -loop-extract -loop-idiom -loop-instsimplify -loop-reduce -loop-reroll -loop-rotate -loop-unroll -loop-unswitch -enable-new-pm=0 -S -debug %s 2>&1 | FileCheck %s --check-prefix=LOOP
7-
; RUN: opt -enable-npm-optnone -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-O0
8-
; RUN: opt -enable-npm-optnone -O1 -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-O1
9-
; RUN: opt -enable-npm-optnone -O2 -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-O1 --check-prefix=NPM-O2O3
10-
; RUN: opt -enable-npm-optnone -O3 -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-O1 --check-prefix=NPM-O2O3
11-
; RUN: opt -enable-npm-optnone -dce -gvn-hoist -loweratomic -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-MORE
12-
; RUN: opt -enable-npm-optnone -indvars -licm -loop-deletion -loop-idiom -loop-instsimplify -loop-reduce -loop-unroll -simple-loop-unswitch -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-LOOP
7+
; RUN: opt -enable-npm-optnone -passes='default<O0>' -S -debug-pass-manager %s 2>&1 | FileCheck %s --check-prefix=NPM-O0
8+
; RUN: opt -enable-npm-optnone -passes='default<O1>' -S -debug-pass-manager %s 2>&1 | FileCheck %s --check-prefix=NPM-O1
9+
; RUN: opt -enable-npm-optnone -passes='default<O2>' -S -debug-pass-manager %s 2>&1 | FileCheck %s --check-prefix=NPM-O1 --check-prefix=NPM-O2O3
10+
; RUN: opt -enable-npm-optnone -passes='default<O3>' -S -debug-pass-manager %s 2>&1 | FileCheck %s --check-prefix=NPM-O1 --check-prefix=NPM-O2O3
11+
; RUN: opt -enable-npm-optnone -passes='dce,gvn-hoist,loweratomic' -S -debug-pass-manager %s 2>&1 | FileCheck %s --check-prefix=NPM-MORE
12+
; RUN: opt -enable-npm-optnone -passes='loop(indvars,licm,loop-deletion,loop-idiom,loop-instsimplify,loop-reduce,simple-loop-unswitch),loop-unroll' -S -debug-pass-manager %s 2>&1 | FileCheck %s --check-prefix=NPM-LOOP
13+
; RUN: opt -enable-npm-optnone -passes='instsimplify,verify' -S -debug-pass-manager %s 2>&1 | FileCheck %s --check-prefix=NPM-REQUIRED
1314

1415
; REQUIRES: asserts
1516

1617
; This test verifies that we don't run target independent IR-level
1718
; optimizations on optnone functions.
1819

1920
; Function Attrs: noinline optnone
20-
define i32 @_Z3fooi(i32 %x) #0 {
21+
define i32 @foo(i32 %x) #0 {
2122
entry:
2223
%x.addr = alloca i32, align 4
2324
store i32 %x, i32* %x.addr, align 4
@@ -50,7 +51,7 @@ attributes #0 = { optnone noinline }
5051
; O1-DAG: Skipping pass 'Reassociate expressions'
5152
; O1-DAG: Skipping pass 'Simplify the CFG'
5253
; O1-DAG: Skipping pass 'Sparse Conditional Constant Propagation'
53-
; NPM-O1-DAG: Skipping pass: SimplifyCFGPass on {{.*}}foo
54+
; NPM-O1-DAG: Skipping pass: SimplifyCFGPass on foo
5455
; NPM-O1-DAG: Skipping pass: SROA
5556
; NPM-O1-DAG: Skipping pass: EarlyCSEPass
5657
; NPM-O1-DAG: Skipping pass: LowerExpectIntrinsicPass
@@ -81,7 +82,7 @@ attributes #0 = { optnone noinline }
8182
; LOOP-DAG: Skipping pass 'Unswitch loops'
8283
; LoopPassManager should not be skipped over an optnone function
8384
; NPM-LOOP-NOT: Skipping pass: PassManager
84-
; NPM-LOOP-DAG: Skipping pass: LoopSimplifyPass on {{.*}}foo
85+
; NPM-LOOP-DAG: Skipping pass: LoopSimplifyPass on foo
8586
; NPM-LOOP-DAG: Skipping pass: LCSSAPass
8687
; NPM-LOOP-DAG: Skipping pass: IndVarSimplifyPass
8788
; NPM-LOOP-DAG: Skipping pass: SimpleLoopUnswitchPass
@@ -91,3 +92,9 @@ attributes #0 = { optnone noinline }
9192
; NPM-LOOP-DAG: Skipping pass: LICMPass
9293
; NPM-LOOP-DAG: Skipping pass: LoopIdiomRecognizePass
9394
; NPM-LOOP-DAG: Skipping pass: LoopInstSimplifyPass
95+
96+
; NPM-REQUIRED-DAG: Skipping pass: InstSimplifyPass
97+
; NPM-REQUIRED-DAG: Skipping pass InstSimplifyPass on foo due to optnone attribute
98+
; NPM-REQUIRED-DAG: Running pass: VerifierPass
99+
; NPM-REQUIRED-NOT: Skipping pass: VerifyPass
100+
; NPM-REQUIRED-NOT: Skipping pass VerifyPass on foo due to optnone attribute

llvm/unittests/IR/PassBuilderCallbacksTest.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,10 @@ struct MockPassInstrumentationCallbacks {
330330
MOCK_METHOD2(runAfterAnalysis, void(StringRef PassID, llvm::Any));
331331

332332
void registerPassInstrumentation() {
333-
Callbacks.registerBeforePassCallback([this](StringRef P, llvm::Any IR) {
334-
return this->runBeforePass(P, IR);
335-
});
333+
Callbacks.registerShouldRunOptionalPassCallback(
334+
[this](StringRef P, llvm::Any IR) {
335+
return this->runBeforePass(P, IR);
336+
});
336337
Callbacks.registerBeforeSkippedPassCallback(
337338
[this](StringRef P, llvm::Any IR) {
338339
this->runBeforeSkippedPass(P, IR);

0 commit comments

Comments
 (0)