19
19
#include " llvm/Analysis/CallGraphSCCPass.h"
20
20
#include " llvm/Analysis/LazyCallGraph.h"
21
21
#include " llvm/Analysis/LoopInfo.h"
22
+ #include " llvm/CodeGen/FreeMachineFunction.h"
23
+ #include " llvm/CodeGen/MIRPrinter.h"
22
24
#include " llvm/CodeGen/MachineFunction.h"
25
+ #include " llvm/CodeGen/MachineModuleInfo.h"
23
26
#include " llvm/IR/Constants.h"
24
27
#include " llvm/IR/Function.h"
25
28
#include " llvm/IR/Module.h"
@@ -105,18 +108,19 @@ static cl::opt<std::string> PrintOnCrashPath(
105
108
cl::desc (" Print the last form of the IR before crash to a file" ),
106
109
cl::Hidden);
107
110
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);
112
116
113
117
static cl::opt<std::string> OptBisectPrintIRPath (
114
118
" opt-bisect-print-ir-path" ,
115
119
cl::desc (" Print IR to path when opt-bisect-limit is reached" ), cl::Hidden);
116
120
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" ));
120
124
121
125
static cl::opt<unsigned > PrintBeforePassNumber (
122
126
" print-before-pass-number" , cl::init(0 ), cl::Hidden,
@@ -180,6 +184,12 @@ const Module *unwrapModule(Any IR, bool Force = false) {
180
184
return F->getParent ();
181
185
}
182
186
187
+ if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
188
+ if (!Force && !isFunctionInPrintList (MF->getName ()))
189
+ return nullptr ;
190
+ return MF->getFunction ().getParent ();
191
+ }
192
+
183
193
llvm_unreachable (" Unknown IR unit" );
184
194
}
185
195
@@ -215,6 +225,12 @@ void printIR(raw_ostream &OS, const Loop *L) {
215
225
printLoop (const_cast <Loop &>(*L), OS);
216
226
}
217
227
228
+ void printIR (raw_ostream &OS, const MachineFunction *MF) {
229
+ if (!isFunctionInPrintList (MF->getName ()))
230
+ return ;
231
+ MF->print (OS);
232
+ }
233
+
218
234
std::string getIRName (Any IR) {
219
235
if (unwrapIR<Module>(IR))
220
236
return " [module]" ;
@@ -262,6 +278,9 @@ bool shouldPrintIR(Any IR) {
262
278
263
279
if (const auto *L = unwrapIR<Loop>(IR))
264
280
return isFunctionInPrintList (L->getHeader ()->getParent ()->getName ());
281
+
282
+ if (const auto *MF = unwrapIR<MachineFunction>(IR))
283
+ return isFunctionInPrintList (MF->getName ());
265
284
llvm_unreachable (" Unknown wrapped IR type" );
266
285
}
267
286
@@ -275,6 +294,14 @@ void unwrapAndPrint(raw_ostream &OS, Any IR) {
275
294
auto *M = unwrapModule (IR);
276
295
assert (M && " should have unwrapped module" );
277
296
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
+ }
278
305
return ;
279
306
}
280
307
@@ -297,6 +324,11 @@ void unwrapAndPrint(raw_ostream &OS, Any IR) {
297
324
printIR (OS, L);
298
325
return ;
299
326
}
327
+
328
+ if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
329
+ printIR (OS, MF);
330
+ return ;
331
+ }
300
332
llvm_unreachable (" Unknown wrapped IR type" );
301
333
}
302
334
@@ -305,7 +337,8 @@ bool isIgnored(StringRef PassID) {
305
337
return isSpecialPass (PassID,
306
338
{" PassManager" , " PassAdaptor" , " AnalysisManagerProxy" ,
307
339
" DevirtSCCRepeatedPass" , " ModuleInlinerWrapperPass" ,
308
- " VerifierPass" , " PrintModulePass" });
340
+ " VerifierPass" , " PrintModulePass" , " PrintMIRPass" ,
341
+ " PrintMIRPreparePass" });
309
342
}
310
343
311
344
std::string makeHTMLReady (StringRef SR) {
@@ -409,6 +442,10 @@ template <typename T>
409
442
void ChangeReporter<T>::handleInvalidatedPass(StringRef PassID) {
410
443
assert (!BeforeStack.empty () && " Unexpected empty stack encountered." );
411
444
445
+ // Prepare to process the next MIR.
446
+ if (PassID == FreeMachineFunctionPass::name ())
447
+ InitialIR = true ;
448
+
412
449
// Always flag it as invalidated as we cannot determine when
413
450
// a pass for a filtered function is invalidated since we do not
414
451
// get the IR in the call. Also, the output is just alternate
@@ -440,6 +477,13 @@ TextChangeReporter<T>::TextChangeReporter(bool Verbose)
440
477
: ChangeReporter<T>(Verbose), Out(dbgs()) {}
441
478
442
479
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
+
443
487
// Always print the module.
444
488
// Unwrap and print directly to avoid filtering problems in general routines.
445
489
auto *M = unwrapModule (IR, /* Force=*/ true );
@@ -664,20 +708,38 @@ template <typename T> void IRComparer<T>::analyzeIR(Any IR, IRDataT<T> &Data) {
664
708
return ;
665
709
}
666
710
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 ;
672
714
}
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 ());
675
736
}
676
737
677
738
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 ());
681
743
int I = 0 ;
682
744
for (const auto &B : F) {
683
745
std::string BBName = B.getName ().str ();
@@ -722,6 +784,12 @@ static SmallString<32> getIRFileDisplayName(Any IR) {
722
784
ResultStream << " -loop-" ;
723
785
stable_hash LoopNameHash = stable_hash_combine_string (L->getName ());
724
786
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);
725
793
} else {
726
794
llvm_unreachable (" Unknown wrapped IR type" );
727
795
}
@@ -815,8 +883,8 @@ void PrintIRInstrumentation::printBeforePass(StringRef PassID, Any IR) {
815
883
++CurrentPassNumber;
816
884
817
885
if (shouldPrintPassNumbers ())
818
- dbgs () << " Running pass " << CurrentPassNumber << " " << PassID
819
- << " on " << getIRName (IR) << " \n " ;
886
+ dbgs () << " Running pass " << CurrentPassNumber << " " << PassID << " on "
887
+ << getIRName (IR) << " \n " ;
820
888
821
889
if (!shouldPrintBeforePass (PassID))
822
890
return ;
@@ -1038,29 +1106,29 @@ void PrintPassInstrumentation::registerCallbacks(
1038
1106
1039
1107
print () << " Skipping pass: " << PassID << " on " << getIRName (IR) << " \n " ;
1040
1108
});
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 ;
1045
1113
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
+ });
1064
1132
PIC.registerAfterPassCallback (
1065
1133
[this , SpecialPasses](StringRef PassID, Any IR,
1066
1134
const PreservedAnalyses &) {
@@ -1419,16 +1487,14 @@ void VerifyInstrumentation::registerCallbacks(
1419
1487
1420
1488
InLineChangePrinter::~InLineChangePrinter () = default ;
1421
1489
1422
- void InLineChangePrinter::generateIRRepresentation (Any IR,
1423
- StringRef PassID,
1490
+ void InLineChangePrinter::generateIRRepresentation (Any IR, StringRef PassID,
1424
1491
IRDataT<EmptyData> &D) {
1425
1492
IRComparer<EmptyData>::analyzeIR (IR, D);
1426
1493
}
1427
1494
1428
1495
void InLineChangePrinter::handleAfter (StringRef PassID, std::string &Name,
1429
1496
const IRDataT<EmptyData> &Before,
1430
- const IRDataT<EmptyData> &After,
1431
- Any IR) {
1497
+ const IRDataT<EmptyData> &After, Any IR) {
1432
1498
SmallString<20 > Banner =
1433
1499
formatv (" *** IR Dump After {0} on {1} ***\n " , PassID, Name);
1434
1500
Out << Banner;
@@ -2122,6 +2188,11 @@ DCData::DCData(const BasicBlock &B) {
2122
2188
addSuccessorLabel (Succ->getName ().str (), " " );
2123
2189
}
2124
2190
2191
+ DCData::DCData (const MachineBasicBlock &B) {
2192
+ for (const MachineBasicBlock *Succ : successors (&B))
2193
+ addSuccessorLabel (Succ->getName ().str (), " " );
2194
+ }
2195
+
2125
2196
DotCfgChangeReporter::DotCfgChangeReporter (bool Verbose)
2126
2197
: ChangeReporter<IRDataT<DCData>>(Verbose) {}
2127
2198
@@ -2188,7 +2259,7 @@ std::string DotCfgChangeReporter::genHTML(StringRef Text, StringRef DotFile,
2188
2259
2189
2260
void DotCfgChangeReporter::handleInitialIR (Any IR) {
2190
2261
assert (HTML && " Expected outstream to be set" );
2191
- *HTML << " <button type=\" button\" class=\" collapsible\" >0 . "
2262
+ *HTML << " <button type=\" button\" class=\" collapsible\" >" << N << " . "
2192
2263
<< " Initial IR (by function)</button>\n "
2193
2264
<< " <div class=\" content\" >\n "
2194
2265
<< " <p>\n " ;
@@ -2329,7 +2400,7 @@ DotCfgChangeReporter::~DotCfgChangeReporter() {
2329
2400
void DotCfgChangeReporter::registerCallbacks (
2330
2401
PassInstrumentationCallbacks &PIC) {
2331
2402
if (PrintChanged == ChangePrinter::DotCfgVerbose ||
2332
- PrintChanged == ChangePrinter::DotCfgQuiet) {
2403
+ PrintChanged == ChangePrinter::DotCfgQuiet) {
2333
2404
SmallString<128 > OutputDir;
2334
2405
sys::fs::expand_tilde (DotCfgDir, OutputDir);
2335
2406
sys::fs::make_absolute (OutputDir);
@@ -2346,8 +2417,7 @@ void DotCfgChangeReporter::registerCallbacks(
2346
2417
StandardInstrumentations::StandardInstrumentations (
2347
2418
LLVMContext &Context, bool DebugLogging, bool VerifyEach,
2348
2419
PrintPassOptions PrintPassOpts)
2349
- : PrintPass(DebugLogging, PrintPassOpts),
2350
- OptNone (DebugLogging),
2420
+ : PrintPass(DebugLogging, PrintPassOpts), OptNone(DebugLogging),
2351
2421
OptPassGate (Context),
2352
2422
PrintChangedIR(PrintChanged == ChangePrinter::Verbose),
2353
2423
PrintChangedDiff(PrintChanged == ChangePrinter::DiffVerbose ||
0 commit comments