diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -1141,6 +1141,11 @@ } }; +class MachineFunctionAnalysisManager; +void verifyMachineFunction(MachineFunctionAnalysisManager *, + const std::string &Banner, + const MachineFunction &MF); + } // end namespace llvm #endif // LLVM_CODEGEN_MACHINEFUNCTION_H diff --git a/llvm/include/llvm/CodeGen/MachinePassManager.h b/llvm/include/llvm/CodeGen/MachinePassManager.h --- a/llvm/include/llvm/CodeGen/MachinePassManager.h +++ b/llvm/include/llvm/CodeGen/MachinePassManager.h @@ -134,8 +134,10 @@ public: MachineFunctionPassManager(bool DebugLogging = false, - bool RequireCodeGenSCCOrder = false) - : Base(DebugLogging), RequireCodeGenSCCOrder(RequireCodeGenSCCOrder) {} + bool RequireCodeGenSCCOrder = false, + bool VerifyMachineFunction = false) + : Base(DebugLogging), RequireCodeGenSCCOrder(RequireCodeGenSCCOrder), + VerifyMachineFunction(VerifyMachineFunction) {} MachineFunctionPassManager(MachineFunctionPassManager &&) = default; MachineFunctionPassManager & operator=(MachineFunctionPassManager &&) = default; @@ -245,6 +247,8 @@ // Run codegen in the SCC order. bool RequireCodeGenSCCOrder; + + bool VerifyMachineFunction; }; } // end namespace llvm diff --git a/llvm/lib/CodeGen/MachinePassManager.cpp b/llvm/lib/CodeGen/MachinePassManager.cpp --- a/llvm/lib/CodeGen/MachinePassManager.cpp +++ b/llvm/lib/CodeGen/MachinePassManager.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/MachinePassManager.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/IR/PassManagerImpl.h" @@ -32,6 +33,22 @@ (void)RequireCodeGenSCCOrder; assert(!RequireCodeGenSCCOrder && "not implemented"); + // Add a PIC to verify machine functions. + if (VerifyMachineFunction) { + PassInstrumentation PI = MFAM.getResult(M); + + // No need to pop this callback later since MIR pipeline is flat which means + // current pipeline is the top-level pipeline. Callbacks are not used after + // current pipeline. + PI.pushBeforeNonSkippedPassCallback([&MFAM](StringRef PassID, Any IR) { + assert(any_isa(IR)); + const MachineFunction *MF = any_cast(IR); + assert(MF && "Machine function should be valid for printing"); + std::string Banner = std::string("After ") + std::string(PassID); + verifyMachineFunction(&MFAM, Banner, *MF); + }); + } + if (DebugLogging) { dbgs() << "Starting " << getTypeName() << " pass manager run.\n"; diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -304,6 +304,19 @@ return new MachineVerifierPass(Banner); } +void llvm::verifyMachineFunction(MachineFunctionAnalysisManager *, + const std::string &Banner, + const MachineFunction &MF) { + // TODO: Use MFAM after porting below analyses. + // LiveVariables *LiveVars; + // LiveIntervals *LiveInts; + // LiveStacks *LiveStks; + // SlotIndexes *Indexes; + unsigned FoundErrors = MachineVerifier(nullptr, Banner.c_str()).verify(MF); + if (FoundErrors) + report_fatal_error("Found " + Twine(FoundErrors) + " machine code errors."); +} + bool MachineFunction::verify(Pass *p, const char *Banner, bool AbortOnErrors) const { MachineFunction &MF = const_cast(*this);