From ee21e9f8237f3ecf31546cbf895e1c795ba4c4df Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Mon, 9 Nov 2015 23:59:33 +0000 Subject: [PATCH] MachineVerifier: Streamline live interval related error reporting Simply perform additional report_context() calls after a report() instead of adding more and more overloaded variations of report(). Also improve several instances where information was output in an ad-hoc way probably because no matching report() overload was available. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252552 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineVerifier.cpp | 183 ++++++++++++++++++++-------------------- 1 file changed, 93 insertions(+), 90 deletions(-) diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index c8c958846b8..e1020772629 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -211,14 +211,12 @@ namespace { void report(const char *msg, const MachineBasicBlock *MBB); void report(const char *msg, const MachineInstr *MI); void report(const char *msg, const MachineOperand *MO, unsigned MONum); - void report(const char *msg, const MachineFunction *MF, - const LiveInterval &LI); - void report(const char *msg, const MachineBasicBlock *MBB, - const LiveInterval &LI); - void report(const char *msg, const MachineFunction *MF, - const LiveRange &LR, unsigned Reg, LaneBitmask LaneMask); - void report(const char *msg, const MachineBasicBlock *MBB, - const LiveRange &LR, unsigned Reg, LaneBitmask LaneMask); + + void report_context(const LiveInterval &LI) const; + void report_context(const LiveRange &LR, unsigned Reg, + LaneBitmask LaneMask) const; + void report_context(const LiveRange::Segment &S) const; + void report_context(const VNInfo &VNI) const; void verifyInlineAsm(const MachineInstr *MI); @@ -437,36 +435,24 @@ void MachineVerifier::report(const char *msg, errs() << "\n"; } -void MachineVerifier::report(const char *msg, const MachineFunction *MF, - const LiveInterval &LI) { - report(msg, MF); - errs() << "- interval: " << LI << '\n'; -} - -void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB, - const LiveInterval &LI) { - report(msg, MBB); +void MachineVerifier::report_context(const LiveInterval &LI) const { errs() << "- interval: " << LI << '\n'; } -void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB, - const LiveRange &LR, unsigned Reg, - LaneBitmask LaneMask) { - report(msg, MBB); - errs() << "- liverange: " << LR << '\n'; +void MachineVerifier::report_context(const LiveRange &LR, unsigned Reg, + LaneBitmask LaneMask) const { errs() << "- register: " << PrintReg(Reg, TRI) << '\n'; if (LaneMask != 0) errs() << "- lanemask: " << PrintLaneMask(LaneMask) << '\n'; + errs() << "- liverange: " << LR << '\n'; } -void MachineVerifier::report(const char *msg, const MachineFunction *MF, - const LiveRange &LR, unsigned Reg, - LaneBitmask LaneMask) { - report(msg, MF); - errs() << "- liverange: " << LR << '\n'; - errs() << "- register: " << PrintReg(Reg, TRI) << '\n'; - if (LaneMask != 0) - errs() << "- lanemask: " << PrintLaneMask(LaneMask) << '\n'; +void MachineVerifier::report_context(const LiveRange::Segment &S) const { + errs() << "- segment: " << S << '\n'; +} + +void MachineVerifier::report_context(const VNInfo &VNI) const { + errs() << "- ValNo: " << VNI.id << " (def " << VNI.def << ")\n"; } void MachineVerifier::markReachable(const MachineBasicBlock *MBB) { @@ -1446,33 +1432,32 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR, const VNInfo *DefVNI = LR.getVNInfoAt(VNI->def); if (!DefVNI) { - report("Valno not live at def and not marked unused", MF, LR, Reg, - LaneMask); - errs() << "Valno #" << VNI->id << '\n'; + report("Value not live at VNInfo def and not marked unused", MF); + report_context(LR, Reg, LaneMask); + report_context(*VNI); return; } if (DefVNI != VNI) { - report("Live segment at def has different valno", MF, LR, Reg, LaneMask); - errs() << "Valno #" << VNI->id << " is defined at " << VNI->def - << " where valno #" << DefVNI->id << " is live\n"; + report("Live segment at def has different VNInfo", MF); + report_context(LR, Reg, LaneMask); + report_context(*VNI); return; } const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(VNI->def); if (!MBB) { - report("Invalid definition index", MF, LR, Reg, LaneMask); - errs() << "Valno #" << VNI->id << " is defined at " << VNI->def - << " in " << LR << '\n'; + report("Invalid VNInfo definition index", MF); + report_context(LR, Reg, LaneMask); + report_context(*VNI); return; } if (VNI->isPHIDef()) { if (VNI->def != LiveInts->getMBBStartIdx(MBB)) { - report("PHIDef value is not defined at MBB start", MBB, LR, Reg, - LaneMask); - errs() << "Valno #" << VNI->id << " is defined at " << VNI->def - << ", not at the beginning of BB#" << MBB->getNumber() << '\n'; + report("PHIDef VNInfo is not defined at MBB start", MBB); + report_context(LR, Reg, LaneMask); + report_context(*VNI); } return; } @@ -1480,8 +1465,9 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR, // Non-PHI def. const MachineInstr *MI = LiveInts->getInstructionFromIndex(VNI->def); if (!MI) { - report("No instruction at def index", MBB, LR, Reg, LaneMask); - errs() << "Valno #" << VNI->id << " is defined at " << VNI->def << '\n'; + report("No instruction at VNInfo def index", MBB); + report_context(LR, Reg, LaneMask); + report_context(*VNI); return; } @@ -1509,21 +1495,22 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR, if (!hasDef) { report("Defining instruction does not modify register", MI); - errs() << "Valno #" << VNI->id << " in " << LR << '\n'; + report_context(LR, Reg, LaneMask); + report_context(*VNI); } // Early clobber defs begin at USE slots, but other defs must begin at // DEF slots. if (isEarlyClobber) { if (!VNI->def.isEarlyClobber()) { - report("Early clobber def must be at an early-clobber slot", MBB, LR, - Reg, LaneMask); - errs() << "Valno #" << VNI->id << " is defined at " << VNI->def << '\n'; + report("Early clobber def must be at an early-clobber slot", MBB); + report_context(LR, Reg, LaneMask); + report_context(*VNI); } } else if (!VNI->def.isRegister()) { - report("Non-PHI, non-early clobber def must be at a register slot", - MBB, LR, Reg, LaneMask); - errs() << "Valno #" << VNI->id << " is defined at " << VNI->def << '\n'; + report("Non-PHI, non-early clobber def must be at a register slot", MBB); + report_context(LR, Reg, LaneMask); + report_context(*VNI); } } } @@ -1537,33 +1524,38 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, assert(VNI && "Live segment has no valno"); if (VNI->id >= LR.getNumValNums() || VNI != LR.getValNumInfo(VNI->id)) { - report("Foreign valno in live segment", MF, LR, Reg, LaneMask); - errs() << S << " has a bad valno\n"; + report("Foreign valno in live segment", MF); + report_context(LR, Reg, LaneMask); + report_context(S); + report_context(*VNI); } if (VNI->isUnused()) { - report("Live segment valno is marked unused", MF, LR, Reg, LaneMask); - errs() << S << '\n'; + report("Live segment valno is marked unused", MF); + report_context(LR, Reg, LaneMask); + report_context(S); } const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(S.start); if (!MBB) { - report("Bad start of live segment, no basic block", MF, LR, Reg, LaneMask); - errs() << S << '\n'; + report("Bad start of live segment, no basic block", MF); + report_context(LR, Reg, LaneMask); + report_context(S); return; } SlotIndex MBBStartIdx = LiveInts->getMBBStartIdx(MBB); if (S.start != MBBStartIdx && S.start != VNI->def) { - report("Live segment must begin at MBB entry or valno def", MBB, LR, Reg, - LaneMask); - errs() << S << '\n'; + report("Live segment must begin at MBB entry or valno def", MBB); + report_context(LR, Reg, LaneMask); + report_context(S); } const MachineBasicBlock *EndMBB = LiveInts->getMBBFromIndex(S.end.getPrevSlot()); if (!EndMBB) { - report("Bad end of live segment, no basic block", MF, LR, Reg, LaneMask); - errs() << S << '\n'; + report("Bad end of live segment, no basic block", MF); + report_context(LR, Reg, LaneMask); + report_context(S); return; } @@ -1580,26 +1572,26 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, const MachineInstr *MI = LiveInts->getInstructionFromIndex(S.end.getPrevSlot()); if (!MI) { - report("Live segment doesn't end at a valid instruction", EndMBB, LR, Reg, - LaneMask); - errs() << S << '\n'; + report("Live segment doesn't end at a valid instruction", EndMBB); + report_context(LR, Reg, LaneMask); + report_context(S); return; } // The block slot must refer to a basic block boundary. if (S.end.isBlock()) { - report("Live segment ends at B slot of an instruction", EndMBB, LR, Reg, - LaneMask); - errs() << S << '\n'; + report("Live segment ends at B slot of an instruction", EndMBB); + report_context(LR, Reg, LaneMask); + report_context(S); } if (S.end.isDead()) { // Segment ends on the dead slot. // That means there must be a dead def. if (!SlotIndex::isSameInstr(S.start, S.end)) { - report("Live segment ending at dead slot spans instructions", EndMBB, LR, - Reg, LaneMask); - errs() << S << '\n'; + report("Live segment ending at dead slot spans instructions", EndMBB); + report_context(LR, Reg, LaneMask); + report_context(S); } } @@ -1608,9 +1600,9 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, if (S.end.isEarlyClobber()) { if (I+1 == LR.end() || (I+1)->start != S.end) { report("Live segment ending at early clobber slot must be " - "redefined by an EC def in the same instruction", EndMBB, LR, Reg, - LaneMask); - errs() << S << '\n'; + "redefined by an EC def in the same instruction", EndMBB); + report_context(LR, Reg, LaneMask); + report_context(S); } } @@ -1640,7 +1632,8 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, !hasSubRegDef) { report("Instruction ending live segment doesn't read the register", MI); - errs() << S << " in " << LR << '\n'; + report_context(LR, Reg, LaneMask); + report_context(S); } } } @@ -1679,9 +1672,10 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, // All predecessors must have a live-out value. if (!PVNI) { - report("Register not marked live out of predecessor", *PI, LR, Reg, - LaneMask); - errs() << "Valno #" << VNI->id << " live into BB#" << MFI->getNumber() + report("Register not marked live out of predecessor", *PI); + report_context(LR, Reg, LaneMask); + report_context(*VNI); + errs() << " live into BB#" << MFI->getNumber() << '@' << LiveInts->getMBBStartIdx(&*MFI) << ", not live before " << PEnd << '\n'; continue; @@ -1689,8 +1683,8 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, // Only PHI-defs can take different predecessor values. if (!IsPHI && PVNI != VNI) { - report("Different value live out of predecessor", *PI, LR, Reg, - LaneMask); + report("Different value live out of predecessor", *PI); + report_context(LR, Reg, LaneMask); errs() << "Valno #" << PVNI->id << " live out of BB#" << (*PI)->getNumber() << '@' << PEnd << "\nValno #" << VNI->id << " live into BB#" << MFI->getNumber() << '@' @@ -1720,23 +1714,32 @@ void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) { LaneBitmask Mask = 0; LaneBitmask MaxMask = MRI->getMaxLaneMaskForVReg(Reg); for (const LiveInterval::SubRange &SR : LI.subranges()) { - if ((Mask & SR.LaneMask) != 0) - report("Lane masks of sub ranges overlap in live interval", MF, LI); - if ((SR.LaneMask & ~MaxMask) != 0) - report("Subrange lanemask is invalid", MF, LI); - if (SR.empty()) - report("Subrange must not be empty", MF, SR, LI.reg, SR.LaneMask); + if ((Mask & SR.LaneMask) != 0) { + report("Lane masks of sub ranges overlap in live interval", MF); + report_context(LI); + } + if ((SR.LaneMask & ~MaxMask) != 0) { + report("Subrange lanemask is invalid", MF); + report_context(LI); + } + if (SR.empty()) { + report("Subrange must not be empty", MF); + report_context(SR, LI.reg, SR.LaneMask); + } Mask |= SR.LaneMask; verifyLiveRange(SR, LI.reg, SR.LaneMask); - if (!LI.covers(SR)) - report("A Subrange is not covered by the main range", MF, LI); + if (!LI.covers(SR)) { + report("A Subrange is not covered by the main range", MF); + report_context(LI); + } } // Check the LI only has one connected component. ConnectedVNInfoEqClasses ConEQ(*LiveInts); unsigned NumComp = ConEQ.Classify(&LI); if (NumComp > 1) { - report("Multiple connected components in live interval", MF, LI); + report("Multiple connected components in live interval", MF); + report_context(LI); for (unsigned comp = 0; comp != NumComp; ++comp) { errs() << comp << ": valnos"; for (LiveInterval::const_vni_iterator I = LI.vni_begin(), -- 2.11.0