mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 21:29:41 +00:00
Fix for PR1406:
v1 = r2 = move v1 = op r2<kill> ... r2 = move v1 = op r2<kill> Clear the first r2 kill if v1 and r2 are joined. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37050 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
47927b3e5a
commit
2f6cb2b14c
@ -271,7 +271,7 @@ namespace llvm {
|
|||||||
/// lastRegisterUse - Returns the last use of the specific register between
|
/// lastRegisterUse - Returns the last use of the specific register between
|
||||||
/// cycles Start and End. It also returns the use operand by reference. It
|
/// cycles Start and End. It also returns the use operand by reference. It
|
||||||
/// returns NULL if there are no uses.
|
/// 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);
|
MachineOperand *&MOU);
|
||||||
|
|
||||||
/// findDefOperand - Returns the MachineOperand that is a def of the specific
|
/// findDefOperand - Returns the MachineOperand that is a def of the specific
|
||||||
@ -282,6 +282,10 @@ namespace llvm {
|
|||||||
/// register of the specific instruction.
|
/// register of the specific instruction.
|
||||||
void unsetRegisterKill(MachineInstr *MI, unsigned Reg);
|
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.
|
/// hasRegisterDef - True if the instruction defines the specific register.
|
||||||
///
|
///
|
||||||
bool hasRegisterDef(MachineInstr *MI, unsigned Reg);
|
bool hasRegisterDef(MachineInstr *MI, unsigned Reg);
|
||||||
|
@ -977,7 +977,7 @@ bool LiveIntervals::JoinCopy(MachineInstr *CopyMI,
|
|||||||
isDead = false;
|
isDead = false;
|
||||||
} else {
|
} else {
|
||||||
MachineOperand *MOU;
|
MachineOperand *MOU;
|
||||||
MachineInstr *LastUse= lastRegisterUse(repSrcReg, SrcStart, CopyIdx, MOU);
|
MachineInstr *LastUse= lastRegisterUse(SrcStart, CopyIdx, repSrcReg, MOU);
|
||||||
if (LastUse) {
|
if (LastUse) {
|
||||||
// Shorten the liveinterval to the end of last use.
|
// Shorten the liveinterval to the end of last use.
|
||||||
MOU->setIsKill();
|
MOU->setIsKill();
|
||||||
@ -1072,6 +1072,11 @@ bool LiveIntervals::JoinCopy(MachineInstr *CopyMI,
|
|||||||
// we have to update any aliased register's live ranges to indicate that they
|
// we have to update any aliased register's live ranges to indicate that they
|
||||||
// have clobbered values for this range.
|
// have clobbered values for this range.
|
||||||
if (MRegisterInfo::isPhysicalRegister(repDstReg)) {
|
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.
|
// Update the liveintervals of sub-registers.
|
||||||
for (const unsigned *AS = mri_->getSubRegisters(repDstReg); *AS; ++AS)
|
for (const unsigned *AS = mri_->getSubRegisters(repDstReg); *AS; ++AS)
|
||||||
getInterval(*AS).MergeInClobberRanges(SrcInt);
|
getInterval(*AS).MergeInClobberRanges(SrcInt);
|
||||||
@ -1632,7 +1637,7 @@ bool LiveIntervals::differingRegisterClasses(unsigned RegA,
|
|||||||
/// cycles Start and End. It also returns the use operand by reference. It
|
/// cycles Start and End. It also returns the use operand by reference. It
|
||||||
/// returns NULL if there are no uses.
|
/// returns NULL if there are no uses.
|
||||||
MachineInstr *
|
MachineInstr *
|
||||||
LiveIntervals::lastRegisterUse(unsigned Reg, unsigned Start, unsigned End,
|
LiveIntervals::lastRegisterUse(unsigned Start, unsigned End, unsigned Reg,
|
||||||
MachineOperand *&MOU) {
|
MachineOperand *&MOU) {
|
||||||
int e = (End-1) / InstrSlots::NUM * InstrSlots::NUM;
|
int e = (End-1) / InstrSlots::NUM * InstrSlots::NUM;
|
||||||
int s = Start;
|
int s = Start;
|
||||||
@ -1685,6 +1690,34 @@ void LiveIntervals::unsetRegisterKill(MachineInstr *MI, unsigned Reg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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.
|
/// hasRegisterDef - True if the instruction defines the specific register.
|
||||||
///
|
///
|
||||||
bool LiveIntervals::hasRegisterDef(MachineInstr *MI, unsigned Reg) {
|
bool LiveIntervals::hasRegisterDef(MachineInstr *MI, unsigned Reg) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user