Skip to content

Commit f9e6d1e

Browse files
jamieschmeiseranhtuyenibm
authored andcommitted
Re-land: Add new hidden option -print-changed which only reports changes to IR
A new hidden option -print-changed is added along with code to support printing the IR as it passes through the opt pipeline in the new pass manager. Only those passes that change the IR are reported, with others only having the banner reported, indicating that they did not change the IR, were filtered out or ignored. Filtering of output via the -filter-print-funcs is supported and a new supporting hidden option -filter-passes is added. The latter takes a comma separated list of pass names and filters the output to only show those passes in the list that change the IR. The output can also be modified via the -print-module-scope function. The code introduces a template base class that generalizes the comparison of IRs that takes an IR representation as template parameter. The constructor takes a series of lambdas that provide an event based API for generalized reporting of IRs as they are changed in the opt pipeline through the new pass manager. The first of several instantiations is provided that prints the IR in a form similar to that produced by -print-after-all with the above mentioned filtering capabilities. This version, and the others to follow will be introduced at the upcoming developer's conference. Reviewed By: aeubanks (Arthur Eubanks), yrouban (Yevgeny Rouban), ychen (Yuanfang Chen) Differential Revision: https://reviews.llvm.org/D86360
1 parent 39faf42 commit f9e6d1e

File tree

4 files changed

+427
-7
lines changed

4 files changed

+427
-7
lines changed

llvm/include/llvm/Passes/StandardInstrumentations.h

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,97 @@ class PreservedCFGCheckerInstrumentation {
124124
void registerCallbacks(PassInstrumentationCallbacks &PIC);
125125
};
126126

127+
// Base class for classes that report changes to the IR.
128+
// It presents an interface for such classes and provides calls
129+
// on various events as the new pass manager transforms the IR.
130+
// It also provides filtering of information based on hidden options
131+
// specifying which functions are interesting.
132+
// Calls are made for the following events/queries:
133+
// 1. The initial IR processed.
134+
// 2. To get the representation of the IR (of type \p T).
135+
// 3. When a pass does not change the IR.
136+
// 4. When a pass changes the IR (given both before and after representations
137+
// of type \p T).
138+
// 5. When an IR is invalidated.
139+
// 6. When a pass is run on an IR that is not interesting (based on options).
140+
// 7. When a pass is ignored (pass manager or adapter pass).
141+
// 8. To compare two IR representations (of type \p T).
142+
template <typename IRUnitT> class ChangePrinter {
143+
protected:
144+
ChangePrinter() : InitialIR(true) {}
145+
146+
public:
147+
virtual ~ChangePrinter();
148+
149+
// Determine if this pass/IR is interesting and if so, save the IR
150+
// otherwise it is left on the stack without data
151+
void saveIRBeforePass(Any IR, StringRef PassID);
152+
// Compare the IR from before the pass after the pass.
153+
void handleIRAfterPass(Any IR, StringRef PassID);
154+
// Handle the situation where a pass is invalidated.
155+
void handleInvalidatedPass(StringRef PassID);
156+
157+
protected:
158+
// called on the first IR processed
159+
virtual void handleInitialIR(Any IR) = 0;
160+
// called before and after a pass to get the representation of the IR
161+
virtual void generateIRRepresentation(Any IR, StringRef PassID,
162+
IRUnitT &Output) = 0;
163+
// called when the pass is not iteresting
164+
virtual void omitAfter(StringRef PassID, std::string &Name) = 0;
165+
// called when an interesting IR has changed
166+
virtual void handleAfter(StringRef PassID, std::string &Name,
167+
const IRUnitT &Before, const IRUnitT &After,
168+
Any) = 0;
169+
// called when an interesting pass is invalidated
170+
virtual void handleInvalidated(StringRef PassID) = 0;
171+
// called when the IR or pass is not interesting
172+
virtual void handleFiltered(StringRef PassID, std::string &Name) = 0;
173+
// called when an ignored pass is encountered
174+
virtual void handleIgnored(StringRef PassID, std::string &Name) = 0;
175+
// called to compare the before and after representations of the IR
176+
virtual bool same(const IRUnitT &Before, const IRUnitT &After) = 0;
177+
178+
// stack of IRs before passes
179+
std::vector<IRUnitT> BeforeStack;
180+
// Is this the first IR seen?
181+
bool InitialIR;
182+
};
183+
184+
// A change printer based on the string representation of the IR as created
185+
// by unwrapAndPrint. The string representation is stored in a std::string
186+
// to preserve it as the IR changes in each pass. Note that the banner is
187+
// included in this representation but it is massaged before reporting.
188+
class IRChangePrinter : public ChangePrinter<std::string> {
189+
public:
190+
IRChangePrinter();
191+
~IRChangePrinter() override;
192+
void registerCallbacks(PassInstrumentationCallbacks &PIC);
193+
194+
protected:
195+
// called on the first IR processed
196+
void handleInitialIR(Any IR) override;
197+
// called before and after a pass to get the representation of the IR
198+
void generateIRRepresentation(Any IR, StringRef PassID,
199+
std::string &Output) override;
200+
// called when the pass is not iteresting
201+
void omitAfter(StringRef PassID, std::string &Name) override;
202+
// called when an interesting IR has changed
203+
void handleAfter(StringRef PassID, std::string &Name,
204+
const std::string &Before, const std::string &After,
205+
Any) override;
206+
// called when an interesting pass is invalidated
207+
void handleInvalidated(StringRef PassID) override;
208+
// called when the IR or pass is not interesting
209+
void handleFiltered(StringRef PassID, std::string &Name) override;
210+
// called when an ignored pass is encountered
211+
void handleIgnored(StringRef PassID, std::string &Name) override;
212+
// called to compare the before and after representations of the IR
213+
bool same(const std::string &Before, const std::string &After) override;
214+
215+
raw_ostream &Out;
216+
};
217+
127218
/// This class provides an interface to register all the standard pass
128219
/// instrumentations and manages their state (if any).
129220
class StandardInstrumentations {
@@ -132,6 +223,7 @@ class StandardInstrumentations {
132223
TimePassesHandler TimePasses;
133224
OptNoneInstrumentation OptNone;
134225
PreservedCFGCheckerInstrumentation PreservedCFGChecker;
226+
IRChangePrinter PrintChangedIR;
135227

136228
public:
137229
StandardInstrumentations(bool DebugLogging) : PrintPass(DebugLogging) {}

llvm/lib/IR/LegacyPassManager.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,14 @@ static cl::opt<bool> PrintAfterAll("print-after-all",
8787
static cl::opt<bool>
8888
PrintModuleScope("print-module-scope",
8989
cl::desc("When printing IR for print-[before|after]{-all} "
90-
"always print a module IR"),
90+
"and change reporters always print a module IR"),
9191
cl::init(false), cl::Hidden);
9292

9393
static cl::list<std::string>
9494
PrintFuncsList("filter-print-funcs", cl::value_desc("function names"),
9595
cl::desc("Only print IR for functions whose name "
9696
"match this for all print-[before|after][-all] "
97-
"options"),
97+
"and change reporter options"),
9898
cl::CommaSeparated, cl::Hidden);
9999

100100
/// This is a helper to determine whether to print IR before or

0 commit comments

Comments
 (0)