/// Look for every register defined by potential LOHs candidates. /// Map these registers with dense id in @p RegToId and vice-versa in /// @p IdToReg. @p IdToReg is populated only in DEBUG mode. static void collectInvolvedReg(const MachineFunction &MF, MapRegToId &RegToId, MapIdToReg &IdToReg, const TargetRegisterInfo *TRI) { unsigned CurRegId = 0; if (!PreCollectRegister) { unsigned NbReg = TRI->getNumRegs(); for (; CurRegId < NbReg; ++CurRegId) { RegToId[CurRegId] = CurRegId; DEBUG(IdToReg.push_back(CurRegId)); DEBUG(assert(IdToReg[CurRegId] == CurRegId && "Reg index mismatches")); } return; } DEBUG(dbgs() << "** Collect Involved Register\n"); for (const auto &MBB : MF) { for (const MachineInstr &MI : MBB) { if (!canDefBePartOfLOH(&MI) && !isCandidateLoad(&MI) && !isCandidateStore(&MI)) continue; // Process defs for (MachineInstr::const_mop_iterator IO = MI.operands_begin(), IOEnd = MI.operands_end(); IO != IOEnd; ++IO) { if (!IO->isReg() || !IO->isDef()) continue; unsigned CurReg = IO->getReg(); for (MCRegAliasIterator AI(CurReg, TRI, true); AI.isValid(); ++AI) if (RegToId.find(*AI) == RegToId.end()) { DEBUG(IdToReg.push_back(*AI); assert(IdToReg[CurRegId] == *AI && "Reg index mismatches insertion index.")); RegToId[*AI] = CurRegId++; DEBUG(dbgs() << "Register: " << PrintReg(*AI, TRI) << '\n'); } } } }
void MachineVerifier::verifyLiveIntervals() { assert(LiveInts && "Don't call verifyLiveIntervals without LiveInts"); 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 VNInfo *DefVNI = LI.getVNInfoAt(VNI->def); if (!DefVNI) { if (!VNI->isUnused()) { report("Valno not live at def and not marked unused", MF); *OS << "Valno #" << VNI->id << " in " << LI << '\n'; } continue; } if (VNI->isUnused()) continue; if (DefVNI != VNI) { report("Live range at def has different valno", MF); *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. 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'; } bool isEarlyClobber = false; if (MI) { for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(), MOE = MI->operands_end(); MOI != MOE; ++MOI) { if (MOI->isReg() && MOI->getReg() == LI.reg && MOI->isDef() && MOI->isEarlyClobber()) { isEarlyClobber = true; break; } } } // Early clobber defs begin at USE slots, but other defs must begin at // DEF slots. if (isEarlyClobber) { if (!VNI->def.isUse()) { report("Early clobber def must be at a USE slot", MF); *OS << "Valno #" << VNI->id << " is defined at " << VNI->def << " in " << LI << '\n'; } } else if (!VNI->def.isDef()) { report("Non-PHI, non-early clobber def must be at a DEF slot", MF); *OS << "Valno #" << VNI->id << " is defined at " << VNI->def << " in " << LI << '\n'; } } } for (LiveInterval::const_iterator I = LI.begin(), E = LI.end(); I!=E; ++I) { const VNInfo *VNI = I->valno; assert(VNI && "Live range has no valno"); if (VNI->id >= LI.getNumValNums() || VNI != LI.getValNumInfo(VNI->id)) { report("Foreign valno in live range", MF); I->print(*OS); *OS << " has a valno not in " << LI << '\n'; } if (VNI->isUnused()) { report("Live range valno is marked unused", MF); 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)) { // A live range can end with either a redefinition, a kill flag on a // use, or a dead flag on a def. // FIXME: Should we check for each of these? bool hasDeadDef = false; for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(), MOE = MI->operands_end(); MOI != MOE; ++MOI) { if (MOI->isReg() && MOI->getReg() == LI.reg && MOI->isDef() && MOI->isDead()) { hasDeadDef = true; break; } } if (!hasDeadDef) { report("Instruction killing live segment neither defines nor reads " "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 this live range the beginning of a non-PHIDef VN? if (I->start == VNI->def && !VNI->isPHIDef()) { // 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 (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI)) continue; 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'; continue; } 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'; } } } } }