Newer
Older
report("LiveVariables: Block should not be in AliveBlocks", MFI);
Jakob Stoklund Olesen
committed
*OS << "Virtual register " << PrintReg(Reg)
<< " is not needed live through the block.\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 (!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;
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';
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);
Jakob Stoklund Olesen
committed
*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';
}
Cameron Zwarich
committed
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.isEarlyClobber()) {
report("Early clobber def must be at an early-clobber slot", MF);
Cameron Zwarich
committed
*OS << "Valno #" << VNI->id << " is defined at " << VNI->def
<< " in " << LI << '\n';
}
} else if (!VNI->def.isRegister()) {
report("Non-PHI, non-early clobber def must be at a register slot",
MF);
Cameron Zwarich
committed
*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);
*OS << " has a valno not in " << LI << '\n';
}
if (VNI->isUnused()) {
report("Live range valno is marked unused", MF);
*OS << " in " << LI << '\n';
}
Jakob Stoklund Olesen
committed
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
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)) {
Cameron Zwarich
committed
// 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()) {
Cameron Zwarich
committed
hasDeadDef = true;
break;
}
}
if (!hasDeadDef) {
report("Instruction killing live segment neither defines nor reads "
"register", MI);
I->print(*OS);
*OS << " in " << LI << '\n';
}
Jakob Stoklund Olesen
committed
}
}
// Now check all the basic blocks in this live segment.
MachineFunction::const_iterator MFI = MBB;
Cameron Zwarich
committed
// Is this live range the beginning of a non-PHIDef VN?
if (I->start == VNI->def && !VNI->isPHIDef()) {
Jakob Stoklund Olesen
committed
// 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;
}
Jakob Stoklund Olesen
committed
// 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);
const VNInfo *PVNI = LI.getVNInfoBefore(PEnd);
Cameron Zwarich
committed
if (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI))
Cameron Zwarich
committed
continue;
Cameron Zwarich
committed
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 before "
Cameron Zwarich
committed
<< PEnd << " in " << LI << '\n';
continue;
}
Cameron Zwarich
committed
if (PVNI != VNI) {
Jakob Stoklund Olesen
committed
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;
}
Jakob Stoklund Olesen
committed
// Check the LI only has one connected component.
Jakob Stoklund Olesen
committed
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';
Jakob Stoklund Olesen
committed
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';
}
Jakob Stoklund Olesen
committed
}
Jakob Stoklund Olesen
committed
}