diff options
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/Legalizer.cpp')
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/Legalizer.cpp | 72 |
1 files changed, 69 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp index e789e4a333dc..1d7be54de3b0 100644 --- a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp +++ b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp @@ -21,6 +21,7 @@ #include "llvm/CodeGen/GlobalISel/GISelWorkList.h" #include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h" #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" +#include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h" #include "llvm/CodeGen/GlobalISel/Utils.h" #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -28,6 +29,7 @@ #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/InitializePasses.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Error.h" #include "llvm/Target/TargetMachine.h" #include <iterator> @@ -41,6 +43,29 @@ static cl::opt<bool> cl::desc("Should enable CSE in Legalizer"), cl::Optional, cl::init(false)); +enum class DebugLocVerifyLevel { + None, + Legalizations, + LegalizationsAndArtifactCombiners, +}; +#ifndef NDEBUG +static cl::opt<DebugLocVerifyLevel> VerifyDebugLocs( + "verify-legalizer-debug-locs", + cl::desc("Verify that debug locations are handled"), + cl::values( + clEnumValN(DebugLocVerifyLevel::None, "none", "No verification"), + clEnumValN(DebugLocVerifyLevel::Legalizations, "legalizations", + "Verify legalizations"), + clEnumValN(DebugLocVerifyLevel::LegalizationsAndArtifactCombiners, + "legalizations+artifactcombiners", + "Verify legalizations and artifact combines")), + cl::init(DebugLocVerifyLevel::Legalizations)); +#else +// Always disable it for release builds by preventing the observer from being +// installed. +static const DebugLocVerifyLevel VerifyDebugLocs = DebugLocVerifyLevel::None; +#endif + char Legalizer::ID = 0; INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE, "Legalize the Machine IR a function's Machine IR", false, @@ -108,7 +133,6 @@ public: } void createdInstr(MachineInstr &MI) override { - LLVM_DEBUG(dbgs() << ".. .. New MI: " << MI); LLVM_DEBUG(NewMIs.push_back(&MI)); createdOrChangedInstr(MI); } @@ -143,7 +167,9 @@ public: Legalizer::MFResult Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI, ArrayRef<GISelChangeObserver *> AuxObservers, + LostDebugLocObserver &LocObserver, MachineIRBuilder &MIRBuilder) { + MIRBuilder.setMF(MF); MachineRegisterInfo &MRI = MF.getRegInfo(); // Populate worklists. @@ -180,7 +206,7 @@ Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI, // Now install the observer as the delegate to MF. // This will keep all the observers notified about new insertions/deletions. - RAIIDelegateInstaller DelInstall(MF, &WrapperObserver); + RAIIMFObsDelInstaller Installer(MF, WrapperObserver); LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder); LegalizationArtifactCombiner ArtCombiner(MIRBuilder, MRI, LI); auto RemoveDeadInstFromLists = [&WrapperObserver](MachineInstr *DeadMI) { @@ -199,6 +225,7 @@ Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI, if (isTriviallyDead(MI, MRI)) { LLVM_DEBUG(dbgs() << MI << "Is dead; erasing.\n"); MI.eraseFromParentAndMarkDBGValuesForRemoval(); + LocObserver.checkpoint(false); continue; } @@ -224,6 +251,7 @@ Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI, return {Changed, &MI}; } WorkListObserver.printNewInstrs(); + LocObserver.checkpoint(); Changed |= Res == LegalizerHelper::Legalized; } // Try to combine the instructions in RetryList again if there @@ -238,6 +266,7 @@ Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI, return {Changed, RetryList.front()}; } } + LocObserver.checkpoint(); while (!ArtifactList.empty()) { MachineInstr &MI = *ArtifactList.pop_back_val(); assert(isPreISelGenericOpcode(MI.getOpcode()) && @@ -246,6 +275,7 @@ Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI, LLVM_DEBUG(dbgs() << MI << "Is dead\n"); RemoveDeadInstFromLists(&MI); MI.eraseFromParentAndMarkDBGValuesForRemoval(); + LocObserver.checkpoint(false); continue; } SmallVector<MachineInstr *, 4> DeadInstructions; @@ -258,6 +288,9 @@ Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI, RemoveDeadInstFromLists(DeadMI); DeadMI->eraseFromParentAndMarkDBGValuesForRemoval(); } + LocObserver.checkpoint( + VerifyDebugLocs == + DebugLocVerifyLevel::LegalizationsAndArtifactCombiners); Changed = true; continue; } @@ -305,9 +338,14 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) { // We want CSEInfo in addition to WorkListObserver to observe all changes. AuxObservers.push_back(CSEInfo); } + assert(!CSEInfo || !errorToBool(CSEInfo->verify())); + LostDebugLocObserver LocObserver(DEBUG_TYPE); + if (VerifyDebugLocs > DebugLocVerifyLevel::None) + AuxObservers.push_back(&LocObserver); const LegalizerInfo &LI = *MF.getSubtarget().getLegalizerInfo(); - MFResult Result = legalizeMachineFunction(MF, LI, AuxObservers, *MIRBuilder); + MFResult Result = + legalizeMachineFunction(MF, LI, AuxObservers, LocObserver, *MIRBuilder); if (Result.FailedOn) { reportGISelFailure(MF, TPC, MORE, "gisel-legalize", @@ -324,5 +362,33 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) { reportGISelFailure(MF, TPC, MORE, R); return false; } + + if (LocObserver.getNumLostDebugLocs()) { + MachineOptimizationRemarkMissed R("gisel-legalize", "LostDebugLoc", + MF.getFunction().getSubprogram(), + /*MBB=*/&*MF.begin()); + R << "lost " + << ore::NV("NumLostDebugLocs", LocObserver.getNumLostDebugLocs()) + << " debug locations during pass"; + reportGISelWarning(MF, TPC, MORE, R); + // Example remark: + // --- !Missed + // Pass: gisel-legalize + // Name: GISelFailure + // DebugLoc: { File: '.../legalize-urem.mir', Line: 1, Column: 0 } + // Function: test_urem_s32 + // Args: + // - String: 'lost ' + // - NumLostDebugLocs: '1' + // - String: ' debug locations during pass' + // ... + } + + // If for some reason CSE was not enabled, make sure that we invalidate the + // CSEInfo object (as we currently declare that the analysis is preserved). + // The next time get on the wrapper is called, it will force it to recompute + // the analysis. + if (!EnableCSE) + Wrapper.setComputed(false); return Result.Changed; } |