/// lastRegisterUse - Returns the last use of the specific register between
/// cycles Start and End. It also returns the use operand by reference. It
/// returns NULL if there are no uses.
- MachineInstr *lastRegisterUse(unsigned Reg, unsigned Start, unsigned End,
+ MachineInstr *lastRegisterUse(unsigned Start, unsigned End, unsigned Reg,
MachineOperand *&MOU);
/// findDefOperand - Returns the MachineOperand that is a def of the specific
/// register of the specific instruction.
void unsetRegisterKill(MachineInstr *MI, unsigned Reg);
+ /// unsetRegisterKills - Unset IsKill property of all uses of specific register
+ /// between cycles Start and End.
+ void unsetRegisterKills(unsigned Start, unsigned End, unsigned Reg);
+
/// hasRegisterDef - True if the instruction defines the specific register.
///
bool hasRegisterDef(MachineInstr *MI, unsigned Reg);
isDead = false;
} else {
MachineOperand *MOU;
- MachineInstr *LastUse= lastRegisterUse(repSrcReg, SrcStart, CopyIdx, MOU);
+ MachineInstr *LastUse= lastRegisterUse(SrcStart, CopyIdx, repSrcReg, MOU);
if (LastUse) {
// Shorten the liveinterval to the end of last use.
MOU->setIsKill();
// we have to update any aliased register's live ranges to indicate that they
// have clobbered values for this range.
if (MRegisterInfo::isPhysicalRegister(repDstReg)) {
+ // Unset unnecessary kills.
+ for (LiveInterval::Ranges::const_iterator I = SrcInt.begin(),
+ E = SrcInt.end(); I != E; ++I)
+ unsetRegisterKills(I->start, I->end, repDstReg);
+
// Update the liveintervals of sub-registers.
for (const unsigned *AS = mri_->getSubRegisters(repDstReg); *AS; ++AS)
getInterval(*AS).MergeInClobberRanges(SrcInt);
/// cycles Start and End. It also returns the use operand by reference. It
/// returns NULL if there are no uses.
MachineInstr *
-LiveIntervals::lastRegisterUse(unsigned Reg, unsigned Start, unsigned End,
+LiveIntervals::lastRegisterUse(unsigned Start, unsigned End, unsigned Reg,
MachineOperand *&MOU) {
int e = (End-1) / InstrSlots::NUM * InstrSlots::NUM;
int s = Start;
}
}
+/// unsetRegisterKills - Unset IsKill property of all uses of specific register
+/// between cycles Start and End.
+void LiveIntervals::unsetRegisterKills(unsigned Start, unsigned End,
+ unsigned Reg) {
+ int e = (End-1) / InstrSlots::NUM * InstrSlots::NUM;
+ int s = Start;
+ while (e >= s) {
+ // Skip deleted instructions
+ MachineInstr *MI = getInstructionFromIndex(e);
+ while ((e - InstrSlots::NUM) >= s && !MI) {
+ e -= InstrSlots::NUM;
+ MI = getInstructionFromIndex(e);
+ }
+ if (e < s || MI == NULL)
+ return;
+
+ for (unsigned i = 0, NumOps = MI->getNumOperands(); i != NumOps; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (MO.isReg() && MO.isUse() && MO.isKill() && MO.getReg() &&
+ mri_->regsOverlap(rep(MO.getReg()), Reg)) {
+ MO.unsetIsKill();
+ }
+ }
+
+ e -= InstrSlots::NUM;
+ }
+}
+
/// hasRegisterDef - True if the instruction defines the specific register.
///
bool LiveIntervals::hasRegisterDef(MachineInstr *MI, unsigned Reg) {