Skip to content

Commit b4726bd

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

File tree

4 files changed

+141
-13
lines changed

4 files changed

+141
-13
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: 84 additions & 12 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"
@@ -180,6 +183,12 @@ const Module *unwrapModule(Any IR, bool Force = false) {
180183
return F->getParent();
181184
}
182185

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

@@ -215,6 +224,12 @@ void printIR(raw_ostream &OS, const Loop *L) {
215224
printLoop(const_cast<Loop &>(*L), OS);
216225
}
217226

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

263278
if (const auto *L = unwrapIR<Loop>(IR))
264279
return isFunctionInPrintList(L->getHeader()->getParent()->getName());
280+
281+
if (const auto *MF = unwrapIR<MachineFunction>(IR))
282+
return isFunctionInPrintList(MF->getName());
265283
llvm_unreachable("Unknown wrapped IR type");
266284
}
267285

@@ -275,6 +293,14 @@ void unwrapAndPrint(raw_ostream &OS, Any IR) {
275293
auto *M = unwrapModule(IR);
276294
assert(M && "should have unwrapped module");
277295
printIR(OS, M);
296+
297+
if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
298+
auto &MMI = MF->getMMI();
299+
for (const auto &F : *M) {
300+
if (auto *MF = MMI.getMachineFunction(F))
301+
MF->print(OS);
302+
}
303+
}
278304
return;
279305
}
280306

@@ -297,6 +323,11 @@ void unwrapAndPrint(raw_ostream &OS, Any IR) {
297323
printIR(OS, L);
298324
return;
299325
}
326+
327+
if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
328+
printIR(OS, MF);
329+
return;
330+
}
300331
llvm_unreachable("Unknown wrapped IR type");
301332
}
302333

@@ -305,7 +336,8 @@ bool isIgnored(StringRef PassID) {
305336
return isSpecialPass(PassID,
306337
{"PassManager", "PassAdaptor", "AnalysisManagerProxy",
307338
"DevirtSCCRepeatedPass", "ModuleInlinerWrapperPass",
308-
"VerifierPass", "PrintModulePass"});
339+
"VerifierPass", "PrintModulePass", "PrintMIRPass",
340+
"PrintMIRPreparePass"});
309341
}
310342

311343
std::string makeHTMLReady(StringRef SR) {
@@ -409,6 +441,10 @@ template <typename T>
409441
void ChangeReporter<T>::handleInvalidatedPass(StringRef PassID) {
410442
assert(!BeforeStack.empty() && "Unexpected empty stack encountered.");
411443

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

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

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();
710+
if (const auto *F = unwrapIR<Function>(IR)) {
711+
generateFunctionData(Data, *F);
712+
return;
713+
}
714+
715+
if (const auto *L = unwrapIR<Loop>(IR)) {
716+
auto *F = L->getHeader()->getParent();
717+
generateFunctionData(Data, *F);
718+
return;
719+
}
720+
721+
if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
722+
generateFunctionData(Data, *MF);
723+
return;
672724
}
673-
assert(F && "Unknown IR unit.");
674-
generateFunctionData(Data, *F);
725+
726+
llvm_unreachable("Unknown IR unit");
727+
}
728+
729+
static bool shouldGenerateData(const Function &F) {
730+
return !F.isDeclaration() && isFunctionInPrintList(F.getName());
731+
}
732+
733+
static bool shouldGenerateData(const MachineFunction &MF) {
734+
return isFunctionInPrintList(MF.getName());
675735
}
676736

677737
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());
738+
template <typename FunctionT>
739+
bool IRComparer<T>::generateFunctionData(IRDataT<T> &Data, const FunctionT &F) {
740+
if (shouldGenerateData(F)) {
741+
FuncDataT<T> FD(F.front().getName().str());
681742
int I = 0;
682743
for (const auto &B : F) {
683744
std::string BBName = B.getName().str();
@@ -722,6 +783,12 @@ static SmallString<32> getIRFileDisplayName(Any IR) {
722783
ResultStream << "-loop-";
723784
stable_hash LoopNameHash = stable_hash_combine_string(L->getName());
724785
write_hex(ResultStream, LoopNameHash, HexPrintStyle::Lower, MaxHashWidth);
786+
} else if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
787+
ResultStream << "-machine-function-";
788+
stable_hash MachineFunctionNameHash =
789+
stable_hash_combine_string(MF->getName());
790+
write_hex(ResultStream, MachineFunctionNameHash, HexPrintStyle::Lower,
791+
MaxHashWidth);
725792
} else {
726793
llvm_unreachable("Unknown wrapped IR type");
727794
}
@@ -2122,6 +2189,11 @@ DCData::DCData(const BasicBlock &B) {
21222189
addSuccessorLabel(Succ->getName().str(), "");
21232190
}
21242191

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

@@ -2188,7 +2260,7 @@ std::string DotCfgChangeReporter::genHTML(StringRef Text, StringRef DotFile,
21882260

21892261
void DotCfgChangeReporter::handleInitialIR(Any IR) {
21902262
assert(HTML && "Expected outstream to be set");
2191-
*HTML << "<button type=\"button\" class=\"collapsible\">0. "
2263+
*HTML << "<button type=\"button\" class=\"collapsible\">" << N << ". "
21922264
<< "Initial IR (by function)</button>\n"
21932265
<< "<div class=\"content\">\n"
21942266
<< " <p>\n";
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+
...

llvm/test/Other/change-printer.mir

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# REQUIRES: x86-registered-target
2+
# RUN: llc -mtriple=x86_64-unknown-linux-gnu -filetype=null %s \
3+
# RUN: -p no-op-machine-function -print-changed 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OP
4+
5+
# RUN: llc -mtriple=x86_64-unknown-linux-gnu -filetype=null %s \
6+
# RUN: -p dead-mi-elimination -print-changed 2>&1 | FileCheck %s --check-prefix=CHECK-SIMPLE
7+
8+
---
9+
name: test
10+
body: |
11+
bb.0:
12+
%1:gr64 = MOV64ri 0
13+
%2:gr64 = MOV64ri 0
14+
$eax = COPY %1
15+
RET64 implicit $eax
16+
...
17+
18+
# CHECK-NO-OP: *** IR Dump After NoOpMachineFunctionPass on test omitted because no change ***
19+
20+
# CHECK-SIMPLE: *** IR Dump After DeadMachineInstructionElimPass on test ***
21+
# CHECK-SIMPLE-NOT: %2:gr64 = MOV64ri 0

0 commit comments

Comments
 (0)