return;
// Live-in registers are in use.
- for (MachineBasicBlock::const_livein_iterator I = MBB->livein_begin(),
+ for (MachineBasicBlock::livein_iterator I = MBB->livein_begin(),
E = MBB->livein_end(); I != E; ++I)
setUsed(*I);
CalleeSavedRegs.set(CSRegs[i]);
}
- // RS used within emit{Pro,Epi}logue()
- if (mbb != MBB) {
- MBB = mbb;
- initRegState();
- }
+ MBB = mbb;
+ initRegState();
Tracking = false;
}
Tracking = true;
} else {
assert(MBBI != MBB->end() && "Already at the end of the basic block!");
- MBBI = next(MBBI);
+ MBBI = llvm::next(MBBI);
}
MachineInstr *MI = MBBI;
ScavengeRestore = NULL;
}
+ if (MI->isDebugValue())
+ return;
+
// Find out which registers are early clobbered, killed, defined, and marked
// def-dead in this instruction.
BitVector EarlyClobberRegs(NumPhysRegs);
if (!Reg || isReserved(Reg))
continue;
if (MO.isUse()) {
- assert(isUsed(Reg) && "Using an undefined register!");
+ if (!isUsed(Reg)) {
+ // Check if it's partial live: e.g.
+ // D0 = insert_subreg D0<undef>, S0
+ // ... D0
+ // The problem is the insert_subreg could be eliminated. The use of
+ // D0 is using a partially undef value. This is not *incorrect* since
+ // S1 is can be freely clobbered.
+ // Ideally we would like a way to model this, but leaving the
+ // insert_subreg around causes both correctness and performance issues.
+ bool SubUsed = false;
+ for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
+ unsigned SubReg = *SubRegs; ++SubRegs)
+ if (isUsed(SubReg)) {
+ SubUsed = true;
+ break;
+ }
+ assert(SubUsed && "Using an undefined register!");
+ }
assert((!EarlyClobberRegs.test(Reg) || MI->isRegTiedToDefOperand(i)) &&
"Using an early clobbered register!");
} else {