Lines Matching full:ir

10 /// This file defines IR-printing pass instrumentation callbacks as well as
26 #include "llvm/IR/Constants.h"
27 #include "llvm/IR/Function.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/IR/PassInstrumentation.h"
30 #include "llvm/IR/PassManager.h"
31 #include "llvm/IR/PrintPasses.h"
32 #include "llvm/IR/StructuralHash.h"
33 #include "llvm/IR/Verifier.h"
105 // Options to print the IR that was being processed when a pass crashes.
108 cl::desc("Print the last form of the IR before crash to a file"),
113 cl::desc("Print the last form of the IR before crash (use -print-on-crash-path to dump to a file)"),
117 "opt-bisect-print-ir-path",
118 cl::desc("Print IR to path when opt-bisect-limit is reached"), cl::Hidden);
126 cl::desc("Print IR before the pass with this number as "
131 cl::desc("Print IR after the pass with this number as "
135 "ir-dump-directory",
136 cl::desc("If specified, IR printed using the "
141 template <typename IRUnitT> static const IRUnitT *unwrapIR(Any IR) {
142 const IRUnitT **IRPtr = llvm::any_cast<const IRUnitT *>(&IR);
148 // An option for specifying an executable that will be called with the IR
150 // the initial IR as it enters the pipeline. The executable will be passed
151 // the name of a temporary file containing the IR and the PassID. This may
152 // be used, for example, to call llc on the IR and run a test to determine
153 // which pass makes a change that changes the functioning of the IR.
156 TestChanged("exec-on-ir-change", cl::Hidden, cl::init(""),
157 cl::desc("exe called with module IR after each pass that "
160 /// Extract Module out of \p IR unit. May return nullptr if \p IR does not match
162 const Module *unwrapModule(Any IR, bool Force = false) {
163 if (const auto *M = unwrapIR<Module>(IR))
166 if (const auto *F = unwrapIR<Function>(IR)) {
173 if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR)) {
184 if (const auto *L = unwrapIR<Loop>(IR)) {
191 if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
197 llvm_unreachable("Unknown IR unit");
238 std::string getIRName(Any IR) {
239 if (unwrapIR<Module>(IR))
242 if (const auto *F = unwrapIR<Function>(IR))
245 if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR))
248 if (const auto *L = unwrapIR<Loop>(IR))
252 if (const auto *MF = unwrapIR<MachineFunction>(IR))
255 llvm_unreachable("Unknown wrapped IR type");
274 bool shouldPrintIR(Any IR) {
275 if (const auto *M = unwrapIR<Module>(IR))
278 if (const auto *F = unwrapIR<Function>(IR))
281 if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR))
284 if (const auto *L = unwrapIR<Loop>(IR))
287 if (const auto *MF = unwrapIR<MachineFunction>(IR))
289 llvm_unreachable("Unknown wrapped IR type");
292 /// Generic IR-printing helper that unpacks a pointer to IRUnit wrapped into
294 void unwrapAndPrint(raw_ostream &OS, Any IR) {
295 if (!shouldPrintIR(IR))
299 auto *M = unwrapModule(IR);
305 if (const auto *M = unwrapIR<Module>(IR)) {
310 if (const auto *F = unwrapIR<Function>(IR)) {
315 if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR)) {
320 if (const auto *L = unwrapIR<Loop>(IR)) {
325 if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
329 llvm_unreachable("Unknown wrapped IR type");
356 // Return the module when that is the appropriate level of comparison for \p IR.
357 const Module *getModuleForComparison(Any IR) {
358 if (const auto *M = unwrapIR<Module>(IR))
360 if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR))
369 // Return true when this is a pass on IR for which printing
371 bool isInteresting(Any IR, StringRef PassID, StringRef PassName) {
374 if (const auto *F = unwrapIR<Function>(IR))
386 void ChangeReporter<T>::saveIRBeforePass(Any IR, StringRef PassID,
388 // Is this the initial IR?
392 handleInitialIR(IR);
396 // are not given the IR so it cannot be determined whether the pass was for
400 if (!isInteresting(IR, PassID, PassName))
403 // Save the IR representation on the stack.
405 generateIRRepresentation(IR, PassID, Data);
409 void ChangeReporter<T>::handleIRAfterPass(Any IR, StringRef PassID,
413 std::string Name = getIRName(IR);
418 } else if (!isInteresting(IR, PassID, PassName)) {
426 generateIRRepresentation(IR, PassID, After);
428 // Was there a change in IR?
433 handleAfter(PassID, Name, Before, After, IR);
444 // get the IR in the call. Also, the output is just alternate
454 PIC.registerBeforeNonSkippedPassCallback([&PIC, this](StringRef P, Any IR) {
455 saveIRBeforePass(IR, P, PIC.getPassNameForClassName(P));
459 [&PIC, this](StringRef P, Any IR, const PreservedAnalyses &) {
460 handleIRAfterPass(IR, P, PIC.getPassNameForClassName(P));
472 template <typename T> void TextChangeReporter<T>::handleInitialIR(Any IR) {
475 auto *M = unwrapModule(IR, /*Force=*/true);
477 Out << "*** IR Dump At Start ***\n";
483 Out << formatv("*** IR Dump After {0} on {1} omitted because no change ***\n",
489 Out << formatv("*** IR Pass {0} invalidated ***\n", PassID);
496 formatv("*** IR Dump After {0} on {1} filtered out ***\n", PassID, Name);
502 Out << formatv("*** IR Pass {0} on {1} ignored ***\n", PassID, Name);
513 void IRChangedPrinter::generateIRRepresentation(Any IR, StringRef PassID,
516 unwrapAndPrint(OS, IR);
523 // Report the IR before the changes when requested.
525 Out << "*** IR Dump Before " << PassID << " on " << Name << " ***\n"
531 Out << "*** IR Deleted After " << PassID << " on " << Name << " ***\n";
535 Out << "*** IR Dump After " << PassID << " on " << Name << " ***\n" << After;
571 void IRChangedTester::handleInitialIR(Any IR) {
575 generateIRRepresentation(IR, "Initial IR", S);
576 handleIR(S, "Initial IR");
689 template <typename T> void IRComparer<T>::analyzeIR(Any IR, IRDataT<T> &Data) {
690 if (const Module *M = getModuleForComparison(IR)) {
697 if (const auto *F = unwrapIR<Function>(IR)) {
702 if (const auto *L = unwrapIR<Loop>(IR)) {
708 if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
713 llvm_unreachable("Unknown IR unit");
751 static SmallString<32> getIRFileDisplayName(Any IR) {
754 const Module *M = unwrapModule(IR);
758 if (unwrapIR<Module>(IR)) {
760 } else if (const auto *F = unwrapIR<Function>(IR)) {
765 } else if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR)) {
769 } else if (const auto *L = unwrapIR<Loop>(IR)) {
773 } else if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
780 llvm_unreachable("Unknown wrapped IR type");
786 Any IR) {
789 "The flag -ir-dump-directory must be passed to dump IR to files");
796 FilenameStream << getIRFileDisplayName(IR);
816 StringRef PassID, Any IR, std::string &DumpIRFilename) {
817 const Module *M = unwrapModule(IR);
819 PassRunDescriptor(M, DumpIRFilename, getIRName(IR), PassID));
838 " to support -ir-dump-directory: " + EC.message());
845 " to support -ir-dump-directory: " + EC.message());
849 void PrintIRInstrumentation::printBeforePass(StringRef PassID, Any IR) {
858 DumpIRFilename = fetchDumpFilename(PassID, IR);
865 pushPassRunDescriptor(PassID, IR, DumpIRFilename);
867 if (!shouldPrintIR(IR))
874 << " on " << getIRName(IR) << "\n";
877 pushPassRunDescriptor(PassID, IR, DumpIRFilename);
883 Stream << "; *** IR Dump Before ";
886 Stream << PassID << " on " << getIRName(IR) << " ***\n";
887 unwrapAndPrint(Stream, IR);
900 void PrintIRInstrumentation::printAfterPass(StringRef PassID, Any IR) {
910 if (!shouldPrintIR(IR) ||
915 Stream << "; *** IR Dump After ";
919 unwrapAndPrint(Stream, IR);
954 Banner = formatv("; *** IR Dump After {0} on {1} (invalidated) ***", PassID,
1023 [this](StringRef P, Any IR) { this->printBeforePass(P, IR); });
1027 [this](StringRef P, Any IR, const PreservedAnalyses &) {
1028 this->printAfterPass(P, IR);
1040 [this](StringRef P, Any IR) { return this->shouldRun(P, IR); });
1043 bool OptNoneInstrumentation::shouldRun(StringRef PassID, Any IR) {
1044 const auto *F = unwrapIR<Function>(IR);
1046 if (const auto *L = unwrapIR<Loop>(IR))
1057 bool OptPassGateInstrumentation::shouldRun(StringRef PassName, Any IR) {
1062 Context.getOptPassGate().shouldRunPass(PassName, getIRName(IR));
1064 // FIXME: print IR if limit is higher than number of opt-bisect
1067 const Module *M = unwrapModule(IR, /*Force=*/true);
1084 PIC.registerShouldRunOptionalPassCallback([this](StringRef PassName, Any IR) {
1085 return this->shouldRun(PassName, IR);
1109 Any IR) {
1113 print() << "Skipping pass: " << PassID << " on " << getIRName(IR) << "\n";
1116 StringRef PassID, Any IR) {
1121 OS << "Running pass: " << PassID << " on " << getIRName(IR);
1122 if (const auto *F = unwrapIR<Function>(IR)) {
1128 } else if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR)) {
1139 [this, SpecialPasses](StringRef PassID, Any IR,
1147 [this, SpecialPasses](StringRef PassID, Any IR) {
1155 PIC.registerBeforeAnalysisCallback([this](StringRef PassID, Any IR) {
1156 print() << "Running analysis: " << PassID << " on " << getIRName(IR)
1161 [this](StringRef PassID, Any IR) { Indent -= 2; });
1162 PIC.registerAnalysisInvalidatedCallback([this](StringRef PassID, Any IR) {
1163 print() << "Invalidating analysis: " << PassID << " on " << getIRName(IR)
1341 static SmallVector<Function *, 1> GetFunctions(Any IR) {
1344 if (const auto *MaybeF = unwrapIR<Function>(IR)) {
1346 } else if (const auto *MaybeM = unwrapIR<Module>(IR)) {
1360 StringRef P, Any IR) mutable {
1367 *const_cast<Module *>(unwrapModule(IR, /*Force=*/true)))
1376 for (Function *F : GetFunctions(IR)) {
1382 if (const auto *MPtr = unwrapIR<Module>(IR)) {
1397 PIC.registerAfterPassCallback([this, &MAM](StringRef P, Any IR,
1409 *const_cast<Module *>(unwrapModule(IR, /*Force=*/true)))
1412 for (Function *F : GetFunctions(IR)) {
1441 if (const auto *MPtr = unwrapIR<Module>(IR)) {
1457 [this, MAM](StringRef P, Any IR, const PreservedAnalyses &PassPA) {
1460 const auto *F = unwrapIR<Function>(IR);
1462 if (const auto *L = unwrapIR<Loop>(IR))
1475 const auto *M = unwrapIR<Module>(IR);
1477 if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR))
1491 if (auto *MF = unwrapIR<MachineFunction>(IR)) {
1515 void InLineChangePrinter::generateIRRepresentation(Any IR,
1518 IRComparer<EmptyData>::analyzeIR(IR, D);
1524 Any IR) {
1526 formatv("*** IR Dump After {0} on {1} ***\n", PassID, Name);
1529 .compare(getModuleForComparison(IR),
1545 Out << "\n*** IR for function " << Name << " ***\n";
1575 [this](StringRef P, Any IR) { this->runBeforePass(P, IR); });
1577 [this](StringRef P, Any IR, const PreservedAnalyses &) {
1585 [this](StringRef P, Any IR) { this->runBeforePass(P, IR); });
1587 [this](StringRef P, Any IR) { this->runAfterPass(); }, true);
1590 void TimeProfilingPassesHandler::runBeforePass(StringRef PassID, Any IR) {
1591 timeTraceProfilerBegin(PassID, getIRName(IR));
1981 // Handle each basic block in the before IR.
1998 // Handle each basic block in the after IR
2004 // This only exists in the after IR. Create the node.
2287 void DotCfgChangeReporter::handleInitialIR(Any IR) {
2290 << "Initial IR (by function)</button>\n"
2293 // Create representation of IR
2295 IRComparer<DCData>::analyzeIR(IR, Data);
2299 .compare(getModuleForComparison(IR),
2303 handleFunctionCompare("", " ", "Initial IR", "", InModule,
2311 void DotCfgChangeReporter::generateIRRepresentation(Any IR, StringRef PassID,
2313 IRComparer<DCData>::analyzeIR(IR, Data);
2327 const IRDataT<DCData> &After, Any IR) {
2330 .compare(getModuleForComparison(IR),
2502 [&PIC, this](StringRef PassID, Any IR) {
2505 OS << formatv("*** Dump of {0}IR Before Last Pass {1}",
2507 if (!isInteresting(IR, PassID, PIC.getPassNameForClassName(PassID))) {
2512 unwrapAndPrint(OS, IR);