mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
avoid calling the virtual isMoveInstr method endlessly by caching its results.
llvm-svn: 29994
This commit is contained in:
parent
f0e85f8600
commit
998dd9b42e
@ -78,10 +78,12 @@ namespace llvm {
|
|||||||
float weight; // weight of this interval
|
float weight; // weight of this interval
|
||||||
Ranges ranges; // the ranges in which this register is live
|
Ranges ranges; // the ranges in which this register is live
|
||||||
private:
|
private:
|
||||||
/// InstDefiningValue - This tracks the def index of the instruction that
|
/// ValueNumberInfo - If this value number is not defined by a copy, this
|
||||||
/// defines a particular value number in the interval. This may be ~0,
|
/// holds ~0,x. If the value number is not in use, it contains ~1,x to
|
||||||
/// which is treated as unknown, or ~1, which is a deleted value number.
|
/// indicate that the value # is not used. If the val# is defined by a
|
||||||
SmallVector<unsigned, 4> InstDefiningValue;
|
/// copy, the first entry is the instruction # of the copy, and the second
|
||||||
|
/// is the register number copied from.
|
||||||
|
SmallVector<std::pair<unsigned,unsigned>, 4> ValueNumberInfo;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LiveInterval(unsigned Reg, float Weight)
|
LiveInterval(unsigned Reg, float Weight)
|
||||||
@ -113,31 +115,44 @@ namespace llvm {
|
|||||||
std::swap(reg, other.reg);
|
std::swap(reg, other.reg);
|
||||||
std::swap(weight, other.weight);
|
std::swap(weight, other.weight);
|
||||||
std::swap(ranges, other.ranges);
|
std::swap(ranges, other.ranges);
|
||||||
std::swap(InstDefiningValue, other.InstDefiningValue);
|
std::swap(ValueNumberInfo, other.ValueNumberInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool containsOneValue() const { return InstDefiningValue.size() == 1; }
|
bool containsOneValue() const { return ValueNumberInfo.size() == 1; }
|
||||||
|
|
||||||
unsigned getNumValNums() const { return InstDefiningValue.size(); }
|
unsigned getNumValNums() const { return ValueNumberInfo.size(); }
|
||||||
|
|
||||||
/// getNextValue - Create a new value number and return it. MIIdx specifies
|
/// getNextValue - Create a new value number and return it. MIIdx specifies
|
||||||
/// the instruction that defines the value number.
|
/// the instruction that defines the value number.
|
||||||
unsigned getNextValue(unsigned MIIdx) {
|
unsigned getNextValue(unsigned MIIdx, unsigned SrcReg) {
|
||||||
InstDefiningValue.push_back(MIIdx);
|
ValueNumberInfo.push_back(std::make_pair(MIIdx, SrcReg));
|
||||||
return InstDefiningValue.size()-1;
|
return ValueNumberInfo.size()-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getInstForValNum - Return the machine instruction index that defines the
|
/// getInstForValNum - Return the machine instruction index that defines the
|
||||||
/// specified value number.
|
/// specified value number.
|
||||||
unsigned getInstForValNum(unsigned ValNo) const {
|
unsigned getInstForValNum(unsigned ValNo) const {
|
||||||
assert(ValNo < InstDefiningValue.size());
|
assert(ValNo < ValueNumberInfo.size());
|
||||||
return InstDefiningValue[ValNo];
|
return ValueNumberInfo[ValNo].first;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// setInstDefiningValNum - Change the instruction defining the specified
|
unsigned getSrcRegForValNum(unsigned ValNo) const {
|
||||||
/// value number to the specified instruction.
|
assert(ValNo < ValueNumberInfo.size());
|
||||||
void setInstDefiningValNum(unsigned ValNo, unsigned MIIdx) {
|
if (ValueNumberInfo[ValNo].first < ~2U)
|
||||||
InstDefiningValue[ValNo] = MIIdx;
|
return ValueNumberInfo[ValNo].second;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<unsigned, unsigned> 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<unsigned, unsigned> &I){
|
||||||
|
ValueNumberInfo[ValNo] = I;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// MergeValueNumberInto - This method is called when two value nubmers
|
/// MergeValueNumberInto - This method is called when two value nubmers
|
||||||
@ -216,7 +231,7 @@ namespace llvm {
|
|||||||
/// the intervals are not joinable, this aborts.
|
/// the intervals are not joinable, this aborts.
|
||||||
void join(LiveInterval &Other, int *ValNoAssignments,
|
void join(LiveInterval &Other, int *ValNoAssignments,
|
||||||
int *RHSValNoAssignments,
|
int *RHSValNoAssignments,
|
||||||
SmallVector<unsigned, 16> &NewInstDefiningValue);
|
SmallVector<std::pair<unsigned,unsigned>,16> &NewValueNumberInfo);
|
||||||
|
|
||||||
|
|
||||||
/// removeRange - Remove the specified range from this interval. Note that
|
/// removeRange - Remove the specified range from this interval. Note that
|
||||||
|
@ -198,8 +198,8 @@ namespace llvm {
|
|||||||
/// def.
|
/// def.
|
||||||
void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
|
void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
|
||||||
MachineBasicBlock::iterator mi,
|
MachineBasicBlock::iterator mi,
|
||||||
LiveInterval& interval,
|
LiveInterval &interval,
|
||||||
bool isLiveIn = false);
|
unsigned SrcReg);
|
||||||
|
|
||||||
/// Return true if the two specified registers belong to different
|
/// Return true if the two specified registers belong to different
|
||||||
/// register classes. The registers may be either phys or virt regs.
|
/// register classes. The registers may be either phys or virt regs.
|
||||||
|
@ -280,7 +280,8 @@ LiveInterval::FindLiveRangeContaining(unsigned Idx) {
|
|||||||
/// the intervals are not joinable, this aborts.
|
/// the intervals are not joinable, this aborts.
|
||||||
void LiveInterval::join(LiveInterval &Other, int *LHSValNoAssignments,
|
void LiveInterval::join(LiveInterval &Other, int *LHSValNoAssignments,
|
||||||
int *RHSValNoAssignments,
|
int *RHSValNoAssignments,
|
||||||
SmallVector<unsigned, 16> &NewInstDefiningValue) {
|
SmallVector<std::pair<unsigned,
|
||||||
|
unsigned>, 16> &NewValueNumberInfo) {
|
||||||
|
|
||||||
// Try to do the least amount of work possible. In particular, if there are
|
// 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,
|
// more liverange chunks in the other set than there are in the 'this' set,
|
||||||
@ -300,7 +301,7 @@ void LiveInterval::join(LiveInterval &Other, int *LHSValNoAssignments,
|
|||||||
// we want to avoid the interval scan if not.
|
// we want to avoid the interval scan if not.
|
||||||
bool MustMapCurValNos = false;
|
bool MustMapCurValNos = false;
|
||||||
for (unsigned i = 0, e = getNumValNums(); i != e; ++i) {
|
for (unsigned i = 0, e = getNumValNums(); i != e; ++i) {
|
||||||
if (InstDefiningValue[i] == ~2U) continue; // tombstone value #
|
if (ValueNumberInfo[i].first == ~2U) continue; // tombstone value #
|
||||||
if (i != (unsigned)LHSValNoAssignments[i]) {
|
if (i != (unsigned)LHSValNoAssignments[i]) {
|
||||||
MustMapCurValNos = true;
|
MustMapCurValNos = true;
|
||||||
break;
|
break;
|
||||||
@ -345,9 +346,8 @@ void LiveInterval::join(LiveInterval &Other, int *LHSValNoAssignments,
|
|||||||
InsertPos = addRangeFrom(*I, InsertPos);
|
InsertPos = addRangeFrom(*I, InsertPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
InstDefiningValue.clear();
|
ValueNumberInfo.clear();
|
||||||
InstDefiningValue.append(NewInstDefiningValue.begin(),
|
ValueNumberInfo.append(NewValueNumberInfo.begin(), NewValueNumberInfo.end());
|
||||||
NewInstDefiningValue.end());
|
|
||||||
weight += Other.weight;
|
weight += Other.weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,7 +360,7 @@ void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers) {
|
|||||||
// Find a value # to use for the clobber ranges. If there is already a value#
|
// Find a value # to use for the clobber ranges. If there is already a value#
|
||||||
// for unknown values, use it.
|
// for unknown values, use it.
|
||||||
// FIXME: Use a single sentinal number for these!
|
// FIXME: Use a single sentinal number for these!
|
||||||
unsigned ClobberValNo = getNextValue(~0U);
|
unsigned ClobberValNo = getNextValue(~0U, 0);
|
||||||
|
|
||||||
iterator IP = begin();
|
iterator IP = begin();
|
||||||
for (const_iterator I = Clobbers.begin(), E = Clobbers.end(); I != E; ++I) {
|
for (const_iterator I = Clobbers.begin(), E = Clobbers.end(); I != E; ++I) {
|
||||||
@ -399,7 +399,7 @@ void LiveInterval::MergeValueNumberInto(unsigned V1, unsigned V2) {
|
|||||||
|
|
||||||
// Make sure V2 is smaller than V1.
|
// Make sure V2 is smaller than V1.
|
||||||
if (V1 < V2) {
|
if (V1 < V2) {
|
||||||
setInstDefiningValNum(V1, getInstForValNum(V2));
|
setValueNumberInfo(V1, getValNumInfo(V2));
|
||||||
std::swap(V1, V2);
|
std::swap(V1, V2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,10 +443,10 @@ void LiveInterval::MergeValueNumberInto(unsigned V1, unsigned V2) {
|
|||||||
// ~1U so it can be nuked later.
|
// ~1U so it can be nuked later.
|
||||||
if (V1 == getNumValNums()-1) {
|
if (V1 == getNumValNums()-1) {
|
||||||
do {
|
do {
|
||||||
InstDefiningValue.pop_back();
|
ValueNumberInfo.pop_back();
|
||||||
} while (InstDefiningValue.back() == ~1U);
|
} while (ValueNumberInfo.back().first == ~1U);
|
||||||
} else {
|
} else {
|
||||||
InstDefiningValue[V1] = ~1U;
|
ValueNumberInfo[V1].first = ~1U;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,10 +482,10 @@ void LiveInterval::print(std::ostream &OS, const MRegisterInfo *MRI) const {
|
|||||||
for (unsigned i = 0; i != getNumValNums(); ++i) {
|
for (unsigned i = 0; i != getNumValNums(); ++i) {
|
||||||
if (i) OS << " ";
|
if (i) OS << " ";
|
||||||
OS << i << "@";
|
OS << i << "@";
|
||||||
if (InstDefiningValue[i] == ~0U) {
|
if (ValueNumberInfo[i].first == ~0U) {
|
||||||
OS << "?";
|
OS << "?";
|
||||||
} else {
|
} else {
|
||||||
OS << InstDefiningValue[i];
|
OS << ValueNumberInfo[i].first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,10 +138,10 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
for (MachineFunction::livein_iterator I = fn.livein_begin(),
|
for (MachineFunction::livein_iterator I = fn.livein_begin(),
|
||||||
E = fn.livein_end(); I != E; ++I) {
|
E = fn.livein_end(); I != E; ++I) {
|
||||||
handlePhysicalRegisterDef(Entry, Entry->begin(),
|
handlePhysicalRegisterDef(Entry, Entry->begin(),
|
||||||
getOrCreateInterval(I->first), true);
|
getOrCreateInterval(I->first), 0);
|
||||||
for (const unsigned* AS = mri_->getAliasSet(I->first); *AS; ++AS)
|
for (const unsigned* AS = mri_->getAliasSet(I->first); *AS; ++AS)
|
||||||
handlePhysicalRegisterDef(Entry, Entry->begin(),
|
handlePhysicalRegisterDef(Entry, Entry->begin(),
|
||||||
getOrCreateInterval(*AS), true);
|
getOrCreateInterval(*AS), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +321,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(~0U));
|
LiveRange LR(start, end, nI.getNextValue(~0U, 0));
|
||||||
DEBUG(std::cerr << " +" << LR);
|
DEBUG(std::cerr << " +" << LR);
|
||||||
nI.addRange(LR);
|
nI.addRange(LR);
|
||||||
added.push_back(&nI);
|
added.push_back(&nI);
|
||||||
@ -366,7 +366,13 @@ 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(defIndex);
|
unsigned ValNum;
|
||||||
|
unsigned SrcReg, DstReg;
|
||||||
|
if (!tii_->isMoveInstr(*mi, SrcReg, DstReg))
|
||||||
|
ValNum = interval.getNextValue(~0U, 0);
|
||||||
|
else
|
||||||
|
ValNum = interval.getNextValue(defIndex, SrcReg);
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
@ -455,12 +461,13 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
|||||||
// that at this point, there should be exactly one value number in it.
|
// that at this point, there should be exactly one value number in it.
|
||||||
assert(interval.containsOneValue() && "Unexpected 2-addr liveint!");
|
assert(interval.containsOneValue() && "Unexpected 2-addr liveint!");
|
||||||
|
|
||||||
// The new value number is defined by the instruction we claimed defined
|
// The new value number (#1) is defined by the instruction we claimed
|
||||||
// value #0.
|
// defined value #0.
|
||||||
unsigned ValNo = interval.getNextValue(DefIndex);
|
unsigned ValNo = interval.getNextValue(0, 0);
|
||||||
|
interval.setValueNumberInfo(1, interval.getValNumInfo(0));
|
||||||
|
|
||||||
// Value#1 is now defined by the 2-addr instruction.
|
// Value#0 is now defined by the 2-addr instruction.
|
||||||
interval.setInstDefiningValNum(0, RedefIndex);
|
interval.setValueNumberInfo(0, std::make_pair(~0U, 0U));
|
||||||
|
|
||||||
// Add the new live interval which replaces the range for the input copy.
|
// Add the new live interval which replaces the range for the input copy.
|
||||||
LiveRange LR(DefIndex, RedefIndex, ValNo);
|
LiveRange LR(DefIndex, RedefIndex, ValNo);
|
||||||
@ -493,7 +500,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
|||||||
|
|
||||||
// Replace the interval with one of a NEW value number. Note that this
|
// Replace the interval with one of a NEW value number. Note that this
|
||||||
// value number isn't actually defined by an instruction, weird huh? :)
|
// value number isn't actually defined by an instruction, weird huh? :)
|
||||||
LiveRange LR(Start, End, interval.getNextValue(~0U));
|
LiveRange LR(Start, End, interval.getNextValue(~0U, 0));
|
||||||
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.print(std::cerr, mri_));
|
DEBUG(std::cerr << "RESULT: "; interval.print(std::cerr, mri_));
|
||||||
@ -503,9 +510,16 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
|||||||
// live until the end of the block. We've already taken care of the
|
// live until the end of the block. We've already taken care of the
|
||||||
// rest of the live range.
|
// rest of the live range.
|
||||||
unsigned defIndex = getDefIndex(getInstructionIndex(mi));
|
unsigned defIndex = getDefIndex(getInstructionIndex(mi));
|
||||||
|
|
||||||
|
unsigned ValNum;
|
||||||
|
unsigned SrcReg, DstReg;
|
||||||
|
if (!tii_->isMoveInstr(*mi, SrcReg, DstReg))
|
||||||
|
ValNum = interval.getNextValue(~0U, 0);
|
||||||
|
else
|
||||||
|
ValNum = interval.getNextValue(defIndex, SrcReg);
|
||||||
|
|
||||||
LiveRange LR(defIndex,
|
LiveRange LR(defIndex,
|
||||||
getInstructionIndex(&mbb->back()) + InstrSlots::NUM,
|
getInstructionIndex(&mbb->back()) + InstrSlots::NUM, ValNum);
|
||||||
interval.getNextValue(defIndex));
|
|
||||||
interval.addRange(LR);
|
interval.addRange(LR);
|
||||||
DEBUG(std::cerr << " +" << LR);
|
DEBUG(std::cerr << " +" << LR);
|
||||||
}
|
}
|
||||||
@ -516,8 +530,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
|||||||
|
|
||||||
void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
|
void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
|
||||||
MachineBasicBlock::iterator mi,
|
MachineBasicBlock::iterator mi,
|
||||||
LiveInterval& interval,
|
LiveInterval &interval,
|
||||||
bool isLiveIn) {
|
unsigned SrcReg) {
|
||||||
// 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));
|
||||||
@ -551,13 +565,14 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
|
|||||||
// The only case we should have a dead physreg here without a killing or
|
// The only case we should have a dead physreg here without a killing or
|
||||||
// instruction where we know it's dead is if it is live-in to the function
|
// instruction where we know it's dead is if it is live-in to the function
|
||||||
// and never used.
|
// and never used.
|
||||||
assert(isLiveIn && "physreg was not killed in defining block!");
|
assert(!SrcReg && "physreg was not killed in defining block!");
|
||||||
end = getDefIndex(start) + 1; // It's dead.
|
end = getDefIndex(start) + 1; // It's dead.
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
assert(start < end && "did not find end of interval?");
|
assert(start < end && "did not find end of interval?");
|
||||||
|
|
||||||
LiveRange LR(start, end, interval.getNextValue(isLiveIn ? ~0U : start));
|
LiveRange LR(start, end, interval.getNextValue(SrcReg != 0 ? start : ~0U,
|
||||||
|
SrcReg));
|
||||||
interval.addRange(LR);
|
interval.addRange(LR);
|
||||||
DEBUG(std::cerr << " +" << LR << '\n');
|
DEBUG(std::cerr << " +" << LR << '\n');
|
||||||
}
|
}
|
||||||
@ -568,9 +583,12 @@ void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB,
|
|||||||
if (MRegisterInfo::isVirtualRegister(reg))
|
if (MRegisterInfo::isVirtualRegister(reg))
|
||||||
handleVirtualRegisterDef(MBB, MI, getOrCreateInterval(reg));
|
handleVirtualRegisterDef(MBB, MI, getOrCreateInterval(reg));
|
||||||
else if (allocatableRegs_[reg]) {
|
else if (allocatableRegs_[reg]) {
|
||||||
handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(reg));
|
unsigned SrcReg, DstReg;
|
||||||
|
if (!tii_->isMoveInstr(*MI, SrcReg, DstReg))
|
||||||
|
SrcReg = 0;
|
||||||
|
handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(reg), SrcReg);
|
||||||
for (const unsigned* AS = mri_->getAliasSet(reg); *AS; ++AS)
|
for (const unsigned* AS = mri_->getAliasSet(reg); *AS; ++AS)
|
||||||
handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(*AS), true);
|
handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(*AS), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,24 +670,17 @@ bool LiveIntervals::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInterval &IntB,
|
|||||||
// If AValNo is defined as a copy from IntB, we can potentially process this.
|
// If AValNo is defined as a copy from IntB, we can potentially process this.
|
||||||
|
|
||||||
// Get the instruction that defines this value number.
|
// Get the instruction that defines this value number.
|
||||||
unsigned AValNoInstIdx = IntA.getInstForValNum(AValNo);
|
unsigned SrcReg = IntA.getSrcRegForValNum(AValNo);
|
||||||
|
if (!SrcReg) return false; // Not defined by a copy.
|
||||||
// If it's unknown, ignore it.
|
|
||||||
if (AValNoInstIdx == ~0U || AValNoInstIdx == ~1U) return false;
|
|
||||||
// Otherwise, get the instruction for it.
|
|
||||||
MachineInstr *AValNoInstMI = getInstructionFromIndex(AValNoInstIdx);
|
|
||||||
|
|
||||||
// If the value number is not defined by a copy instruction, ignore it.
|
// If the value number is not defined by a copy instruction, ignore it.
|
||||||
unsigned SrcReg, DstReg;
|
|
||||||
if (!tii_->isMoveInstr(*AValNoInstMI, SrcReg, DstReg))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// If the source register comes from an interval other than IntB, we can't
|
// If the source register comes from an interval other than IntB, we can't
|
||||||
// handle this.
|
// handle this.
|
||||||
assert(rep(DstReg) == IntA.reg && "Not defining a reg in IntA?");
|
|
||||||
if (rep(SrcReg) != IntB.reg) return false;
|
if (rep(SrcReg) != IntB.reg) return false;
|
||||||
|
|
||||||
// Get the LiveRange in IntB that this value number starts with.
|
// Get the LiveRange in IntB that this value number starts with.
|
||||||
|
unsigned AValNoInstIdx = IntA.getInstForValNum(AValNo);
|
||||||
LiveInterval::iterator ValLR = IntB.FindLiveRangeContaining(AValNoInstIdx-1);
|
LiveInterval::iterator ValLR = IntB.FindLiveRangeContaining(AValNoInstIdx-1);
|
||||||
|
|
||||||
// Make sure that the end of the live range is inside the same block as
|
// Make sure that the end of the live range is inside the same block as
|
||||||
@ -687,7 +698,7 @@ bool LiveIntervals::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInterval &IntB,
|
|||||||
|
|
||||||
// We are about to delete CopyMI, so need to remove it as the 'instruction
|
// We are about to delete CopyMI, so need to remove it as the 'instruction
|
||||||
// that defines this value #'.
|
// that defines this value #'.
|
||||||
IntB.setInstDefiningValNum(BValNo, ~0U);
|
IntB.setValueNumberInfo(BValNo, std::make_pair(~0U, 0));
|
||||||
|
|
||||||
// Okay, we can merge them. We need to insert a new liverange:
|
// Okay, we can merge them. We need to insert a new liverange:
|
||||||
// [ValLR.end, BLR.begin) of either value number, then we merge the
|
// [ValLR.end, BLR.begin) of either value number, then we merge the
|
||||||
@ -701,7 +712,7 @@ bool LiveIntervals::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInterval &IntB,
|
|||||||
for (const unsigned *AS = mri_->getAliasSet(IntB.reg); *AS; ++AS) {
|
for (const unsigned *AS = mri_->getAliasSet(IntB.reg); *AS; ++AS) {
|
||||||
LiveInterval &AliasLI = getInterval(*AS);
|
LiveInterval &AliasLI = getInterval(*AS);
|
||||||
AliasLI.addRange(LiveRange(FillerStart, FillerEnd,
|
AliasLI.addRange(LiveRange(FillerStart, FillerEnd,
|
||||||
AliasLI.getNextValue(~0U)));
|
AliasLI.getNextValue(~0U, 0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -832,7 +843,8 @@ bool LiveIntervals::JoinCopy(MachineInstr *CopyMI,
|
|||||||
/// contains the value number the copy is from.
|
/// contains the value number the copy is from.
|
||||||
///
|
///
|
||||||
static unsigned ComputeUltimateVN(unsigned VN,
|
static unsigned ComputeUltimateVN(unsigned VN,
|
||||||
SmallVector<unsigned, 16> &InstDefiningValue,
|
SmallVector<std::pair<unsigned,
|
||||||
|
unsigned>, 16> &ValueNumberInfo,
|
||||||
SmallVector<int, 16> &ThisFromOther,
|
SmallVector<int, 16> &ThisFromOther,
|
||||||
SmallVector<int, 16> &OtherFromThis,
|
SmallVector<int, 16> &OtherFromThis,
|
||||||
SmallVector<int, 16> &ThisValNoAssignments,
|
SmallVector<int, 16> &ThisValNoAssignments,
|
||||||
@ -847,8 +859,8 @@ static unsigned ComputeUltimateVN(unsigned VN,
|
|||||||
// number in the destination.
|
// number in the destination.
|
||||||
int OtherValNo = ThisFromOther[VN];
|
int OtherValNo = ThisFromOther[VN];
|
||||||
if (OtherValNo == -1) {
|
if (OtherValNo == -1) {
|
||||||
InstDefiningValue.push_back(ThisLI.getInstForValNum(VN));
|
ValueNumberInfo.push_back(ThisLI.getValNumInfo(VN));
|
||||||
return ThisValNoAssignments[VN] = InstDefiningValue.size()-1;
|
return ThisValNoAssignments[VN] = ValueNumberInfo.size()-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, this *is* a copy from the RHS. Mark this value number as
|
// Otherwise, this *is* a copy from the RHS. Mark this value number as
|
||||||
@ -856,7 +868,7 @@ static unsigned ComputeUltimateVN(unsigned VN,
|
|||||||
// value is.
|
// value is.
|
||||||
ThisValNoAssignments[VN] = -2;
|
ThisValNoAssignments[VN] = -2;
|
||||||
unsigned UltimateVN =
|
unsigned UltimateVN =
|
||||||
ComputeUltimateVN(OtherValNo, InstDefiningValue,
|
ComputeUltimateVN(OtherValNo, ValueNumberInfo,
|
||||||
OtherFromThis, ThisFromOther,
|
OtherFromThis, ThisFromOther,
|
||||||
OtherValNoAssignments, ThisValNoAssignments,
|
OtherValNoAssignments, ThisValNoAssignments,
|
||||||
OtherLI, ThisLI);
|
OtherLI, ThisLI);
|
||||||
@ -875,24 +887,17 @@ bool LiveIntervals::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS) {
|
|||||||
SmallVector<int, 16> LHSValsDefinedFromRHS;
|
SmallVector<int, 16> LHSValsDefinedFromRHS;
|
||||||
LHSValsDefinedFromRHS.resize(LHS.getNumValNums(), -1);
|
LHSValsDefinedFromRHS.resize(LHS.getNumValNums(), -1);
|
||||||
for (unsigned VN = 0, e = LHS.getNumValNums(); VN != e; ++VN) {
|
for (unsigned VN = 0, e = LHS.getNumValNums(); VN != e; ++VN) {
|
||||||
unsigned ValInst = LHS.getInstForValNum(VN);
|
unsigned ValSrcReg = LHS.getSrcRegForValNum(VN);
|
||||||
if (ValInst == ~0U || ValInst == ~1U)
|
if (ValSrcReg == 0) // Src not defined by a copy?
|
||||||
continue;
|
|
||||||
|
|
||||||
// If the instruction defining the LHS's value is a copy.
|
|
||||||
MachineInstr *ValInstMI = getInstructionFromIndex(ValInst);
|
|
||||||
|
|
||||||
// If the value number is not defined by a copy instruction, ignore it.
|
|
||||||
unsigned SrcReg, DstReg;
|
|
||||||
if (!tii_->isMoveInstr(*ValInstMI, SrcReg, DstReg))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// DstReg is known to be a register in the LHS interval. If the src is from
|
// DstReg is known to be a register in the LHS interval. If the src is from
|
||||||
// the RHS interval, we can use its value #.
|
// the RHS interval, we can use its value #.
|
||||||
if (rep(SrcReg) != RHS.reg)
|
if (rep(ValSrcReg) != RHS.reg)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Figure out the value # from the RHS.
|
// Figure out the value # from the RHS.
|
||||||
|
unsigned ValInst = LHS.getInstForValNum(VN);
|
||||||
LHSValsDefinedFromRHS[VN] = RHS.getLiveRangeContaining(ValInst-1)->ValId;
|
LHSValsDefinedFromRHS[VN] = RHS.getLiveRangeContaining(ValInst-1)->ValId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -901,24 +906,17 @@ bool LiveIntervals::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS) {
|
|||||||
SmallVector<int, 16> RHSValsDefinedFromLHS;
|
SmallVector<int, 16> RHSValsDefinedFromLHS;
|
||||||
RHSValsDefinedFromLHS.resize(RHS.getNumValNums(), -1);
|
RHSValsDefinedFromLHS.resize(RHS.getNumValNums(), -1);
|
||||||
for (unsigned VN = 0, e = RHS.getNumValNums(); VN != e; ++VN) {
|
for (unsigned VN = 0, e = RHS.getNumValNums(); VN != e; ++VN) {
|
||||||
unsigned ValInst = RHS.getInstForValNum(VN);
|
unsigned ValSrcReg = RHS.getSrcRegForValNum(VN);
|
||||||
if (ValInst == ~0U || ValInst == ~1U)
|
if (ValSrcReg == 0) // Src not defined by a copy?
|
||||||
continue;
|
|
||||||
|
|
||||||
// If the instruction defining the RHS's value is a copy.
|
|
||||||
MachineInstr *ValInstMI = getInstructionFromIndex(ValInst);
|
|
||||||
|
|
||||||
// If the value number is not defined by a copy instruction, ignore it.
|
|
||||||
unsigned SrcReg, DstReg;
|
|
||||||
if (!tii_->isMoveInstr(*ValInstMI, SrcReg, DstReg))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// DstReg is known to be a register in the RHS interval. If the src is from
|
// DstReg is known to be a register in the RHS interval. If the src is from
|
||||||
// the LHS interval, we can use its value #.
|
// the LHS interval, we can use its value #.
|
||||||
if (rep(SrcReg) != LHS.reg)
|
if (rep(ValSrcReg) != LHS.reg)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Figure out the value # from the LHS.
|
// Figure out the value # from the LHS.
|
||||||
|
unsigned ValInst = RHS.getInstForValNum(VN);
|
||||||
RHSValsDefinedFromLHS[VN] = LHS.getLiveRangeContaining(ValInst-1)->ValId;
|
RHSValsDefinedFromLHS[VN] = LHS.getLiveRangeContaining(ValInst-1)->ValId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -926,20 +924,20 @@ bool LiveIntervals::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS) {
|
|||||||
// assuming that the live ranges can be coallesced.
|
// assuming that the live ranges can be coallesced.
|
||||||
SmallVector<int, 16> LHSValNoAssignments;
|
SmallVector<int, 16> LHSValNoAssignments;
|
||||||
SmallVector<int, 16> RHSValNoAssignments;
|
SmallVector<int, 16> RHSValNoAssignments;
|
||||||
SmallVector<unsigned, 16> InstDefiningValue;
|
SmallVector<std::pair<unsigned,unsigned>, 16> ValueNumberInfo;
|
||||||
LHSValNoAssignments.resize(LHS.getNumValNums(), -1);
|
LHSValNoAssignments.resize(LHS.getNumValNums(), -1);
|
||||||
RHSValNoAssignments.resize(RHS.getNumValNums(), -1);
|
RHSValNoAssignments.resize(RHS.getNumValNums(), -1);
|
||||||
|
|
||||||
// Compute ultimate value numbers for the LHS and RHS values.
|
// Compute ultimate value numbers for the LHS and RHS values.
|
||||||
for (unsigned VN = 0, e = LHS.getNumValNums(); VN != e; ++VN) {
|
for (unsigned VN = 0, e = LHS.getNumValNums(); VN != e; ++VN) {
|
||||||
if (LHS.getInstForValNum(VN) == ~2U) continue;
|
if (LHS.getInstForValNum(VN) == ~2U) continue;
|
||||||
ComputeUltimateVN(VN, InstDefiningValue,
|
ComputeUltimateVN(VN, ValueNumberInfo,
|
||||||
LHSValsDefinedFromRHS, RHSValsDefinedFromLHS,
|
LHSValsDefinedFromRHS, RHSValsDefinedFromLHS,
|
||||||
LHSValNoAssignments, RHSValNoAssignments, LHS, RHS);
|
LHSValNoAssignments, RHSValNoAssignments, LHS, RHS);
|
||||||
}
|
}
|
||||||
for (unsigned VN = 0, e = RHS.getNumValNums(); VN != e; ++VN) {
|
for (unsigned VN = 0, e = RHS.getNumValNums(); VN != e; ++VN) {
|
||||||
if (RHS.getInstForValNum(VN) == ~2U) continue;
|
if (RHS.getInstForValNum(VN) == ~2U) continue;
|
||||||
ComputeUltimateVN(VN, InstDefiningValue,
|
ComputeUltimateVN(VN, ValueNumberInfo,
|
||||||
RHSValsDefinedFromLHS, LHSValsDefinedFromRHS,
|
RHSValsDefinedFromLHS, LHSValsDefinedFromRHS,
|
||||||
RHSValNoAssignments, LHSValNoAssignments, RHS, LHS);
|
RHSValNoAssignments, LHSValNoAssignments, RHS, LHS);
|
||||||
}
|
}
|
||||||
@ -989,7 +987,7 @@ bool LiveIntervals::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS) {
|
|||||||
// If we get here, we know that we can coallesce the live ranges. Ask the
|
// If we get here, we know that we can coallesce the live ranges. Ask the
|
||||||
// intervals to coallesce themselves now.
|
// intervals to coallesce themselves now.
|
||||||
LHS.join(RHS, &LHSValNoAssignments[0], &RHSValNoAssignments[0],
|
LHS.join(RHS, &LHSValNoAssignments[0], &RHSValNoAssignments[0],
|
||||||
InstDefiningValue);
|
ValueNumberInfo);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user