diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 1912d642960..d24aec4eb87 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -85,13 +85,22 @@ namespace llvm { float weight; // weight of this interval MachineInstr* remat; // definition if the definition rematerializable Ranges ranges; // the ranges in which this register is live + + /// ValueNumberInfo - If the value number definition is undefined (e.g. phi + /// merge point), it contains ~0,x,x. If the value number is not in use, it + /// contains ~1,x,x to indicate that the value # is not used. The first + /// entry is the instruction # of the definition, the second is the kill #. + /// If the third value is non-zero, then the val# is defined by a copy and + /// it represents the register number it is copied from. + struct VNInfo { + unsigned def; + unsigned kill; + unsigned reg; + VNInfo() : def(~1U), kill(~0U), reg(0) {}; + VNInfo(unsigned d, unsigned k, unsigned r) : def(d), kill(k), reg(r) {}; + }; private: - /// ValueNumberInfo - If this value number is not defined by a copy, this - /// holds ~0,x. If the value number is not in use, it contains ~1,x to - /// indicate that the value # is not used. If the val# is defined by a - /// copy, the first entry is the instruction # of the copy, and the second - /// is the register number copied from. - SmallVector, 4> ValueNumberInfo; + SmallVector ValueNumberInfo; public: LiveInterval(unsigned Reg, float Weight) @@ -134,7 +143,7 @@ namespace llvm { /// getNextValue - Create a new value number and return it. MIIdx specifies /// the instruction that defines the value number. unsigned getNextValue(unsigned MIIdx, unsigned SrcReg) { - ValueNumberInfo.push_back(std::make_pair(MIIdx, SrcReg)); + ValueNumberInfo.push_back(VNInfo(MIIdx, ~0U, SrcReg)); return ValueNumberInfo.size()-1; } @@ -142,25 +151,29 @@ namespace llvm { /// specified value number. unsigned getInstForValNum(unsigned ValNo) const { //assert(ValNo < ValueNumberInfo.size()); - return ValueNumberInfo[ValNo].first; + return ValueNumberInfo[ValNo].def; + } + + /// getKillForValNum - Return the machine instruction index that kills the + /// specified value number. + unsigned getKillForValNum(unsigned ValNo) const { + //assert(ValNo < ValueNumberInfo.size()); + return ValueNumberInfo[ValNo].kill; } unsigned getSrcRegForValNum(unsigned ValNo) const { //assert(ValNo < ValueNumberInfo.size()); - if (ValueNumberInfo[ValNo].first < ~2U) - return ValueNumberInfo[ValNo].second; - return 0; + return ValueNumberInfo[ValNo].reg; } - std::pair getValNumInfo(unsigned ValNo) const { + VNInfo getValNumInfo(unsigned ValNo) const { //assert(ValNo < ValueNumberInfo.size()); return ValueNumberInfo[ValNo]; } /// setValueNumberInfo - Change the value number info for the specified /// value number. - void setValueNumberInfo(unsigned ValNo, - const std::pair &I){ + void setValueNumberInfo(unsigned ValNo, const VNInfo &I) { ValueNumberInfo[ValNo] = I; } @@ -247,7 +260,7 @@ namespace llvm { /// the intervals are not joinable, this aborts. void join(LiveInterval &Other, int *ValNoAssignments, int *RHSValNoAssignments, - SmallVector,16> &NewValueNumberInfo); + SmallVector &NewValueNumberInfo); /// removeRange - Remove the specified range from this interval. Note that /// the range must already be in this interval in its entirety. diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 45c1dd03da5..1aa02f00701 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -281,8 +281,7 @@ LiveInterval::FindLiveRangeContaining(unsigned Idx) { /// the intervals are not joinable, this aborts. void LiveInterval::join(LiveInterval &Other, int *LHSValNoAssignments, int *RHSValNoAssignments, - SmallVector, 16> &NewValueNumberInfo) { + SmallVector &NewValueNumberInfo) { // Try to do the least amount of work possible. In particular, if there are // more liverange chunks in the other set than there are in the 'this' set, @@ -301,7 +300,8 @@ void LiveInterval::join(LiveInterval &Other, int *LHSValNoAssignments, // we want to avoid the interval scan if not. bool MustMapCurValNos = false; for (unsigned i = 0, e = getNumValNums(); i != e; ++i) { - if (ValueNumberInfo[i].first == ~2U) continue; // tombstone value # + assert(ValueNumberInfo[i].def != ~2U); + if (ValueNumberInfo[i].def == ~1U) continue; // tombstone value # if (i != (unsigned)LHSValNoAssignments[i]) { MustMapCurValNos = true; break; @@ -463,9 +463,9 @@ void LiveInterval::MergeValueNumberInto(unsigned V1, unsigned V2) { if (V1 == getNumValNums()-1) { do { ValueNumberInfo.pop_back(); - } while (ValueNumberInfo.back().first == ~1U); + } while (ValueNumberInfo.back().def == ~1U); } else { - ValueNumberInfo[V1].first = ~1U; + ValueNumberInfo[V1].def = ~1U; } } @@ -507,10 +507,15 @@ void LiveInterval::print(std::ostream &OS, const MRegisterInfo *MRI) const { for (unsigned i = 0; i != getNumValNums(); ++i) { if (i) OS << " "; OS << i << "@"; - if (ValueNumberInfo[i].first == ~0U) { + if (ValueNumberInfo[i].def == ~0U) { OS << "?"; } else { - OS << ValueNumberInfo[i].first; + OS << ValueNumberInfo[i].def; + } + if (ValueNumberInfo[i].kill == ~0U) { + OS << ",?"; + } else { + OS << "," << ValueNumberInfo[i].kill; } } } diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 369493ff94e..c17f2ac90b9 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -351,7 +351,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, unsigned ValNum; unsigned SrcReg, DstReg; if (!tii_->isMoveInstr(*mi, SrcReg, DstReg)) - ValNum = interval.getNextValue(~0U, 0); + ValNum = interval.getNextValue(defIndex, 0); else ValNum = interval.getNextValue(defIndex, SrcReg); @@ -450,7 +450,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, interval.setValueNumberInfo(1, interval.getValNumInfo(0)); // Value#0 is now defined by the 2-addr instruction. - interval.setValueNumberInfo(0, std::make_pair(~0U, 0U)); + interval.setValueNumberInfo(0, LiveInterval::VNInfo(DefIndex, ~0U, 0U)); // Add the new live interval which replaces the range for the input copy. LiveRange LR(DefIndex, RedefIndex, ValNo); @@ -484,7 +484,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // Replace the interval with one of a NEW value number. Note that this // value number isn't actually defined by an instruction, weird huh? :) - LiveRange LR(Start, End, interval.getNextValue(~0U, 0)); + LiveRange LR(Start, End, interval.getNextValue(~0, 0)); DOUT << " replace range with " << LR; interval.addRange(LR); DOUT << " RESULT: "; interval.print(DOUT, mri_); @@ -498,7 +498,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, unsigned ValNum; unsigned SrcReg, DstReg; if (!tii_->isMoveInstr(*mi, SrcReg, DstReg)) - ValNum = interval.getNextValue(~0U, 0); + ValNum = interval.getNextValue(defIndex, 0); else ValNum = interval.getNextValue(defIndex, SrcReg); @@ -566,8 +566,7 @@ exit: // Already exists? Extend old live interval. LiveInterval::iterator OldLR = interval.FindLiveRangeContaining(start); unsigned Id = (OldLR != interval.end()) - ? OldLR->ValId - : interval.getNextValue(SrcReg != 0 ? start : ~0U, SrcReg); + ? OldLR->ValId : interval.getNextValue(start, SrcReg); LiveRange LR(start, end, Id); interval.addRange(LR); DOUT << " +" << LR << '\n'; @@ -634,7 +633,7 @@ exit: } } - LiveRange LR(start, end, interval.getNextValue(~0U, 0)); + LiveRange LR(start, end, interval.getNextValue(start, 0)); DOUT << " +" << LR << '\n'; interval.addRange(LR); } diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index a3f8ccac20c..a37a00545f6 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -91,7 +91,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInte // an unknown definition point or it is defined at CopyIdx. If unknown, we // can't process it. unsigned BValNoDefIdx = IntB.getInstForValNum(BValNo); - if (BValNoDefIdx == ~0U) return false; + if (!IntB.getSrcRegForValNum(BValNo)) return false; assert(BValNoDefIdx == CopyIdx && "Copy doesn't define the value?"); @@ -128,14 +128,15 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInte DOUT << "\nExtending: "; IntB.print(DOUT, mri_); + unsigned FillerStart = ValLR->end, FillerEnd = BLR->start; // We are about to delete CopyMI, so need to remove it as the 'instruction - // that defines this value #'. - IntB.setValueNumberInfo(BValNo, std::make_pair(~0U, 0)); + // that defines this value #'. Update the the valnum with the new defining + // instruction #. + IntB.setValueNumberInfo(BValNo, LiveInterval::VNInfo(FillerStart, ~0U, 0)); // Okay, we can merge them. We need to insert a new liverange: // [ValLR.end, BLR.begin) of either value number, then we merge the // two value numbers. - unsigned FillerStart = ValLR->end, FillerEnd = BLR->start; IntB.addRange(LiveRange(FillerStart, FillerEnd, BValNo)); // If the IntB live range is assigned to a physical register, and if that @@ -145,7 +146,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInte for (const unsigned *AS = mri_->getSubRegisters(IntB.reg); *AS; ++AS) { LiveInterval &AliasLI = li_->getInterval(*AS); AliasLI.addRange(LiveRange(FillerStart, FillerEnd, - AliasLI.getNextValue(~0U, 0))); + AliasLI.getNextValue(FillerStart, 0))); } } @@ -398,8 +399,7 @@ bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI, /// contains the value number the copy is from. /// static unsigned ComputeUltimateVN(unsigned VN, - SmallVector, 16> &ValueNumberInfo, + SmallVector &ValueNumberInfo, SmallVector &ThisFromOther, SmallVector &OtherFromThis, SmallVector &ThisValNoAssignments, @@ -574,7 +574,7 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RH // coalesced. SmallVector LHSValNoAssignments; SmallVector RHSValNoAssignments; - SmallVector, 16> ValueNumberInfo; + SmallVector ValueNumberInfo; // If a live interval is a physical register, conservatively check if any // of its sub-registers is overlapping the live interval of the virtual @@ -605,7 +605,7 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RH // Find out if the RHS is defined as a copy from some value in the LHS. int RHSValID = -1; - std::pair RHSValNoInfo; + LiveInterval::VNInfo RHSValNoInfo; unsigned RHSSrcReg = RHS.getSrcRegForValNum(0); if ((RHSSrcReg == 0 || rep(RHSSrcReg) != LHS.reg)) { // If RHS is not defined as a copy from the LHS, we can use simpler and @@ -645,7 +645,7 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RH // Otherwise, use the specified value #. LHSValNoAssignments[VN] = RHSValID; if (VN != (unsigned)RHSValID) - ValueNumberInfo[VN].first = ~1U; + ValueNumberInfo[VN].def = ~1U; else ValueNumberInfo[VN] = RHSValNoInfo; } @@ -702,14 +702,14 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RH ValueNumberInfo.reserve(LHS.getNumValNums() + RHS.getNumValNums()); for (unsigned VN = 0, e = LHS.getNumValNums(); VN != e; ++VN) { - if (LHSValNoAssignments[VN] >= 0 || LHS.getInstForValNum(VN) == ~2U) + if (LHSValNoAssignments[VN] >= 0 || LHS.getInstForValNum(VN) == ~1U) continue; ComputeUltimateVN(VN, ValueNumberInfo, LHSValsDefinedFromRHS, RHSValsDefinedFromLHS, LHSValNoAssignments, RHSValNoAssignments, LHS, RHS); } for (unsigned VN = 0, e = RHS.getNumValNums(); VN != e; ++VN) { - if (RHSValNoAssignments[VN] >= 0 || RHS.getInstForValNum(VN) == ~2U) + if (RHSValNoAssignments[VN] >= 0 || RHS.getInstForValNum(VN) == ~1U) continue; // If this value number isn't a copy from the LHS, it's a new number. if (RHSValsDefinedFromLHS[VN] == -1) {