mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-13 17:38:39 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29830 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ad6f758f89
commit
be4f88a8b8
@ -79,6 +79,11 @@ namespace llvm {
|
|||||||
Ranges ranges; // the ranges in which this register is live
|
Ranges ranges; // the ranges in which this register is live
|
||||||
private:
|
private:
|
||||||
unsigned NumValues; // the number of distinct values in this interval.
|
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<unsigned, 4> InstDefiningValue;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LiveInterval(unsigned Reg, float Weight)
|
LiveInterval(unsigned Reg, float Weight)
|
||||||
@ -109,16 +114,32 @@ namespace llvm {
|
|||||||
void swap(LiveInterval& other) {
|
void swap(LiveInterval& other) {
|
||||||
std::swap(reg, other.reg);
|
std::swap(reg, other.reg);
|
||||||
std::swap(weight, other.weight);
|
std::swap(weight, other.weight);
|
||||||
ranges.swap(other.ranges);
|
std::swap(ranges, other.ranges);
|
||||||
std::swap(NumValues, other.NumValues);
|
std::swap(NumValues, other.NumValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool containsOneValue() const { return NumValues == 1; }
|
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++;
|
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(); }
|
bool empty() const { return ranges.empty(); }
|
||||||
|
|
||||||
/// beginNumber - Return the lowest numbered slot covered by interval.
|
/// beginNumber - Return the lowest numbered slot covered by interval.
|
||||||
|
@ -388,7 +388,7 @@ void LiveInterval::join(LiveInterval &Other, unsigned CopyIdx) {
|
|||||||
I->ValId = MergedDstValIdx;
|
I->ValId = MergedDstValIdx;
|
||||||
else {
|
else {
|
||||||
unsigned &NV = Dst2SrcIdxMap[I->ValId];
|
unsigned &NV = Dst2SrcIdxMap[I->ValId];
|
||||||
if (NV == 0) NV = getNextValue();
|
if (NV == 0) NV = getNextValue(Other.getInstForValNum(I->ValId));
|
||||||
I->ValId = NV;
|
I->ValId = NV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,6 +422,20 @@ void LiveInterval::print(std::ostream &OS, const MRegisterInfo *MRI) const {
|
|||||||
E = ranges.end(); I != E; ++I)
|
E = ranges.end(); I != E; ++I)
|
||||||
OS << *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 {
|
void LiveInterval::dump() const {
|
||||||
|
@ -328,7 +328,7 @@ addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) {
|
|||||||
// the spill weight is now infinity as it
|
// the spill weight is now infinity as it
|
||||||
// cannot be spilled again
|
// cannot be spilled again
|
||||||
nI.weight = float(HUGE_VAL);
|
nI.weight = float(HUGE_VAL);
|
||||||
LiveRange LR(start, end, nI.getNextValue());
|
LiveRange LR(start, end, nI.getNextValue(~0U));
|
||||||
DEBUG(std::cerr << " +" << LR);
|
DEBUG(std::cerr << " +" << LR);
|
||||||
nI.addRange(LR);
|
nI.addRange(LR);
|
||||||
added.push_back(&nI);
|
added.push_back(&nI);
|
||||||
@ -351,18 +351,16 @@ addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) {
|
|||||||
return added;
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LiveIntervals::printRegName(unsigned reg) const
|
void LiveIntervals::printRegName(unsigned reg) const {
|
||||||
{
|
|
||||||
if (MRegisterInfo::isPhysicalRegister(reg))
|
if (MRegisterInfo::isPhysicalRegister(reg))
|
||||||
std::cerr << mri_->getName(reg);
|
std::cerr << mri_->getName(reg);
|
||||||
else
|
else
|
||||||
std::cerr << "%reg" << reg;
|
std::cerr << "%reg" << reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
|
void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||||
MachineBasicBlock::iterator mi,
|
MachineBasicBlock::iterator mi,
|
||||||
LiveInterval& interval)
|
LiveInterval &interval) {
|
||||||
{
|
|
||||||
DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg));
|
DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg));
|
||||||
LiveVariables::VarInfo& vi = lv_->getVarInfo(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.
|
// Get the Idx of the defining instructions.
|
||||||
unsigned defIndex = getDefIndex(getInstructionIndex(mi));
|
unsigned defIndex = getDefIndex(getInstructionIndex(mi));
|
||||||
|
|
||||||
unsigned ValNum = interval.getNextValue();
|
unsigned ValNum = interval.getNextValue(defIndex);
|
||||||
assert(ValNum == 0 && "First value in interval is not 0?");
|
assert(ValNum == 0 && "First value in interval is not 0?");
|
||||||
ValNum = 0; // Clue in the optimizer.
|
ValNum = 0; // Clue in the optimizer.
|
||||||
|
|
||||||
@ -456,10 +454,22 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
|
|||||||
unsigned RedefIndex = getDefIndex(getInstructionIndex(mi));
|
unsigned RedefIndex = getDefIndex(getInstructionIndex(mi));
|
||||||
|
|
||||||
// Delete the initial value, which should be short and continuous,
|
// 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);
|
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);
|
DEBUG(std::cerr << " replace range with " << LR);
|
||||||
interval.addRange(LR);
|
interval.addRange(LR);
|
||||||
|
|
||||||
@ -487,8 +497,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
|
|||||||
interval.removeRange(Start, End);
|
interval.removeRange(Start, End);
|
||||||
DEBUG(std::cerr << "RESULT: " << interval);
|
DEBUG(std::cerr << "RESULT: " << interval);
|
||||||
|
|
||||||
// Replace the interval with one of a NEW value number.
|
// Replace the interval with one of a NEW value number. Note that this
|
||||||
LiveRange LR(Start, End, interval.getNextValue());
|
// 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);
|
DEBUG(std::cerr << " replace range with " << LR);
|
||||||
interval.addRange(LR);
|
interval.addRange(LR);
|
||||||
DEBUG(std::cerr << "RESULT: " << interval);
|
DEBUG(std::cerr << "RESULT: " << interval);
|
||||||
@ -500,7 +511,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
|
|||||||
unsigned defIndex = getDefIndex(getInstructionIndex(mi));
|
unsigned defIndex = getDefIndex(getInstructionIndex(mi));
|
||||||
LiveRange LR(defIndex,
|
LiveRange LR(defIndex,
|
||||||
getInstructionIndex(&mbb->back()) + InstrSlots::NUM,
|
getInstructionIndex(&mbb->back()) + InstrSlots::NUM,
|
||||||
interval.getNextValue());
|
interval.getNextValue(defIndex));
|
||||||
interval.addRange(LR);
|
interval.addRange(LR);
|
||||||
DEBUG(std::cerr << " +" << LR);
|
DEBUG(std::cerr << " +" << LR);
|
||||||
}
|
}
|
||||||
@ -513,8 +524,7 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
|
|||||||
MachineBasicBlock::iterator mi,
|
MachineBasicBlock::iterator mi,
|
||||||
LiveInterval& interval,
|
LiveInterval& interval,
|
||||||
unsigned SrcReg, unsigned DestReg,
|
unsigned SrcReg, unsigned DestReg,
|
||||||
bool isLiveIn)
|
bool isLiveIn) {
|
||||||
{
|
|
||||||
// A physical register cannot be live across basic block, so its
|
// A physical register cannot be live across basic block, so its
|
||||||
// lifetime must end somewhere in its defining basic block.
|
// lifetime must end somewhere in its defining basic block.
|
||||||
DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg));
|
DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg));
|
||||||
@ -591,8 +601,7 @@ exit:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LiveRange LR(start, end, interval.getNextValue(start));
|
||||||
LiveRange LR(start, end, interval.getNextValue());
|
|
||||||
interval.addRange(LR);
|
interval.addRange(LR);
|
||||||
DEBUG(std::cerr << " +" << LR << '\n');
|
DEBUG(std::cerr << " +" << LR << '\n');
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user