From 410c49afd311c33fb19467accdafeafeda734b4f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 22 Aug 2006 18:19:46 +0000 Subject: [PATCH] Improve the LiveInterval class to keep track of which machine instruction defines each value# tracked by the interval. This will be used to improve coallescing. llvm-svn: 29830 --- include/llvm/CodeGen/LiveInterval.h | 25 +++++++++++++++-- lib/CodeGen/LiveInterval.cpp | 16 ++++++++++- lib/CodeGen/LiveIntervalAnalysis.cpp | 41 +++++++++++++++++----------- 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 183cd9abc9f..30a397b22fb 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -79,6 +79,11 @@ namespace llvm { Ranges ranges; // the ranges in which this register is live private: unsigned NumValues; // the number of distinct values in this interval. + + /// InstDefiningValue - This tracks the def index of the instruction that + /// defines a particular value number in the interval. This may be ~0, + /// which is treated as unknown. + SmallVector InstDefiningValue; public: LiveInterval(unsigned Reg, float Weight) @@ -109,15 +114,31 @@ namespace llvm { void swap(LiveInterval& other) { std::swap(reg, other.reg); std::swap(weight, other.weight); - ranges.swap(other.ranges); + std::swap(ranges, other.ranges); std::swap(NumValues, other.NumValues); } bool containsOneValue() const { return NumValues == 1; } - unsigned getNextValue() { + /// getNextValue - Create a new value number and return it. MIIdx specifies + /// the instruction that defines the value number. + unsigned getNextValue(unsigned MIIdx) { + InstDefiningValue.push_back(MIIdx); return NumValues++; } + + /// getInstForValNum - Return the machine instruction index that defines the + /// specified value number. + unsigned getInstForValNum(unsigned ValNo) const { + return InstDefiningValue[ValNo]; + } + + /// setInstDefiningValNum - Change the instruction defining the specified + /// value number to the specified instruction. + void setInstDefiningValNum(unsigned ValNo, unsigned MIIdx) { + InstDefiningValue[ValNo] = MIIdx; + } + bool empty() const { return ranges.empty(); } diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index b0f09297b3e..0a2483e481b 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -388,7 +388,7 @@ void LiveInterval::join(LiveInterval &Other, unsigned CopyIdx) { I->ValId = MergedDstValIdx; else { unsigned &NV = Dst2SrcIdxMap[I->ValId]; - if (NV == 0) NV = getNextValue(); + if (NV == 0) NV = getNextValue(Other.getInstForValNum(I->ValId)); I->ValId = NV; } @@ -422,6 +422,20 @@ void LiveInterval::print(std::ostream &OS, const MRegisterInfo *MRI) const { E = ranges.end(); I != E; ++I) OS << *I; } + + // Print value number info. + if (NumValues) { + OS << " "; + for (unsigned i = 0; i != NumValues; ++i) { + if (i) OS << " "; + OS << i << "@"; + if (InstDefiningValue[i] == ~0U) { + OS << "?"; + } else { + OS << InstDefiningValue[i]; + } + } + } } void LiveInterval::dump() const { diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index e5128558e34..e9bdaa11c81 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -328,7 +328,7 @@ addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) { // the spill weight is now infinity as it // cannot be spilled again nI.weight = float(HUGE_VAL); - LiveRange LR(start, end, nI.getNextValue()); + LiveRange LR(start, end, nI.getNextValue(~0U)); DEBUG(std::cerr << " +" << LR); nI.addRange(LR); added.push_back(&nI); @@ -351,18 +351,16 @@ addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) { return added; } -void LiveIntervals::printRegName(unsigned reg) const -{ +void LiveIntervals::printRegName(unsigned reg) const { if (MRegisterInfo::isPhysicalRegister(reg)) std::cerr << mri_->getName(reg); else std::cerr << "%reg" << reg; } -void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb, +void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, MachineBasicBlock::iterator mi, - LiveInterval& interval) -{ + LiveInterval &interval) { DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg)); LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg); @@ -374,7 +372,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb, // Get the Idx of the defining instructions. unsigned defIndex = getDefIndex(getInstructionIndex(mi)); - unsigned ValNum = interval.getNextValue(); + unsigned ValNum = interval.getNextValue(defIndex); assert(ValNum == 0 && "First value in interval is not 0?"); ValNum = 0; // Clue in the optimizer. @@ -456,10 +454,22 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb, unsigned RedefIndex = getDefIndex(getInstructionIndex(mi)); // Delete the initial value, which should be short and continuous, - // becuase the 2-addr copy must be in the same MBB as the redef. + // because the 2-addr copy must be in the same MBB as the redef. interval.removeRange(DefIndex, RedefIndex); - LiveRange LR(DefIndex, RedefIndex, interval.getNextValue()); + // Two-address vregs should always only be redefined once. This means + // that at this point, there should be exactly one value number in it. + assert(interval.containsOneValue() && "Unexpected 2-addr liveint!"); + + // The new value number is defined by the instruction we claimed defined + // value #0. + unsigned ValNo = interval.getNextValue(DefIndex); + + // Value#1 is now defined by the 2-addr instruction. + interval.setInstDefiningValNum(0, RedefIndex); + + // Add the new live interval which replaces the range for the input copy. + LiveRange LR(DefIndex, RedefIndex, ValNo); DEBUG(std::cerr << " replace range with " << LR); interval.addRange(LR); @@ -487,8 +497,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb, interval.removeRange(Start, End); DEBUG(std::cerr << "RESULT: " << interval); - // Replace the interval with one of a NEW value number. - LiveRange LR(Start, End, interval.getNextValue()); + // 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)); DEBUG(std::cerr << " replace range with " << LR); interval.addRange(LR); DEBUG(std::cerr << "RESULT: " << interval); @@ -500,7 +511,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb, unsigned defIndex = getDefIndex(getInstructionIndex(mi)); LiveRange LR(defIndex, getInstructionIndex(&mbb->back()) + InstrSlots::NUM, - interval.getNextValue()); + interval.getNextValue(defIndex)); interval.addRange(LR); DEBUG(std::cerr << " +" << LR); } @@ -513,8 +524,7 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB, MachineBasicBlock::iterator mi, LiveInterval& interval, unsigned SrcReg, unsigned DestReg, - bool isLiveIn) -{ + bool isLiveIn) { // A physical register cannot be live across basic block, so its // lifetime must end somewhere in its defining basic block. DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg)); @@ -591,8 +601,7 @@ exit: } } - - LiveRange LR(start, end, interval.getNextValue()); + LiveRange LR(start, end, interval.getNextValue(start)); interval.addRange(LR); DEBUG(std::cerr << " +" << LR << '\n'); }