Properly verify liveness with bundled machine instructions.

Bundles should be treated as one atomic transaction when checking
liveness. That is how the register allocator (and VLIW targets) treats
bundles.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158116 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2012-06-06 22:34:30 +00:00
parent 8e5271d462
commit 1f9c3ec831

View File

@ -191,9 +191,11 @@ namespace {
void visitMachineFunctionBefore(); void visitMachineFunctionBefore();
void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB); void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB);
void visitMachineBundleBefore(const MachineInstr *MI);
void visitMachineInstrBefore(const MachineInstr *MI); void visitMachineInstrBefore(const MachineInstr *MI);
void visitMachineOperand(const MachineOperand *MO, unsigned MONum); void visitMachineOperand(const MachineOperand *MO, unsigned MONum);
void visitMachineInstrAfter(const MachineInstr *MI); void visitMachineInstrAfter(const MachineInstr *MI);
void visitMachineBundleAfter(const MachineInstr *MI);
void visitMachineBasicBlockAfter(const MachineBasicBlock *MBB); void visitMachineBasicBlockAfter(const MachineBasicBlock *MBB);
void visitMachineFunctionAfter(); void visitMachineFunctionAfter();
@ -288,6 +290,8 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
for (MachineFunction::const_iterator MFI = MF.begin(), MFE = MF.end(); for (MachineFunction::const_iterator MFI = MF.begin(), MFE = MF.end();
MFI!=MFE; ++MFI) { MFI!=MFE; ++MFI) {
visitMachineBasicBlockBefore(MFI); visitMachineBasicBlockBefore(MFI);
// Keep track of the current bundle header.
const MachineInstr *CurBundle = 0;
for (MachineBasicBlock::const_instr_iterator MBBI = MFI->instr_begin(), for (MachineBasicBlock::const_instr_iterator MBBI = MFI->instr_begin(),
MBBE = MFI->instr_end(); MBBI != MBBE; ++MBBI) { MBBE = MFI->instr_end(); MBBI != MBBE; ++MBBI) {
if (MBBI->getParent() != MFI) { if (MBBI->getParent() != MFI) {
@ -295,15 +299,21 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
*OS << "Instruction: " << *MBBI; *OS << "Instruction: " << *MBBI;
continue; continue;
} }
// Skip BUNDLE instruction for now. FIXME: We should add code to verify // Is this a bundle header?
// the BUNDLE's specifically. if (!MBBI->isInsideBundle()) {
if (MBBI->isBundle()) if (CurBundle)
continue; visitMachineBundleAfter(CurBundle);
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) for (unsigned I = 0, E = MBBI->getNumOperands(); I != E; ++I)
visitMachineOperand(&MBBI->getOperand(I), I); visitMachineOperand(&MBBI->getOperand(I), I);
visitMachineInstrAfter(MBBI); visitMachineInstrAfter(MBBI);
} }
if (CurBundle)
visitMachineBundleAfter(CurBundle);
visitMachineBasicBlockAfter(MFI); visitMachineBasicBlockAfter(MFI);
} }
visitMachineFunctionAfter(); visitMachineFunctionAfter();
@ -575,6 +585,19 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
lastIndex = Indexes->getMBBStartIdx(MBB); lastIndex = Indexes->getMBBStartIdx(MBB);
} }
// This function gets called for all bundle headers, including normal
// stand-alone unbundled instructions.
void MachineVerifier::visitMachineBundleBefore(const MachineInstr *MI) {
if (Indexes && Indexes->hasIndex(MI)) {
SlotIndex idx = Indexes->getInstructionIndex(MI);
if (!(idx > lastIndex)) {
report("Instruction index out of order", MI);
*OS << "Last instruction was at " << lastIndex << '\n';
}
lastIndex = idx;
}
}
void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) { void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
const MCInstrDesc &MCID = MI->getDesc(); const MCInstrDesc &MCID = MI->getDesc();
if (MI->getNumOperands() < MCID.getNumOperands()) { if (MI->getNumOperands() < MCID.getNumOperands()) {
@ -865,6 +888,13 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
} }
void MachineVerifier::visitMachineInstrAfter(const MachineInstr *MI) { void MachineVerifier::visitMachineInstrAfter(const MachineInstr *MI) {
}
// This function gets called after visiting all instructions in a bundle. The
// argument points to the bundle header.
// Normal stand-alone instructions are also considered 'bundles', and this
// function is called for all of them.
void MachineVerifier::visitMachineBundleAfter(const MachineInstr *MI) {
BBInfo &MInfo = MBBInfoMap[MI->getParent()]; BBInfo &MInfo = MBBInfoMap[MI->getParent()];
set_union(MInfo.regsKilled, regsKilled); set_union(MInfo.regsKilled, regsKilled);
set_subtract(regsLive, regsKilled); regsKilled.clear(); set_subtract(regsLive, regsKilled); regsKilled.clear();
@ -878,15 +908,6 @@ void MachineVerifier::visitMachineInstrAfter(const MachineInstr *MI) {
} }
set_subtract(regsLive, regsDead); regsDead.clear(); set_subtract(regsLive, regsDead); regsDead.clear();
set_union(regsLive, regsDefined); regsDefined.clear(); set_union(regsLive, regsDefined); regsDefined.clear();
if (Indexes && Indexes->hasIndex(MI)) {
SlotIndex idx = Indexes->getInstructionIndex(MI);
if (!(idx > lastIndex)) {
report("Instruction index out of order", MI);
*OS << "Last instruction was at " << lastIndex << '\n';
}
lastIndex = idx;
}
} }
void void