diff options
Diffstat (limited to 'lib/CodeGen/MachineVerifier.cpp')
-rw-r--r-- | lib/CodeGen/MachineVerifier.cpp | 256 |
1 files changed, 226 insertions, 30 deletions
diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index 1e88562..8ada60a 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -26,6 +26,7 @@ #include "llvm/Function.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/LiveVariables.h" +#include "llvm/CodeGen/LiveStackAnalysis.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineMemOperand.h" @@ -167,7 +168,9 @@ namespace { // Analysis information if available LiveVariables *LiveVars; - const LiveIntervals *LiveInts; + LiveIntervals *LiveInts; + LiveStacks *LiveStks; + SlotIndexes *Indexes; void visitMachineFunctionBefore(); void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB); @@ -195,7 +198,9 @@ namespace { static char ID; // Pass ID, replacement for typeid MachineVerifierPass() - : MachineFunctionPass(ID) {} + : MachineFunctionPass(ID) { + initializeMachineVerifierPassPass(*PassRegistry::getPassRegistry()); + } void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); @@ -212,7 +217,7 @@ namespace { char MachineVerifierPass::ID = 0; INITIALIZE_PASS(MachineVerifierPass, "machineverifier", - "Verify generated machine code", false, false); + "Verify generated machine code", false, false) FunctionPass *llvm::createMachineVerifierPass() { return new MachineVerifierPass(); @@ -247,11 +252,15 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) { LiveVars = NULL; LiveInts = NULL; + LiveStks = NULL; + Indexes = NULL; if (PASS) { LiveInts = PASS->getAnalysisIfAvailable<LiveIntervals>(); // We don't want to verify LiveVariables if LiveIntervals is available. if (!LiveInts) LiveVars = PASS->getAnalysisIfAvailable<LiveVariables>(); + LiveStks = PASS->getAnalysisIfAvailable<LiveStacks>(); + Indexes = PASS->getAnalysisIfAvailable<SlotIndexes>(); } visitMachineFunctionBefore(); @@ -289,7 +298,7 @@ void MachineVerifier::report(const char *msg, const MachineFunction *MF) { assert(MF); *OS << '\n'; if (!foundErrors++) - MF->print(*OS); + MF->print(*OS, Indexes); *OS << "*** Bad machine code: " << msg << " ***\n" << "- function: " << MF->getFunction()->getNameStr() << "\n"; } @@ -299,13 +308,19 @@ void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB) { report(msg, MBB->getParent()); *OS << "- basic block: " << MBB->getName() << " " << (void*)MBB - << " (BB#" << MBB->getNumber() << ")\n"; + << " (BB#" << MBB->getNumber() << ")"; + if (Indexes) + *OS << " [" << Indexes->getMBBStartIdx(MBB) + << ';' << Indexes->getMBBEndIdx(MBB) << ')'; + *OS << '\n'; } void MachineVerifier::report(const char *msg, const MachineInstr *MI) { assert(MI); report(msg, MI->getParent()); *OS << "- instruction: "; + if (Indexes && Indexes->hasIndex(MI)) + *OS << Indexes->getInstructionIndex(MI) << '\t'; MI->print(*OS, TM); } @@ -357,6 +372,14 @@ void MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); + // Count the number of landing pad successors. + unsigned LandingPadSuccs = 0; + for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(), + E = MBB->succ_end(); I != E; ++I) + LandingPadSuccs += (*I)->isLandingPad(); + if (LandingPadSuccs > 1) + report("MBB has more than one landing pad successor", MBB); + // Call AnalyzeBranch. If it succeeds, there several more conditions to check. MachineBasicBlock *TBB = 0, *FBB = 0; SmallVector<MachineOperand, 4> Cond; @@ -372,14 +395,14 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { // It's possible that the block legitimately ends with a noreturn // call or an unreachable, in which case it won't actually fall // out the bottom of the function. - } else if (MBB->succ_empty()) { + } else if (MBB->succ_size() == LandingPadSuccs) { // It's possible that the block legitimately ends with a noreturn // call or an unreachable, in which case it won't actuall fall // out of the block. - } else if (MBB->succ_size() != 1) { + } else if (MBB->succ_size() != 1+LandingPadSuccs) { report("MBB exits via unconditional fall-through but doesn't have " "exactly one CFG successor!", MBB); - } else if (MBB->succ_begin()[0] != MBBI) { + } else if (!MBB->isSuccessor(MBBI)) { report("MBB exits via unconditional fall-through but its successor " "differs from its CFG successor!", MBB); } @@ -394,10 +417,10 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { } } else if (TBB && !FBB && Cond.empty()) { // Block unconditionally branches somewhere. - if (MBB->succ_size() != 1) { + if (MBB->succ_size() != 1+LandingPadSuccs) { report("MBB exits via unconditional branch but doesn't have " "exactly one CFG successor!", MBB); - } else if (MBB->succ_begin()[0] != TBB) { + } else if (!MBB->isSuccessor(TBB)) { report("MBB exits via unconditional branch but the CFG " "successor doesn't match the actual successor!", MBB); } @@ -566,7 +589,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { unsigned DefReg = MI->getOperand(defIdx).getReg(); if (Reg == DefReg) { isKill = true; - // ANd in that case an explicit kill flag is not allowed. + // And in that case an explicit kill flag is not allowed. if (MO->isKill()) report("Illegal kill flag on two-address instruction operand", MO, MONum); @@ -590,7 +613,8 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { } // Check LiveInts liveness and kill. - if (LiveInts && !LiveInts->isNotInMIMap(MI)) { + if (TargetRegisterInfo::isVirtualRegister(Reg) && + LiveInts && !LiveInts->isNotInMIMap(MI)) { SlotIndex UseIdx = LiveInts->getInstructionIndex(MI).getUseIndex(); if (LiveInts->hasInterval(Reg)) { const LiveInterval &LI = LiveInts->getInterval(Reg); @@ -598,8 +622,21 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { report("No live range at use", MO, MONum); *OS << UseIdx << " is not live in " << LI << '\n'; } - // TODO: Verify isKill == LI.killedAt. - } else if (TargetRegisterInfo::isVirtualRegister(Reg)) { + // Verify isKill == LI.killedAt. + if (!MI->isRegTiedToDefOperand(MONum)) { + // MI could kill register without a kill flag on MO. + bool miKill = MI->killsRegister(Reg); + bool liKill = LI.killedAt(UseIdx.getDefIndex()); + if (miKill && !liKill) { + report("Live range continues after kill flag", MO, MONum); + *OS << "Live range: " << LI << '\n'; + } + if (!miKill && liKill) { + report("Live range ends without kill flag", MO, MONum); + *OS << "Live range: " << LI << '\n'; + } + } + } else { report("Virtual register has no Live interval", MO, MONum); } } @@ -636,11 +673,11 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { SlotIndex DefIdx = LiveInts->getInstructionIndex(MI).getDefIndex(); if (LiveInts->hasInterval(Reg)) { const LiveInterval &LI = LiveInts->getInterval(Reg); - if (const LiveRange *LR = LI.getLiveRangeContaining(DefIdx)) { - assert(LR->valno && "NULL valno is not allowed"); - if (LR->valno->def != DefIdx) { + if (const VNInfo *VNI = LI.getVNInfoAt(DefIdx)) { + assert(VNI && "NULL valno is not allowed"); + if (VNI->def != DefIdx) { report("Inconsistent valno->def", MO, MONum); - *OS << "Valno " << LR->valno->id << " is not defined at " + *OS << "Valno " << VNI->id << " is not defined at " << DefIdx << " in " << LI << '\n'; } } else { @@ -706,6 +743,22 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { report("PHI operand is not in the CFG", MO, MONum); break; + case MachineOperand::MO_FrameIndex: + if (LiveStks && LiveStks->hasInterval(MO->getIndex()) && + LiveInts && !LiveInts->isNotInMIMap(MI)) { + LiveInterval &LI = LiveStks->getInterval(MO->getIndex()); + SlotIndex Idx = LiveInts->getInstructionIndex(MI); + if (TI.mayLoad() && !LI.liveAt(Idx.getUseIndex())) { + report("Instruction loads from dead spill slot", MO, MONum); + *OS << "Live stack: " << LI << '\n'; + } + if (TI.mayStore() && !LI.liveAt(Idx.getDefIndex())) { + report("Instruction stores to dead spill slot", MO, MONum); + *OS << "Live stack: " << LI << '\n'; + } + } + break; + default: break; } @@ -884,14 +937,24 @@ void MachineVerifier::verifyLiveIntervals() { for (LiveIntervals::const_iterator LVI = LiveInts->begin(), LVE = LiveInts->end(); LVI != LVE; ++LVI) { const LiveInterval &LI = *LVI->second; + + // Spilling and splitting may leave unused registers around. Skip them. + if (MRI->use_empty(LI.reg)) + continue; + + // Physical registers have much weirdness going on, mostly from coalescing. + // We should probably fix it, but for now just ignore them. + if (TargetRegisterInfo::isPhysicalRegister(LI.reg)) + continue; + assert(LVI->first == LI.reg && "Invalid reg to interval mapping"); for (LiveInterval::const_vni_iterator I = LI.vni_begin(), E = LI.vni_end(); I!=E; ++I) { VNInfo *VNI = *I; - const LiveRange *DefLR = LI.getLiveRangeContaining(VNI->def); + const VNInfo *DefVNI = LI.getVNInfoAt(VNI->def); - if (!DefLR) { + if (!DefVNI) { if (!VNI->isUnused()) { report("Valno not live at def and not marked unused", MF); *OS << "Valno #" << VNI->id << " in " << LI << '\n'; @@ -902,31 +965,164 @@ void MachineVerifier::verifyLiveIntervals() { if (VNI->isUnused()) continue; - if (DefLR->valno != VNI) { + if (DefVNI != VNI) { report("Live range at def has different valno", MF); - DefLR->print(*OS); - *OS << " should use valno #" << VNI->id << " in " << LI << '\n'; + *OS << "Valno #" << VNI->id << " is defined at " << VNI->def + << " where valno #" << DefVNI->id << " is live in " << LI << '\n'; + continue; } + const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(VNI->def); + if (!MBB) { + report("Invalid definition index", MF); + *OS << "Valno #" << VNI->id << " is defined at " << VNI->def + << " in " << LI << '\n'; + continue; + } + + if (VNI->isPHIDef()) { + if (VNI->def != LiveInts->getMBBStartIdx(MBB)) { + report("PHIDef value is not defined at MBB start", MF); + *OS << "Valno #" << VNI->id << " is defined at " << VNI->def + << ", not at the beginning of BB#" << MBB->getNumber() + << " in " << LI << '\n'; + } + } else { + // Non-PHI def. + if (!VNI->def.isDef()) { + report("Non-PHI def must be at a DEF slot", MF); + *OS << "Valno #" << VNI->id << " is defined at " << VNI->def + << " in " << LI << '\n'; + } + const MachineInstr *MI = LiveInts->getInstructionFromIndex(VNI->def); + if (!MI) { + report("No instruction at def index", MF); + *OS << "Valno #" << VNI->id << " is defined at " << VNI->def + << " in " << LI << '\n'; + } else if (!MI->modifiesRegister(LI.reg, TRI)) { + report("Defining instruction does not modify register", MI); + *OS << "Valno #" << VNI->id << " in " << LI << '\n'; + } + } } for (LiveInterval::const_iterator I = LI.begin(), E = LI.end(); I!=E; ++I) { - const LiveRange &LR = *I; - assert(LR.valno && "Live range has no valno"); + const VNInfo *VNI = I->valno; + assert(VNI && "Live range has no valno"); - if (LR.valno->id >= LI.getNumValNums() || - LR.valno != LI.getValNumInfo(LR.valno->id)) { + if (VNI->id >= LI.getNumValNums() || VNI != LI.getValNumInfo(VNI->id)) { report("Foreign valno in live range", MF); - LR.print(*OS); + I->print(*OS); *OS << " has a valno not in " << LI << '\n'; } - if (LR.valno->isUnused()) { + if (VNI->isUnused()) { report("Live range valno is marked unused", MF); - LR.print(*OS); + I->print(*OS); + *OS << " in " << LI << '\n'; + } + + const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(I->start); + if (!MBB) { + report("Bad start of live segment, no basic block", MF); + I->print(*OS); *OS << " in " << LI << '\n'; + continue; + } + SlotIndex MBBStartIdx = LiveInts->getMBBStartIdx(MBB); + if (I->start != MBBStartIdx && I->start != VNI->def) { + report("Live segment must begin at MBB entry or valno def", MBB); + I->print(*OS); + *OS << " in " << LI << '\n' << "Basic block starts at " + << MBBStartIdx << '\n'; } + const MachineBasicBlock *EndMBB = + LiveInts->getMBBFromIndex(I->end.getPrevSlot()); + if (!EndMBB) { + report("Bad end of live segment, no basic block", MF); + I->print(*OS); + *OS << " in " << LI << '\n'; + continue; + } + if (I->end != LiveInts->getMBBEndIdx(EndMBB)) { + // The live segment is ending inside EndMBB + const MachineInstr *MI = + LiveInts->getInstructionFromIndex(I->end.getPrevSlot()); + if (!MI) { + report("Live segment doesn't end at a valid instruction", EndMBB); + I->print(*OS); + *OS << " in " << LI << '\n' << "Basic block starts at " + << MBBStartIdx << '\n'; + } else if (TargetRegisterInfo::isVirtualRegister(LI.reg) && + !MI->readsVirtualRegister(LI.reg)) { + // FIXME: Should we require a kill flag? + report("Instruction killing live segment doesn't read register", MI); + I->print(*OS); + *OS << " in " << LI << '\n'; + } + } + + // Now check all the basic blocks in this live segment. + MachineFunction::const_iterator MFI = MBB; + // Is LI live-in to MBB and not a PHIDef? + if (I->start == VNI->def) { + // Not live-in to any blocks. + if (MBB == EndMBB) + continue; + // Skip this block. + ++MFI; + } + for (;;) { + assert(LiveInts->isLiveInToMBB(LI, MFI)); + // We don't know how to track physregs into a landing pad. + if (TargetRegisterInfo::isPhysicalRegister(LI.reg) && + MFI->isLandingPad()) { + if (&*MFI == EndMBB) + break; + ++MFI; + continue; + } + // Check that VNI is live-out of all predecessors. + for (MachineBasicBlock::const_pred_iterator PI = MFI->pred_begin(), + PE = MFI->pred_end(); PI != PE; ++PI) { + SlotIndex PEnd = LiveInts->getMBBEndIdx(*PI).getPrevSlot(); + const VNInfo *PVNI = LI.getVNInfoAt(PEnd); + if (!PVNI) { + report("Register not marked live out of predecessor", *PI); + *OS << "Valno #" << VNI->id << " live into BB#" << MFI->getNumber() + << '@' << LiveInts->getMBBStartIdx(MFI) << ", not live at " + << PEnd << " in " << LI << '\n'; + } else if (PVNI != VNI) { + report("Different value live out of predecessor", *PI); + *OS << "Valno #" << PVNI->id << " live out of BB#" + << (*PI)->getNumber() << '@' << PEnd + << "\nValno #" << VNI->id << " live into BB#" << MFI->getNumber() + << '@' << LiveInts->getMBBStartIdx(MFI) << " in " << LI << '\n'; + } + } + if (&*MFI == EndMBB) + break; + ++MFI; + } + } + + // Check the LI only has one connected component. + if (TargetRegisterInfo::isVirtualRegister(LI.reg)) { + ConnectedVNInfoEqClasses ConEQ(*LiveInts); + unsigned NumComp = ConEQ.Classify(&LI); + if (NumComp > 1) { + report("Multiple connected components in live interval", MF); + *OS << NumComp << " components in " << LI << '\n'; + for (unsigned comp = 0; comp != NumComp; ++comp) { + *OS << comp << ": valnos"; + for (LiveInterval::const_vni_iterator I = LI.vni_begin(), + E = LI.vni_end(); I!=E; ++I) + if (comp == ConEQ.getEqClass(*I)) + *OS << ' ' << (*I)->id; + *OS << '\n'; + } + } } } } |