X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FCodeGen%2FMachineVerifier.cpp;h=c21b875a082c917917163a35a2e6ebfc4b92dd34;hb=3f45c27d19f4315437d493ed3c9429b57e2cc59c;hp=ca35ec5fdcf8238e243122b1351777f0b55c4cec;hpb=97c5de758a9c3d4ad14fa97abc0b81a2204aeb1f;p=oota-llvm.git diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index ca35ec5fdcf..c21b875a082 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -42,7 +42,6 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" -#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" @@ -204,6 +203,9 @@ namespace { void visitMachineBasicBlockAfter(const MachineBasicBlock *MBB); void visitMachineFunctionAfter(); + template void report(const char *msg, ilist_iterator I) { + report(msg, &*I); + } void report(const char *msg, const MachineFunction *MF); void report(const char *msg, const MachineBasicBlock *MBB); void report(const char *msg, const MachineInstr *MI); @@ -213,9 +215,9 @@ namespace { void report(const char *msg, const MachineBasicBlock *MBB, const LiveInterval &LI); void report(const char *msg, const MachineFunction *MF, - const LiveRange &LR, unsigned Reg, unsigned LaneMask); + const LiveRange &LR, unsigned Reg, LaneBitmask LaneMask); void report(const char *msg, const MachineBasicBlock *MBB, - const LiveRange &LR, unsigned Reg, unsigned LaneMask); + const LiveRange &LR, unsigned Reg, LaneBitmask LaneMask); void verifyInlineAsm(const MachineInstr *MI); @@ -233,9 +235,11 @@ namespace { void verifyLiveRangeSegment(const LiveRange&, const LiveRange::const_iterator I, unsigned, unsigned); - void verifyLiveRange(const LiveRange&, unsigned, unsigned LaneMask = 0); + void verifyLiveRange(const LiveRange&, unsigned, LaneBitmask LaneMask = 0); void verifyStackFrame(); + + void verifySlotIndexes() const; }; struct MachineVerifierPass : public MachineFunctionPass { @@ -273,6 +277,19 @@ void MachineFunction::verify(Pass *p, const char *Banner) const { .runOnMachineFunction(const_cast(*this)); } +void MachineVerifier::verifySlotIndexes() const { + if (Indexes == nullptr) + return; + + // Ensure the IdxMBB list is sorted by slot indexes. + SlotIndex Last; + for (SlotIndexes::MBBIndexIterator I = Indexes->MBBIndexBegin(), + E = Indexes->MBBIndexEnd(); I != E; ++I) { + assert(!Last.isValid() || I->first > Last); + Last = I->first; + } +} + bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) { foundErrors = 0; @@ -295,10 +312,12 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) { Indexes = PASS->getAnalysisIfAvailable(); } + verifySlotIndexes(); + visitMachineFunctionBefore(); for (MachineFunction::const_iterator MFI = MF.begin(), MFE = MF.end(); MFI!=MFE; ++MFI) { - visitMachineBasicBlockBefore(MFI); + visitMachineBasicBlockBefore(&*MFI); // Keep track of the current bundle header. const MachineInstr *CurBundle = nullptr; // Do we expect the next instruction to be part of the same bundle? @@ -306,7 +325,7 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) { for (MachineBasicBlock::const_instr_iterator MBBI = MFI->instr_begin(), MBBE = MFI->instr_end(); MBBI != MBBE; ++MBBI) { - if (MBBI->getParent() != MFI) { + if (MBBI->getParent() != &*MFI) { report("Bad instruction parent pointer", MFI); errs() << "Instruction: " << *MBBI; continue; @@ -315,20 +334,22 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) { // Check for consistent bundle flags. if (InBundle && !MBBI->isBundledWithPred()) report("Missing BundledPred flag, " - "BundledSucc was set on predecessor", MBBI); + "BundledSucc was set on predecessor", + &*MBBI); if (!InBundle && MBBI->isBundledWithPred()) report("BundledPred flag is set, " - "but BundledSucc not set on predecessor", MBBI); + "but BundledSucc not set on predecessor", + &*MBBI); // Is this a bundle header? if (!MBBI->isInsideBundle()) { if (CurBundle) visitMachineBundleAfter(CurBundle); - CurBundle = MBBI; + CurBundle = &*MBBI; visitMachineBundleBefore(CurBundle); } else if (!CurBundle) report("No bundle header", MBBI); - visitMachineInstrBefore(MBBI); + visitMachineInstrBefore(&*MBBI); for (unsigned I = 0, E = MBBI->getNumOperands(); I != E; ++I) { const MachineInstr &MI = *MBBI; const MachineOperand &Op = MI.getOperand(I); @@ -341,7 +362,7 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) { visitMachineOperand(&Op, I); } - visitMachineInstrAfter(MBBI); + visitMachineInstrAfter(&*MBBI); // Was this the last bundled instruction? InBundle = MBBI->isBundledWithSucc(); @@ -350,7 +371,7 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) { visitMachineBundleAfter(CurBundle); if (InBundle) report("BundledSucc flag set on last instruction in block", &MFI->back()); - visitMachineBasicBlockAfter(MFI); + visitMachineBasicBlockAfter(&*MFI); } visitMachineFunctionAfter(); @@ -425,22 +446,22 @@ void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB, void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB, const LiveRange &LR, unsigned Reg, - unsigned LaneMask) { + LaneBitmask LaneMask) { report(msg, MBB); errs() << "- liverange: " << LR << '\n'; errs() << "- register: " << PrintReg(Reg, TRI) << '\n'; if (LaneMask != 0) - errs() << "- lanemask: " << format("%04X\n", LaneMask); + errs() << "- lanemask: " << PrintLaneMask(LaneMask) << '\n'; } void MachineVerifier::report(const char *msg, const MachineFunction *MF, const LiveRange &LR, unsigned Reg, - unsigned LaneMask) { + LaneBitmask LaneMask) { report(msg, MF); errs() << "- liverange: " << LR << '\n'; errs() << "- register: " << PrintReg(Reg, TRI) << '\n'; if (LaneMask != 0) - errs() << "- lanemask: " << format("%04X\n", LaneMask); + errs() << "- lanemask: " << PrintLaneMask(LaneMask) << '\n'; } void MachineVerifier::markReachable(const MachineBasicBlock *MBB) { @@ -507,11 +528,8 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { if (MRI->isSSA()) { // If this block has allocatable physical registers live-in, check that // it is an entry block or landing pad. - for (MachineBasicBlock::livein_iterator LI = MBB->livein_begin(), - LE = MBB->livein_end(); - LI != LE; ++LI) { - unsigned reg = *LI; - if (isAllocatable(reg) && !MBB->isLandingPad() && + for (const auto &LI : MBB->liveins()) { + if (isAllocatable(LI.PhysReg) && !MBB->isEHPad() && MBB != MBB->getParent()->begin()) { report("MBB has allocable live-in, but isn't entry or landing-pad.", MBB); } @@ -522,7 +540,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { SmallPtrSet LandingPadSuccs; for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(), E = MBB->succ_end(); I != E; ++I) { - if ((*I)->isLandingPad()) + if ((*I)->isEHPad()) LandingPadSuccs.insert(*I); if (!FunctionBlocks.count(*I)) report("MBB has successor that isn't part of the function.", MBB); @@ -562,7 +580,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { // check whether its answers match up with reality. if (!TBB && !FBB) { // Block falls through to its successor. - MachineFunction::const_iterator MBBI = MBB; + MachineFunction::const_iterator MBBI = MBB->getIterator(); ++MBBI; if (MBBI == MF->end()) { // It's possible that the block legitimately ends with a noreturn @@ -575,7 +593,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { } else if (MBB->succ_size() != 1+LandingPadSuccs.size()) { report("MBB exits via unconditional fall-through but doesn't have " "exactly one CFG successor!", MBB); - } else if (!MBB->isSuccessor(MBBI)) { + } else if (!MBB->isSuccessor(&*MBBI)) { report("MBB exits via unconditional fall-through but its successor " "differs from its CFG successor!", MBB); } @@ -613,7 +631,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { } } else if (TBB && !FBB && !Cond.empty()) { // Block conditionally branches somewhere, otherwise falls through. - MachineFunction::const_iterator MBBI = MBB; + MachineFunction::const_iterator MBBI = MBB->getIterator(); ++MBBI; if (MBBI == MF->end()) { report("MBB conditionally falls through out of function!", MBB); @@ -628,7 +646,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { } else if (MBB->succ_size() != 2) { report("MBB exits via conditional branch/fall-through but doesn't have " "exactly two CFG successors!", MBB); - } else if (!matchPair(MBB->succ_begin(), TBB, MBBI)) { + } else if (!matchPair(MBB->succ_begin(), TBB, &*MBBI)) { report("MBB exits via conditional branch/fall-through but the CFG " "successors don't match the actual successors!", MBB); } @@ -680,13 +698,12 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { } regsLive.clear(); - for (MachineBasicBlock::livein_iterator I = MBB->livein_begin(), - E = MBB->livein_end(); I != E; ++I) { - if (!TargetRegisterInfo::isPhysicalRegister(*I)) { + for (const auto &LI : MBB->liveins()) { + if (!TargetRegisterInfo::isPhysicalRegister(LI.PhysReg)) { report("MBB live-in list contains non-physical register", MBB); continue; } - for (MCSubRegIterator SubRegs(*I, TRI, /*IncludeSelf=*/true); + for (MCSubRegIterator SubRegs(LI.PhysReg, TRI, /*IncludeSelf=*/true); SubRegs.isValid(); ++SubRegs) regsLive.insert(*SubRegs); } @@ -822,9 +839,12 @@ void MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { const MachineInstr *MI = MO->getParent(); const MCInstrDesc &MCID = MI->getDesc(); + unsigned NumDefs = MCID.getNumDefs(); + if (MCID.getOpcode() == TargetOpcode::PATCHPOINT) + NumDefs = (MONum == 0 && MO->isReg()) ? NumDefs : 0; // The first MCID.NumDefs operands must be explicit register defines - if (MONum < MCID.getNumDefs()) { + if (MONum < NumDefs) { const MCOperandInfo &MCOI = MCID.OpInfo[MONum]; if (!MO->isReg()) report("Explicit definition must be a register", MO, MONum); @@ -1387,7 +1407,7 @@ void MachineVerifier::verifyLiveIntervals() { void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR, const VNInfo *VNI, unsigned Reg, - unsigned LaneMask) { + LaneBitmask LaneMask) { if (VNI->isUnused()) return; @@ -1478,7 +1498,8 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR, void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, const LiveRange::const_iterator I, - unsigned Reg, unsigned LaneMask) { + unsigned Reg, LaneBitmask LaneMask) +{ const LiveRange::Segment &S = *I; const VNInfo *VNI = S.valno; assert(VNI && "Live segment has no valno"); @@ -1594,7 +1615,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, } // Now check all the basic blocks in this live segment. - MachineFunction::const_iterator MFI = MBB; + MachineFunction::const_iterator MFI = MBB->getIterator(); // Is this live segment the beginning of a non-PHIDef VN? if (S.start == VNI->def && !VNI->isPHIDef()) { // Not live-in to any blocks. @@ -1604,10 +1625,10 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, ++MFI; } for (;;) { - assert(LiveInts->isLiveInToMBB(LR, MFI)); + assert(LiveInts->isLiveInToMBB(LR, &*MFI)); // We don't know how to track physregs into a landing pad. if (!TargetRegisterInfo::isVirtualRegister(Reg) && - MFI->isLandingPad()) { + MFI->isEHPad()) { if (&*MFI == EndMBB) break; ++MFI; @@ -1616,7 +1637,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, // Is VNI a PHI-def in the current block? bool IsPHI = VNI->isPHIDef() && - VNI->def == LiveInts->getMBBStartIdx(MFI); + VNI->def == LiveInts->getMBBStartIdx(&*MFI); // Check that VNI is live-out of all predecessors. for (MachineBasicBlock::const_pred_iterator PI = MFI->pred_begin(), @@ -1629,8 +1650,8 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, report("Register not marked live out of predecessor", *PI, LR, Reg, LaneMask); errs() << "Valno #" << VNI->id << " live into BB#" << MFI->getNumber() - << '@' << LiveInts->getMBBStartIdx(MFI) << ", not live before " - << PEnd << '\n'; + << '@' << LiveInts->getMBBStartIdx(&*MFI) << ", not live before " + << PEnd << '\n'; continue; } @@ -1639,9 +1660,9 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, report("Different value live out of predecessor", *PI, LR, Reg, LaneMask); errs() << "Valno #" << PVNI->id << " live out of BB#" - << (*PI)->getNumber() << '@' << PEnd - << "\nValno #" << VNI->id << " live into BB#" << MFI->getNumber() - << '@' << LiveInts->getMBBStartIdx(MFI) << '\n'; + << (*PI)->getNumber() << '@' << PEnd << "\nValno #" << VNI->id + << " live into BB#" << MFI->getNumber() << '@' + << LiveInts->getMBBStartIdx(&*MFI) << '\n'; } } if (&*MFI == EndMBB) @@ -1651,7 +1672,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, } void MachineVerifier::verifyLiveRange(const LiveRange &LR, unsigned Reg, - unsigned LaneMask) { + LaneBitmask LaneMask) { for (const VNInfo *VNI : LR.valnos) verifyLiveRangeValue(LR, VNI, Reg, LaneMask); @@ -1664,13 +1685,15 @@ void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) { assert(TargetRegisterInfo::isVirtualRegister(Reg)); verifyLiveRange(LI, Reg); - unsigned Mask = 0; - unsigned MaxMask = MRI->getMaxLaneMaskForVReg(Reg); + 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); Mask |= SR.LaneMask; verifyLiveRange(SR, LI.reg, SR.LaneMask); if (!LI.covers(SR))