Skip to content

Commit 0442446

Browse files
committed
[Instrumentation] Support MachineFunction in ChangeReporter
1 parent f546b6e commit 0442446

File tree

4 files changed

+177
-51
lines changed

4 files changed

+177
-51
lines changed

llvm/include/llvm/Passes/StandardInstrumentations.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "llvm/ADT/STLExtras.h"
1919
#include "llvm/ADT/SmallVector.h"
2020
#include "llvm/ADT/StringRef.h"
21+
#include "llvm/ADT/StringSet.h"
22+
#include "llvm/CodeGen/MachineBasicBlock.h"
2123
#include "llvm/IR/BasicBlock.h"
2224
#include "llvm/IR/OptBisect.h"
2325
#include "llvm/IR/PassTimingInfo.h"
@@ -33,6 +35,7 @@ namespace llvm {
3335

3436
class Module;
3537
class Function;
38+
class MachineFunction;
3639
class PassInstrumentationCallbacks;
3740

3841
/// Instrumentation to print IR before/after passes.
@@ -313,6 +316,11 @@ template <typename T> class BlockDataT {
313316
B.print(SS, nullptr, true, true);
314317
}
315318

319+
BlockDataT(const MachineBasicBlock &B) : Label(B.getName().str()), Data(B) {
320+
raw_string_ostream SS(Body);
321+
B.print(SS);
322+
}
323+
316324
bool operator==(const BlockDataT &That) const { return Body == That.Body; }
317325
bool operator!=(const BlockDataT &That) const { return Body != That.Body; }
318326

@@ -364,6 +372,7 @@ template <typename T> class OrderedChangedData {
364372
class EmptyData {
365373
public:
366374
EmptyData(const BasicBlock &) {}
375+
EmptyData(const MachineBasicBlock &) {}
367376
};
368377

369378
// The data saved for comparing functions.
@@ -405,7 +414,8 @@ template <typename T> class IRComparer {
405414

406415
protected:
407416
// Generate the data for \p F into \p Data.
408-
static bool generateFunctionData(IRDataT<T> &Data, const Function &F);
417+
template <typename FunctionT>
418+
static bool generateFunctionData(IRDataT<T> &Data, const FunctionT &F);
409419

410420
const IRDataT<T> &Before;
411421
const IRDataT<T> &After;
@@ -475,6 +485,7 @@ class DCData {
475485
public:
476486
// Fill the map with the transitions from basic block \p B.
477487
DCData(const BasicBlock &B);
488+
DCData(const MachineBasicBlock &B);
478489

479490
// Return an iterator to the names of the successor blocks.
480491
StringMap<std::string>::const_iterator begin() const {

llvm/lib/Passes/StandardInstrumentations.cpp

Lines changed: 120 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
#include "llvm/Analysis/CallGraphSCCPass.h"
2020
#include "llvm/Analysis/LazyCallGraph.h"
2121
#include "llvm/Analysis/LoopInfo.h"
22+
#include "llvm/CodeGen/FreeMachineFunction.h"
23+
#include "llvm/CodeGen/MIRPrinter.h"
2224
#include "llvm/CodeGen/MachineFunction.h"
25+
#include "llvm/CodeGen/MachineModuleInfo.h"
2326
#include "llvm/IR/Constants.h"
2427
#include "llvm/IR/Function.h"
2528
#include "llvm/IR/Module.h"
@@ -105,18 +108,19 @@ static cl::opt<std::string> PrintOnCrashPath(
105108
cl::desc("Print the last form of the IR before crash to a file"),
106109
cl::Hidden);
107110

108-
static cl::opt<bool> PrintOnCrash(
109-
"print-on-crash",
110-
cl::desc("Print the last form of the IR before crash (use -print-on-crash-path to dump to a file)"),
111-
cl::Hidden);
111+
static cl::opt<bool>
112+
PrintOnCrash("print-on-crash",
113+
cl::desc("Print the last form of the IR before crash (use "
114+
"-print-on-crash-path to dump to a file)"),
115+
cl::Hidden);
112116

113117
static cl::opt<std::string> OptBisectPrintIRPath(
114118
"opt-bisect-print-ir-path",
115119
cl::desc("Print IR to path when opt-bisect-limit is reached"), cl::Hidden);
116120

117-
static cl::opt<bool> PrintPassNumbers(
118-
"print-pass-numbers", cl::init(false), cl::Hidden,
119-
cl::desc("Print pass names and their ordinals"));
121+
static cl::opt<bool>
122+
PrintPassNumbers("print-pass-numbers", cl::init(false), cl::Hidden,
123+
cl::desc("Print pass names and their ordinals"));
120124

121125
static cl::opt<unsigned> PrintBeforePassNumber(
122126
"print-before-pass-number", cl::init(0), cl::Hidden,
@@ -180,6 +184,12 @@ const Module *unwrapModule(Any IR, bool Force = false) {
180184
return F->getParent();
181185
}
182186

187+
if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
188+
if (!Force && !isFunctionInPrintList(MF->getName()))
189+
return nullptr;
190+
return MF->getFunction().getParent();
191+
}
192+
183193
llvm_unreachable("Unknown IR unit");
184194
}
185195

@@ -215,6 +225,12 @@ void printIR(raw_ostream &OS, const Loop *L) {
215225
printLoop(const_cast<Loop &>(*L), OS);
216226
}
217227

228+
void printIR(raw_ostream &OS, const MachineFunction *MF) {
229+
if (!isFunctionInPrintList(MF->getName()))
230+
return;
231+
MF->print(OS);
232+
}
233+
218234
std::string getIRName(Any IR) {
219235
if (unwrapIR<Module>(IR))
220236
return "[module]";
@@ -262,6 +278,9 @@ bool shouldPrintIR(Any IR) {
262278

263279
if (const auto *L = unwrapIR<Loop>(IR))
264280
return isFunctionInPrintList(L->getHeader()->getParent()->getName());
281+
282+
if (const auto *MF = unwrapIR<MachineFunction>(IR))
283+
return isFunctionInPrintList(MF->getName());
265284
llvm_unreachable("Unknown wrapped IR type");
266285
}
267286

@@ -275,6 +294,14 @@ void unwrapAndPrint(raw_ostream &OS, Any IR) {
275294
auto *M = unwrapModule(IR);
276295
assert(M && "should have unwrapped module");
277296
printIR(OS, M);
297+
298+
if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
299+
auto &MMI = MF->getMMI();
300+
for (const auto &F : *M) {
301+
if (auto *MF = MMI.getMachineFunction(F))
302+
MF->print(OS);
303+
}
304+
}
278305
return;
279306
}
280307

@@ -297,6 +324,11 @@ void unwrapAndPrint(raw_ostream &OS, Any IR) {
297324
printIR(OS, L);
298325
return;
299326
}
327+
328+
if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
329+
printIR(OS, MF);
330+
return;
331+
}
300332
llvm_unreachable("Unknown wrapped IR type");
301333
}
302334

@@ -305,7 +337,8 @@ bool isIgnored(StringRef PassID) {
305337
return isSpecialPass(PassID,
306338
{"PassManager", "PassAdaptor", "AnalysisManagerProxy",
307339
"DevirtSCCRepeatedPass", "ModuleInlinerWrapperPass",
308-
"VerifierPass", "PrintModulePass"});
340+
"VerifierPass", "PrintModulePass", "PrintMIRPass",
341+
"PrintMIRPreparePass"});
309342
}
310343

311344
std::string makeHTMLReady(StringRef SR) {
@@ -409,6 +442,10 @@ template <typename T>
409442
void ChangeReporter<T>::handleInvalidatedPass(StringRef PassID) {
410443
assert(!BeforeStack.empty() && "Unexpected empty stack encountered.");
411444

445+
// Prepare to process the next MIR.
446+
if (PassID == FreeMachineFunctionPass::name())
447+
InitialIR = true;
448+
412449
// Always flag it as invalidated as we cannot determine when
413450
// a pass for a filtered function is invalidated since we do not
414451
// get the IR in the call. Also, the output is just alternate
@@ -440,6 +477,13 @@ TextChangeReporter<T>::TextChangeReporter(bool Verbose)
440477
: ChangeReporter<T>(Verbose), Out(dbgs()) {}
441478

442479
template <typename T> void TextChangeReporter<T>::handleInitialIR(Any IR) {
480+
// MIR is special, not all MIRs are available at the beginning.
481+
if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
482+
Out << "*** MIR Dump At Start ***\n";
483+
MF->print(Out);
484+
return;
485+
}
486+
443487
// Always print the module.
444488
// Unwrap and print directly to avoid filtering problems in general routines.
445489
auto *M = unwrapModule(IR, /*Force=*/true);
@@ -664,20 +708,38 @@ template <typename T> void IRComparer<T>::analyzeIR(Any IR, IRDataT<T> &Data) {
664708
return;
665709
}
666710

667-
const auto *F = unwrapIR<Function>(IR);
668-
if (!F) {
669-
const auto *L = unwrapIR<Loop>(IR);
670-
assert(L && "Unknown IR unit.");
671-
F = L->getHeader()->getParent();
711+
if (const auto *F = unwrapIR<Function>(IR)) {
712+
generateFunctionData(Data, *F);
713+
return;
672714
}
673-
assert(F && "Unknown IR unit.");
674-
generateFunctionData(Data, *F);
715+
716+
if (const auto *L = unwrapIR<Loop>(IR)) {
717+
auto *F = L->getHeader()->getParent();
718+
generateFunctionData(Data, *F);
719+
return;
720+
}
721+
722+
if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
723+
generateFunctionData(Data, *MF);
724+
return;
725+
}
726+
727+
llvm_unreachable("Unknown IR unit");
728+
}
729+
730+
static bool shouldGenerateData(const Function &F) {
731+
return !F.isDeclaration() && isFunctionInPrintList(F.getName());
732+
}
733+
734+
static bool shouldGenerateData(const MachineFunction &MF) {
735+
return isFunctionInPrintList(MF.getName());
675736
}
676737

677738
template <typename T>
678-
bool IRComparer<T>::generateFunctionData(IRDataT<T> &Data, const Function &F) {
679-
if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) {
680-
FuncDataT<T> FD(F.getEntryBlock().getName().str());
739+
template <typename FunctionT>
740+
bool IRComparer<T>::generateFunctionData(IRDataT<T> &Data, const FunctionT &F) {
741+
if (shouldGenerateData(F)) {
742+
FuncDataT<T> FD(F.front().getName().str());
681743
int I = 0;
682744
for (const auto &B : F) {
683745
std::string BBName = B.getName().str();
@@ -722,6 +784,12 @@ static SmallString<32> getIRFileDisplayName(Any IR) {
722784
ResultStream << "-loop-";
723785
stable_hash LoopNameHash = stable_hash_combine_string(L->getName());
724786
write_hex(ResultStream, LoopNameHash, HexPrintStyle::Lower, MaxHashWidth);
787+
} else if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
788+
ResultStream << "-machine-function-";
789+
stable_hash MachineFunctionNameHash =
790+
stable_hash_combine_string(MF->getName());
791+
write_hex(ResultStream, MachineFunctionNameHash, HexPrintStyle::Lower,
792+
MaxHashWidth);
725793
} else {
726794
llvm_unreachable("Unknown wrapped IR type");
727795
}
@@ -815,8 +883,8 @@ void PrintIRInstrumentation::printBeforePass(StringRef PassID, Any IR) {
815883
++CurrentPassNumber;
816884

817885
if (shouldPrintPassNumbers())
818-
dbgs() << " Running pass " << CurrentPassNumber << " " << PassID
819-
<< " on " << getIRName(IR) << "\n";
886+
dbgs() << " Running pass " << CurrentPassNumber << " " << PassID << " on "
887+
<< getIRName(IR) << "\n";
820888

821889
if (!shouldPrintBeforePass(PassID))
822890
return;
@@ -1038,29 +1106,29 @@ void PrintPassInstrumentation::registerCallbacks(
10381106

10391107
print() << "Skipping pass: " << PassID << " on " << getIRName(IR) << "\n";
10401108
});
1041-
PIC.registerBeforeNonSkippedPassCallback([this, SpecialPasses](
1042-
StringRef PassID, Any IR) {
1043-
if (isSpecialPass(PassID, SpecialPasses))
1044-
return;
1109+
PIC.registerBeforeNonSkippedPassCallback(
1110+
[this, SpecialPasses](StringRef PassID, Any IR) {
1111+
if (isSpecialPass(PassID, SpecialPasses))
1112+
return;
10451113

1046-
auto &OS = print();
1047-
OS << "Running pass: " << PassID << " on " << getIRName(IR);
1048-
if (const auto *F = unwrapIR<Function>(IR)) {
1049-
unsigned Count = F->getInstructionCount();
1050-
OS << " (" << Count << " instruction";
1051-
if (Count != 1)
1052-
OS << 's';
1053-
OS << ')';
1054-
} else if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR)) {
1055-
int Count = C->size();
1056-
OS << " (" << Count << " node";
1057-
if (Count != 1)
1058-
OS << 's';
1059-
OS << ')';
1060-
}
1061-
OS << "\n";
1062-
Indent += 2;
1063-
});
1114+
auto &OS = print();
1115+
OS << "Running pass: " << PassID << " on " << getIRName(IR);
1116+
if (const auto *F = unwrapIR<Function>(IR)) {
1117+
unsigned Count = F->getInstructionCount();
1118+
OS << " (" << Count << " instruction";
1119+
if (Count != 1)
1120+
OS << 's';
1121+
OS << ')';
1122+
} else if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR)) {
1123+
int Count = C->size();
1124+
OS << " (" << Count << " node";
1125+
if (Count != 1)
1126+
OS << 's';
1127+
OS << ')';
1128+
}
1129+
OS << "\n";
1130+
Indent += 2;
1131+
});
10641132
PIC.registerAfterPassCallback(
10651133
[this, SpecialPasses](StringRef PassID, Any IR,
10661134
const PreservedAnalyses &) {
@@ -1419,16 +1487,14 @@ void VerifyInstrumentation::registerCallbacks(
14191487

14201488
InLineChangePrinter::~InLineChangePrinter() = default;
14211489

1422-
void InLineChangePrinter::generateIRRepresentation(Any IR,
1423-
StringRef PassID,
1490+
void InLineChangePrinter::generateIRRepresentation(Any IR, StringRef PassID,
14241491
IRDataT<EmptyData> &D) {
14251492
IRComparer<EmptyData>::analyzeIR(IR, D);
14261493
}
14271494

14281495
void InLineChangePrinter::handleAfter(StringRef PassID, std::string &Name,
14291496
const IRDataT<EmptyData> &Before,
1430-
const IRDataT<EmptyData> &After,
1431-
Any IR) {
1497+
const IRDataT<EmptyData> &After, Any IR) {
14321498
SmallString<20> Banner =
14331499
formatv("*** IR Dump After {0} on {1} ***\n", PassID, Name);
14341500
Out << Banner;
@@ -2122,6 +2188,11 @@ DCData::DCData(const BasicBlock &B) {
21222188
addSuccessorLabel(Succ->getName().str(), "");
21232189
}
21242190

2191+
DCData::DCData(const MachineBasicBlock &B) {
2192+
for (const MachineBasicBlock *Succ : successors(&B))
2193+
addSuccessorLabel(Succ->getName().str(), "");
2194+
}
2195+
21252196
DotCfgChangeReporter::DotCfgChangeReporter(bool Verbose)
21262197
: ChangeReporter<IRDataT<DCData>>(Verbose) {}
21272198

@@ -2188,7 +2259,7 @@ std::string DotCfgChangeReporter::genHTML(StringRef Text, StringRef DotFile,
21882259

21892260
void DotCfgChangeReporter::handleInitialIR(Any IR) {
21902261
assert(HTML && "Expected outstream to be set");
2191-
*HTML << "<button type=\"button\" class=\"collapsible\">0. "
2262+
*HTML << "<button type=\"button\" class=\"collapsible\">" << N << ". "
21922263
<< "Initial IR (by function)</button>\n"
21932264
<< "<div class=\"content\">\n"
21942265
<< " <p>\n";
@@ -2329,7 +2400,7 @@ DotCfgChangeReporter::~DotCfgChangeReporter() {
23292400
void DotCfgChangeReporter::registerCallbacks(
23302401
PassInstrumentationCallbacks &PIC) {
23312402
if (PrintChanged == ChangePrinter::DotCfgVerbose ||
2332-
PrintChanged == ChangePrinter::DotCfgQuiet) {
2403+
PrintChanged == ChangePrinter::DotCfgQuiet) {
23332404
SmallString<128> OutputDir;
23342405
sys::fs::expand_tilde(DotCfgDir, OutputDir);
23352406
sys::fs::make_absolute(OutputDir);
@@ -2346,8 +2417,7 @@ void DotCfgChangeReporter::registerCallbacks(
23462417
StandardInstrumentations::StandardInstrumentations(
23472418
LLVMContext &Context, bool DebugLogging, bool VerifyEach,
23482419
PrintPassOptions PrintPassOpts)
2349-
: PrintPass(DebugLogging, PrintPassOpts),
2350-
OptNone(DebugLogging),
2420+
: PrintPass(DebugLogging, PrintPassOpts), OptNone(DebugLogging),
23512421
OptPassGate(Context),
23522422
PrintChangedIR(PrintChanged == ChangePrinter::Verbose),
23532423
PrintChangedDiff(PrintChanged == ChangePrinter::DiffVerbose ||
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# REQUIRES: x86-registered-target
2+
# Simple functionality check.
3+
# RUN: rm -rf %t && mkdir -p %t
4+
# RUN: llc -filetype=null -print-changed=dot-cfg -passes=no-op-machine-function -dot-cfg-dir=%t %s
5+
# RUN: ls %t/*.pdf %t/passes.html | count 3
6+
7+
---
8+
name: g
9+
body: |
10+
bb.0.entry:
11+
%0:gr32 = MOV32ri 5
12+
$eax = COPY %0
13+
RET 0, $eax
14+
15+
...
16+
---
17+
name: f
18+
body: |
19+
bb.0.entry:
20+
%0:gr32 = MOV32ri 7
21+
$eax = COPY %0
22+
RET 0, $eax
23+
24+
...

0 commit comments

Comments
 (0)