From 2f6cb2b14c5811b154b06163355b3c8bc8b73231 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 14 May 2007 21:10:05 +0000 Subject: [PATCH] Fix for PR1406: v1 = r2 = move v1 = op r2 ... r2 = move v1 = op r2 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 --- include/llvm/CodeGen/LiveIntervalAnalysis.h | 6 +++- lib/CodeGen/LiveIntervalAnalysis.cpp | 37 +++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 26a244fcb0e..10f60f4f05c 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -271,7 +271,7 @@ namespace llvm { /// 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 @@ -282,6 +282,10 @@ namespace llvm { /// 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); diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index c816baffdbf..a996aea4816 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -977,7 +977,7 @@ bool LiveIntervals::JoinCopy(MachineInstr *CopyMI, 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(); @@ -1072,6 +1072,11 @@ bool LiveIntervals::JoinCopy(MachineInstr *CopyMI, // 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); @@ -1632,7 +1637,7 @@ bool LiveIntervals::differingRegisterClasses(unsigned RegA, /// 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; @@ -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. /// bool LiveIntervals::hasRegisterDef(MachineInstr *MI, unsigned Reg) { -- 2.34.1