Skip to content

Commit 662e568

Browse files
author
Fedor Sergeev
committedSep 24, 2018
[New PM][PassInstrumentation] IR printing support for New Pass Manager
Implementing -print-before-all/-print-after-all/-filter-print-func support through PassInstrumentation callbacks. - PrintIR routines implement printing callbacks. - StandardInstrumentations class provides a central place to manage all the "standard" in-tree pass instrumentations. Currently it registers PrintIR callbacks. Reviewers: chandlerc, paquette, philip.pfaffe Differential Revision: https://reviews.llvm.org/D50923 llvm-svn: 342896
1 parent 8284b19 commit 662e568

13 files changed

+236
-43
lines changed
 

‎llvm/include/llvm/IR/IRPrintingPasses.h

+16
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,22 @@ void printLLVMNameWithoutPrefix(raw_ostream &OS, StringRef Name);
5858
/// Return true if a pass is for IR printing.
5959
bool isIRPrintingPass(Pass *P);
6060

61+
/// isFunctionInPrintList - returns true if a function should be printed via
62+
// debugging options like -print-after-all/-print-before-all.
63+
// Tells if the function IR should be printed by PrinterPass.
64+
extern bool isFunctionInPrintList(StringRef FunctionName);
65+
66+
/// forcePrintModuleIR - returns true if IR printing passes should
67+
// be printing module IR (even for local-pass printers e.g. function-pass)
68+
// to provide more context, as enabled by debugging option -print-module-scope
69+
// Tells if IR printer should be printing module IR
70+
extern bool forcePrintModuleIR();
71+
72+
extern bool shouldPrintBeforePass();
73+
extern bool shouldPrintBeforePass(StringRef);
74+
extern bool shouldPrintAfterPass();
75+
extern bool shouldPrintAfterPass(StringRef);
76+
6177
/// Pass for printing a Module as LLVM's text IR assembly.
6278
///
6379
/// Note: This pass is for use with the new pass manager. Use the create...Pass

‎llvm/include/llvm/Pass.h

-11
Original file line numberDiff line numberDiff line change
@@ -356,17 +356,6 @@ class BasicBlockPass : public Pass {
356356
/// This is the storage for the -time-passes option.
357357
extern bool TimePassesIsEnabled;
358358

359-
/// isFunctionInPrintList - returns true if a function should be printed via
360-
// debugging options like -print-after-all/-print-before-all.
361-
// Tells if the function IR should be printed by PrinterPass.
362-
extern bool isFunctionInPrintList(StringRef FunctionName);
363-
364-
/// forcePrintModuleIR - returns true if IR printing passes should
365-
// be printing module IR (even for local-pass printers e.g. function-pass)
366-
// to provide more context, as enabled by debugging option -print-module-scope
367-
// Tells if IR printer should be printing module IR
368-
extern bool forcePrintModuleIR();
369-
370359
} // end namespace llvm
371360

372361
// Include support files that contain important APIs commonly used by Passes,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===- StandardInstrumentations.h ------------------------------*- C++ -*--===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
/// \file
10+
///
11+
/// This header defines a class that provides bookkeeping for all standard
12+
/// (i.e in-tree) pass instrumentations.
13+
///
14+
//===----------------------------------------------------------------------===//
15+
16+
#ifndef LLVM_PASSES_STANDARDINSTRUMENTATIONS_H
17+
#define LLVM_PASSES_STANDARDINSTRUMENTATIONS_H
18+
19+
#include "llvm/IR/PassInstrumentation.h"
20+
21+
namespace llvm {
22+
23+
/// This class provides an interface to register all the standard pass
24+
/// instrumentations and manages their state (if any).
25+
class StandardInstrumentations {
26+
// for now we do not have instrumentations with state
27+
public:
28+
StandardInstrumentations() = default;
29+
30+
void registerCallbacks(PassInstrumentationCallbacks &PIC);
31+
};
32+
} // namespace llvm
33+
34+
#endif

‎llvm/lib/Analysis/CallGraphSCCPass.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/Analysis/CallGraph.h"
2323
#include "llvm/IR/CallSite.h"
2424
#include "llvm/IR/Function.h"
25+
#include "llvm/IR/IRPrintingPasses.h"
2526
#include "llvm/IR/Intrinsics.h"
2627
#include "llvm/IR/LLVMContext.h"
2728
#include "llvm/IR/LegacyPassManagers.h"

‎llvm/lib/Analysis/LoopInfo.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "llvm/IR/Constants.h"
2727
#include "llvm/IR/DebugLoc.h"
2828
#include "llvm/IR/Dominators.h"
29+
#include "llvm/IR/IRPrintingPasses.h"
2930
#include "llvm/IR/Instructions.h"
3031
#include "llvm/IR/LLVMContext.h"
3132
#include "llvm/IR/Metadata.h"

‎llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "llvm/CodeGen/MachineFunctionPass.h"
1616
#include "llvm/CodeGen/Passes.h"
1717
#include "llvm/CodeGen/SlotIndexes.h"
18+
#include "llvm/IR/IRPrintingPasses.h"
1819
#include "llvm/Support/Debug.h"
1920
#include "llvm/Support/raw_ostream.h"
2021

‎llvm/lib/IR/LegacyPassManager.cpp

+16-12
Original file line numberDiff line numberDiff line change
@@ -100,27 +100,31 @@ static cl::list<std::string>
100100
/// This is a helper to determine whether to print IR before or
101101
/// after a pass.
102102

103-
static bool ShouldPrintBeforeOrAfterPass(const PassInfo *PI,
103+
bool llvm::shouldPrintBeforePass() {
104+
return PrintBeforeAll || !PrintBefore.empty();
105+
}
106+
107+
bool llvm::shouldPrintAfterPass() {
108+
return PrintAfterAll || !PrintAfter.empty();
109+
}
110+
111+
static bool ShouldPrintBeforeOrAfterPass(StringRef PassID,
104112
PassOptionList &PassesToPrint) {
105113
for (auto *PassInf : PassesToPrint) {
106114
if (PassInf)
107-
if (PassInf->getPassArgument() == PI->getPassArgument()) {
115+
if (PassInf->getPassArgument() == PassID) {
108116
return true;
109117
}
110118
}
111119
return false;
112120
}
113121

114-
/// This is a utility to check whether a pass should have IR dumped
115-
/// before it.
116-
static bool ShouldPrintBeforePass(const PassInfo *PI) {
117-
return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PI, PrintBefore);
122+
bool llvm::shouldPrintBeforePass(StringRef PassID) {
123+
return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PassID, PrintBefore);
118124
}
119125

120-
/// This is a utility to check whether a pass should have IR dumped
121-
/// after it.
122-
static bool ShouldPrintAfterPass(const PassInfo *PI) {
123-
return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter);
126+
bool llvm::shouldPrintAfterPass(StringRef PassID) {
127+
return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PassID, PrintAfter);
124128
}
125129

126130
bool llvm::forcePrintModuleIR() { return PrintModuleScope; }
@@ -780,7 +784,7 @@ void PMTopLevelManager::schedulePass(Pass *P) {
780784
return;
781785
}
782786

783-
if (PI && !PI->isAnalysis() && ShouldPrintBeforePass(PI)) {
787+
if (PI && !PI->isAnalysis() && shouldPrintBeforePass(PI->getPassArgument())) {
784788
Pass *PP = P->createPrinterPass(
785789
dbgs(), ("*** IR Dump Before " + P->getPassName() + " ***").str());
786790
PP->assignPassManager(activeStack, getTopLevelPassManagerType());
@@ -789,7 +793,7 @@ void PMTopLevelManager::schedulePass(Pass *P) {
789793
// Add the requested pass to the best available pass manager.
790794
P->assignPassManager(activeStack, getTopLevelPassManagerType());
791795

792-
if (PI && !PI->isAnalysis() && ShouldPrintAfterPass(PI)) {
796+
if (PI && !PI->isAnalysis() && shouldPrintAfterPass(PI->getPassArgument())) {
793797
Pass *PP = P->createPrinterPass(
794798
dbgs(), ("*** IR Dump After " + P->getPassName() + " ***").str());
795799
PP->assignPassManager(activeStack, getTopLevelPassManagerType());

‎llvm/lib/Passes/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ endif()
55
add_llvm_library(LLVMPasses
66
PassBuilder.cpp
77
PassPlugin.cpp
8+
StandardInstrumentations.cpp
89

910
ADDITIONAL_HEADER_DIRS
1011
${LLVM_MAIN_INCLUDE_DIR}/llvm/Passes
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
//===- Standard pass instrumentations handling ----------------*- C++ -*--===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
/// \file
10+
///
11+
/// This file defines IR-printing pass instrumentation callbacks as well as
12+
/// StandardInstrumentations class that manages standard pass instrumentations.
13+
///
14+
//===----------------------------------------------------------------------===//
15+
16+
#include "llvm/Passes/StandardInstrumentations.h"
17+
#include "llvm/Analysis/CallGraphSCCPass.h"
18+
#include "llvm/Analysis/LazyCallGraph.h"
19+
#include "llvm/Analysis/LoopInfo.h"
20+
#include "llvm/IR/Function.h"
21+
#include "llvm/IR/IRPrintingPasses.h"
22+
#include "llvm/IR/Module.h"
23+
#include "llvm/IR/PassInstrumentation.h"
24+
#include "llvm/Support/Debug.h"
25+
#include "llvm/Support/FormatVariadic.h"
26+
#include "llvm/Support/raw_ostream.h"
27+
28+
using namespace llvm;
29+
30+
namespace {
31+
namespace PrintIR {
32+
33+
//===----------------------------------------------------------------------===//
34+
// IR-printing instrumentation
35+
//===----------------------------------------------------------------------===//
36+
37+
/// Generic IR-printing helper that unpacks a pointer to IRUnit wrapped into
38+
/// llvm::Any and does actual print job.
39+
void unwrapAndPrint(StringRef Banner, Any IR) {
40+
if (any_isa<const CallGraphSCC *>(IR) ||
41+
any_isa<const LazyCallGraph::SCC *>(IR))
42+
return;
43+
44+
SmallString<40> Extra{"\n"};
45+
const Module *M = nullptr;
46+
if (any_isa<const Module *>(IR)) {
47+
M = any_cast<const Module *>(IR);
48+
} else if (any_isa<const Function *>(IR)) {
49+
const Function *F = any_cast<const Function *>(IR);
50+
if (!llvm::isFunctionInPrintList(F->getName()))
51+
return;
52+
if (!llvm::forcePrintModuleIR()) {
53+
dbgs() << Banner << Extra << static_cast<const Value &>(*F);
54+
return;
55+
}
56+
M = F->getParent();
57+
Extra = formatv(" (function: {0})\n", F->getName());
58+
} else if (any_isa<const Loop *>(IR)) {
59+
const Loop *L = any_cast<const Loop *>(IR);
60+
const Function *F = L->getHeader()->getParent();
61+
if (!isFunctionInPrintList(F->getName()))
62+
return;
63+
if (!llvm::forcePrintModuleIR()) {
64+
llvm::printLoop(const_cast<Loop &>(*L), dbgs(), Banner);
65+
return;
66+
}
67+
M = F->getParent();
68+
{
69+
std::string LoopName;
70+
raw_string_ostream ss(LoopName);
71+
L->getHeader()->printAsOperand(ss, false);
72+
Extra = formatv(" (loop: {0})\n", ss.str());
73+
}
74+
}
75+
if (M) {
76+
dbgs() << Banner << Extra;
77+
M->print(dbgs(), nullptr, false);
78+
} else {
79+
llvm_unreachable("Unknown wrapped IR type");
80+
}
81+
}
82+
83+
bool printBeforePass(StringRef PassID, Any IR) {
84+
if (!llvm::shouldPrintBeforePass(PassID))
85+
return true;
86+
87+
if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<"))
88+
return true;
89+
90+
SmallString<20> Banner = formatv("*** IR Dump Before {0} ***", PassID);
91+
unwrapAndPrint(Banner, IR);
92+
return true;
93+
}
94+
95+
void printAfterPass(StringRef PassID, Any IR) {
96+
if (!llvm::shouldPrintAfterPass(PassID))
97+
return;
98+
99+
if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<"))
100+
return;
101+
102+
SmallString<20> Banner = formatv("*** IR Dump After {0} ***", PassID);
103+
unwrapAndPrint(Banner, IR);
104+
return;
105+
}
106+
} // namespace PrintIR
107+
} // namespace
108+
109+
void StandardInstrumentations::registerCallbacks(
110+
PassInstrumentationCallbacks &PIC) {
111+
if (llvm::shouldPrintBeforePass())
112+
PIC.registerBeforePassCallback(PrintIR::printBeforePass);
113+
if (llvm::shouldPrintAfterPass())
114+
PIC.registerAfterPassCallback(PrintIR::printAfterPass);
115+
}

‎llvm/test/Other/loop-pass-printer.ll

+16-11
Original file line numberDiff line numberDiff line change
@@ -5,48 +5,53 @@
55
; RUN: -loop-deletion -print-before=loop-deletion \
66
; RUN: | FileCheck %s -check-prefix=DEL
77
; RUN: opt < %s 2>&1 -disable-output \
8+
; RUN: -passes='loop(loop-deletion)' -print-before-all \
9+
; RUN: | FileCheck %s -check-prefix=DEL
10+
; RUN: opt < %s 2>&1 -disable-output \
811
; RUN: -loop-unroll -print-after=loop-unroll -filter-print-funcs=bar \
12+
; RUN: | FileCheck %s -check-prefix=BAR -check-prefix=BAR-OLD
13+
; RUN: opt < %s 2>&1 -disable-output \
14+
; RUN: -passes='require<opt-remark-emit>,loop(unroll-full)' -print-after-all -filter-print-funcs=bar \
915
; RUN: | FileCheck %s -check-prefix=BAR
1016
; RUN: opt < %s 2>&1 -disable-output \
1117
; RUN: -loop-unroll -print-after=loop-unroll -filter-print-funcs=foo -print-module-scope \
18+
; RUN: | FileCheck %s -check-prefix=FOO-MODULE -check-prefix=FOO-MODULE-OLD
19+
; RUN: opt < %s 2>&1 -disable-output \
20+
; RUN: -passes='require<opt-remark-emit>,loop(unroll-full)' -print-after-all -filter-print-funcs=foo -print-module-scope \
1221
; RUN: | FileCheck %s -check-prefix=FOO-MODULE
1322

14-
; DEL: IR Dump Before
15-
; DEL-SAME: dead loops
23+
; DEL: IR Dump Before {{Delete dead loops|LoopDeletionPass}}
1624
; DEL: ; Preheader:
1725
; DEL-NEXT: %idx = alloca i32, align 4
1826
; DEL: ; Loop:
1927
; DEL-NEXT: loop:
2028
; DEL: cont:
2129
; DEL: ; Exit blocks
2230
; DEL: done:
23-
; DEL: IR Dump Before
24-
; DEL-SAME: dead loops
31+
; DEL: IR Dump Before {{Delete dead loops|LoopDeletionPass}}
2532
; DEL: ; Preheader:
2633
; DEL-NEXT: br label %loop
2734
; DEL: ; Loop:
2835
; DEL-NEXT: loop:
2936
; DEL: ; Exit blocks
3037
; DEL: end:
3138

32-
; BAR: IR Dump After
33-
; BAR-SAME: Unroll
39+
; BAR: IR Dump After {{Unroll|LoopFullUnrollPass}}
3440
; BAR: ; Preheader:
3541
; BAR-NEXT: br label %loop
3642
; BAR: ; Loop:
3743
; BAR-NEXT: loop:
3844
; BAR: ; Exit blocks
3945
; BAR: end:
40-
; BAR-NOT: IR Dump
41-
; BAR-NOT: ; Loop
46+
; BAR-OLD-NOT: IR Dump
47+
; BAR-OLD-NOT: ; Loop
4248

43-
; FOO-MODULE: IR Dump After
44-
; FOO-MODULE-SAME: Unroll
49+
; FOO-MODULE: IR Dump After {{Unroll|LoopFullUnrollPass}}
4550
; FOO-MODULE-SAME: loop: %loop
4651
; FOO-MODULE-NEXT: ModuleID =
4752
; FOO-MODULE: define void @foo
4853
; FOO-MODULE: define void @bar
49-
; FOO-MODULE-NOT: IR Dump
54+
; FOO-MODULE-OLD-NOT: IR Dump
5055

5156
define void @foo(){
5257
%idx = alloca i32, align 4

‎llvm/test/Other/print-module-scope.ll

+9-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,16 @@
77
; RUN: -simplifycfg -print-after=simplifycfg -print-module-scope \
88
; RUN: | FileCheck %s -check-prefix=CFG
99
; RUN: opt < %s 2>&1 -disable-output \
10+
; RUN: -passes=simplify-cfg -print-after-all -print-module-scope \
11+
; RUN: | FileCheck %s -check-prefix=CFG
12+
; RUN: opt < %s 2>&1 -disable-output \
1013
; RUN: -simplifycfg -print-after=simplifycfg -filter-print-funcs=foo -print-module-scope \
1114
; RUN: | FileCheck %s -check-prefix=FOO
15+
; RUN: opt < %s 2>&1 -disable-output \
16+
; RUN: -passes=simplify-cfg -print-after-all -filter-print-funcs=foo -print-module-scope \
17+
; RUN: | FileCheck %s -check-prefix=FOO
1218

13-
; CFG: IR Dump After
19+
; CFG: IR Dump After {{Simplify the CFG|SimplifyCFGPass}}
1420
; CFG-SAME: function: foo
1521
; CFG-NEXT: ModuleID =
1622
; CFG: define void @foo
@@ -23,7 +29,7 @@
2329
; CFG: define void @bar
2430
; CFG: declare void @baz
2531

26-
; FOO: IR Dump After
32+
; FOO: IR Dump After {{Simplify the CFG|SimplifyCFGPass}}
2733
; FOO-NOT: function: bar
2834
; FOO-SAME: function: foo
2935
; FOO-NEXT: ModuleID =
@@ -52,4 +58,4 @@ attributes #1 = { nounwind readnone ssp "use-soft-float"="false" }
5258

5359
; FOO: attributes #{{[0-9]}} = { nounwind readnone ssp "use-soft-float"="false" }
5460

55-
; FOO-NOT: IR Dump
61+
; FOO-NOT: IR Dump After {{Simplify the CFG|SimplifyCFGPass}}

‎llvm/test/Other/printer.ll

+19-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
; RUN: opt -mem2reg -instcombine -print-after-all -S < %s 2>&1 | FileCheck %s
1+
; RUN: opt -mem2reg -instcombine -print-after-all -disable-output < %s 2>&1 | FileCheck %s
2+
; RUN: opt -passes='mem2reg,instcombine' -print-after-all -disable-output < %s 2>&1 | FileCheck %s
23
define void @tester(){
34
ret void
45
}
@@ -7,7 +8,21 @@ define void @foo(){
78
ret void
89
}
910

10-
;CHECK: IR Dump After Promote Memory to Register
11-
;CHECK: IR Dump After Combine redundant instructions
12-
;CHECK: IR Dump After Module Verifier
11+
;CHECK-NOT: IR Dump After PassManager
12+
;CHECK-NOT: IR Dump After ModuleToFunctionPassAdaptor
13+
;
14+
;CHECK: *** IR Dump After {{Promote Memory to Register|PromotePass}}
15+
;CHECK: define void @tester
16+
;CHECK-NOT: define void @foo
17+
;CHECK: *** IR Dump After {{Combine redundant instructions|InstCombinePass}}
18+
;CHECK: define void @tester
19+
;CHECK-NOT: define void @foo
20+
;CHECK: *** IR Dump After {{Promote Memory to Register|PromotePass}}
21+
;CHECK: define void @foo
22+
;CHECK-NOT: define void @tester
23+
;CHECK: *** IR Dump After {{Combine redundant instructions|InstCombinePass}}
24+
;CHECK: define void @foo
25+
;CHECK-NOT: define void @tester
26+
;CHECK: *** IR Dump After {{Module Verifier|VerifierPass}}
27+
;
1328
;CHECK-NOT: IR Dump After Print Module IR

‎llvm/tools/opt/NewPMDriver.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
///
1414
//===----------------------------------------------------------------------===//
1515

16-
#include "Debugify.h"
1716
#include "NewPMDriver.h"
17+
#include "Debugify.h"
1818
#include "PassPrinters.h"
1919
#include "llvm/ADT/StringRef.h"
2020
#include "llvm/Analysis/AliasAnalysis.h"
@@ -29,6 +29,7 @@
2929
#include "llvm/IR/Verifier.h"
3030
#include "llvm/Passes/PassBuilder.h"
3131
#include "llvm/Passes/PassPlugin.h"
32+
#include "llvm/Passes/StandardInstrumentations.h"
3233
#include "llvm/Support/CommandLine.h"
3334
#include "llvm/Support/ErrorHandling.h"
3435
#include "llvm/Support/ToolOutputFile.h"
@@ -213,7 +214,11 @@ bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
213214
else
214215
P = None;
215216
}
216-
PassBuilder PB(TM, P);
217+
PassInstrumentationCallbacks PIC;
218+
StandardInstrumentations SI;
219+
SI.registerCallbacks(PIC);
220+
221+
PassBuilder PB(TM, P, &PIC);
217222
registerEPCallbacks(PB, VerifyEachPass, DebugPM);
218223

219224
// Load requested pass plugins and let them register pass builder callbacks

0 commit comments

Comments
 (0)
Please sign in to comment.