From 88d1f587d2205b4275dc4c0319a5f2d4d1e6fd42 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 1 Mar 2007 02:03:03 +0000 Subject: [PATCH] Track all joined registers and eliminate unneeded kills after all joining are done. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34767 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/LiveIntervalAnalysis.h | 13 ++++- lib/CodeGen/LiveIntervalAnalysis.cpp | 64 ++++++++++++++------- 2 files changed, 52 insertions(+), 25 deletions(-) diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 4f3af88787b..ebd63c80962 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -57,6 +57,10 @@ namespace llvm { BitVector allocatableRegs_; + /// JoinedLIs - Keep track which register intervals have been coalesced + /// with other intervals. + BitVector JoinedLIs; + public: struct CopyRec { MachineInstr *MI; @@ -119,8 +123,7 @@ namespace llvm { } bool hasInterval(unsigned reg) const { - Reg2IntervalMap::const_iterator I = r2iMap_.find(reg); - return I != r2iMap_.end(); + return r2iMap_.count(reg); } /// getMBBStartIdx - Return the base index of the first instruction in the @@ -264,10 +267,14 @@ namespace llvm { MachineInstr *lastRegisterUse(unsigned Reg, unsigned Start, unsigned End, MachineOperand *&MOU); - /// unsetRegisterKill - Unset IsKill property of all uses of specific + /// unsetRegisterKill - Unset IsKill property of all uses of the specific /// register of the specific instruction. void unsetRegisterKill(MachineInstr *MI, unsigned Reg); + /// hasRegisterDef - True if the instruction defines the specific register. + /// + bool hasRegisterDef(MachineInstr *MI, unsigned Reg); + static LiveInterval createInterval(unsigned Reg); void removeInterval(unsigned Reg) { diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 5aeb4601629..6e516f560e5 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -65,6 +65,7 @@ void LiveIntervals::releaseMemory() { i2miMap_.clear(); r2iMap_.clear(); r2rMap_.clear(); + JoinedLIs.clear(); } @@ -987,27 +988,11 @@ bool LiveIntervals::JoinCopy(MachineInstr *CopyMI, DOUT << "\n\t\tJoined. Result = "; DestInt.print(DOUT, mri_); DOUT << "\n"; - // Live range has been lengthened due to colaescing, eliminate the - // unnecessary kills at the end of the source live ranges. - LiveVariables::VarInfo& svi = lv_->getVarInfo(repSrcReg); - for (unsigned i = 0, e = svi.Kills.size(); i != e; ++i) { - MachineInstr *Kill = svi.Kills[i]; - if (Kill == CopyMI || isRemoved(Kill)) - continue; - if (DestInt.liveAt(getInstructionIndex(Kill) + InstrSlots::NUM)) - unsetRegisterKill(Kill, repSrcReg); - } - if (MRegisterInfo::isVirtualRegister(repDstReg)) { - // If both are virtual registers... - LiveVariables::VarInfo& dvi = lv_->getVarInfo(repDstReg); - for (unsigned i = 0, e = dvi.Kills.size(); i != e; ++i) { - MachineInstr *Kill = dvi.Kills[i]; - if (Kill == CopyMI || isRemoved(Kill)) - continue; - if (DestInt.liveAt(getInstructionIndex(Kill) + InstrSlots::NUM)) - unsetRegisterKill(Kill, repDstReg); - } - } +#if 1 + // Remember these liveintervals have been joined. + JoinedLIs.set(repSrcReg - MRegisterInfo::FirstVirtualRegister); + if (MRegisterInfo::isVirtualRegister(repDstReg)) + JoinedLIs.set(repDstReg - MRegisterInfo::FirstVirtualRegister); // If the intervals were swapped by Join, swap them back so that the register // mapping (in the r2i map) is correct. @@ -1427,8 +1412,10 @@ void LiveIntervals::CopyCoallesceInMBB(MachineBasicBlock *MBB, void LiveIntervals::joinIntervals() { DOUT << "********** JOINING INTERVALS ***********\n"; + JoinedLIs.resize(getNumIntervals()); + JoinedLIs.reset(); + std::vector TryAgainList; - const LoopInfo &LI = getAnalysis(); if (LI.begin() == LI.end()) { // If there are no loops in the function, join intervals in function order. @@ -1467,6 +1454,27 @@ void LiveIntervals::joinIntervals() { } } } + + // Some live range has been lengthened due to colaescing, eliminate the + // unnecessary kills. + int RegNum = JoinedLIs.find_first(); + while (RegNum != -1) { + unsigned Reg = RegNum + MRegisterInfo::FirstVirtualRegister; + unsigned repReg = rep(Reg); + LiveInterval &LI = getInterval(repReg); + LiveVariables::VarInfo& svi = lv_->getVarInfo(Reg); + for (unsigned i = 0, e = svi.Kills.size(); i != e; ++i) { + MachineInstr *Kill = svi.Kills[i]; + // Suppose vr1 = op vr2, x + // and vr1 and vr2 are coalesced. vr2 should still be marked kill + // unless it is a two-address operand. + if (isRemoved(Kill) || hasRegisterDef(Kill, repReg)) + continue; + if (LI.liveAt(getInstructionIndex(Kill) + InstrSlots::NUM)) + unsetRegisterKill(Kill, repReg); + } + RegNum = JoinedLIs.find_next(RegNum); + } DOUT << "*** Register mapping ***\n"; for (int i = 0, e = r2rMap_.size(); i != e; ++i) @@ -1541,6 +1549,18 @@ void LiveIntervals::unsetRegisterKill(MachineInstr *MI, unsigned Reg) { } } +/// hasRegisterDef - True if the instruction defines the specific register. +/// +bool LiveIntervals::hasRegisterDef(MachineInstr *MI, unsigned Reg) { + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (MO.isReg() && MO.isDef() && + mri_->regsOverlap(rep(MO.getReg()), Reg)) + return true; + } + return false; +} + LiveInterval LiveIntervals::createInterval(unsigned reg) { float Weight = MRegisterInfo::isPhysicalRegister(reg) ? HUGE_VALF : 0.0F;