mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-18 17:39:04 +00:00
Code to maintain kill information during register coalescing.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41016 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a1eb155e52
commit
4f8ff168de
@ -144,57 +144,164 @@ namespace llvm {
|
||||
return ValueNumberInfo.size()-1;
|
||||
}
|
||||
|
||||
/// getInstForValNum - Return the machine instruction index that defines the
|
||||
/// getDefForValNum - Return the machine instruction index that defines the
|
||||
/// specified value number.
|
||||
unsigned getInstForValNum(unsigned ValNo) const {
|
||||
unsigned getDefForValNum(unsigned ValNo) const {
|
||||
assert(ValNo < ValueNumberInfo.size());
|
||||
return ValueNumberInfo[ValNo].def;
|
||||
}
|
||||
|
||||
/// getSrcRegForValNum - If the machine instruction that defines the
|
||||
/// specified value number is a copy, returns the source register. Otherwise,
|
||||
/// returns zero.
|
||||
unsigned getSrcRegForValNum(unsigned ValNo) const {
|
||||
assert(ValNo < ValueNumberInfo.size());
|
||||
return ValueNumberInfo[ValNo].reg;
|
||||
}
|
||||
|
||||
/// setDefForValNum - Set the machine instruction index that defines the
|
||||
/// specified value number.
|
||||
void setDefForValNum(unsigned ValNo, unsigned NewDef) {
|
||||
assert(ValNo < ValueNumberInfo.size());
|
||||
ValueNumberInfo[ValNo].def = NewDef;
|
||||
}
|
||||
|
||||
/// setSrcRegForValNum - Set the source register of the specified value
|
||||
/// number.
|
||||
void setSrcRegForValNum(unsigned ValNo, unsigned NewReg) {
|
||||
assert(ValNo < ValueNumberInfo.size());
|
||||
ValueNumberInfo[ValNo].reg = NewReg;
|
||||
}
|
||||
|
||||
/// getKillsForValNum - Return the kill instruction indexes of the specified
|
||||
/// value number.
|
||||
const SmallVector<unsigned, 4> &getKillsForValNum(unsigned ValNo) const {
|
||||
assert(ValNo < ValueNumberInfo.size());
|
||||
return ValueNumberInfo[ValNo].kills;
|
||||
}
|
||||
|
||||
|
||||
/// addKillForValNum - Add a kill instruction index to the specified value
|
||||
/// number.
|
||||
void addKillForValNum(unsigned ValNo, unsigned KillIdx) {
|
||||
assert(ValNo < ValueNumberInfo.size());
|
||||
ValueNumberInfo[ValNo].kills.push_back(KillIdx);
|
||||
SmallVector<unsigned, 4> &kills = ValueNumberInfo[ValNo].kills;
|
||||
if (kills.empty()) {
|
||||
kills.push_back(KillIdx);
|
||||
} else {
|
||||
SmallVector<unsigned, 4>::iterator
|
||||
I = std::lower_bound(kills.begin(), kills.end(), KillIdx);
|
||||
kills.insert(I, KillIdx);
|
||||
}
|
||||
}
|
||||
|
||||
/// replaceKillForValNum - Replace a kill index of the specified value with
|
||||
/// a new kill index.
|
||||
bool replaceKillForValNum(unsigned ValNo, unsigned OldKill,
|
||||
unsigned NewKill) {
|
||||
SmallVector<unsigned, 4> kills = ValueNumberInfo[ValNo].kills;
|
||||
SmallVector<unsigned, 4>::iterator I =
|
||||
std::find(kills.begin(), kills.end(), OldKill);
|
||||
/// addKills - Add a number of kills into the VNInfo kill vector. If this
|
||||
/// interval is live at a kill point, then the kill is not added.
|
||||
void addKills(VNInfo &VNI, const SmallVector<unsigned, 4> &kills) {
|
||||
for (unsigned i = 0, e = kills.size(); i != e; ++i) {
|
||||
unsigned KillIdx = kills[i];
|
||||
if (!liveAt(KillIdx)) {
|
||||
SmallVector<unsigned, 4>::iterator
|
||||
I = std::lower_bound(VNI.kills.begin(), VNI.kills.end(), KillIdx);
|
||||
VNI.kills.insert(I, KillIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// addKillsForValNum - Add a number of kills into the kills vector of
|
||||
/// the specified value number.
|
||||
void addKillsForValNum(unsigned ValNo,
|
||||
const SmallVector<unsigned, 4> &kills) {
|
||||
addKills(ValueNumberInfo[ValNo], kills);
|
||||
}
|
||||
|
||||
/// isKillForValNum - Returns true if KillIdx is a kill of the specified
|
||||
/// val#.
|
||||
bool isKillForValNum(unsigned ValNo, unsigned KillIdx) const {
|
||||
assert(ValNo < ValueNumberInfo.size());
|
||||
const SmallVector<unsigned, 4> &kills = ValueNumberInfo[ValNo].kills;
|
||||
SmallVector<unsigned, 4>::const_iterator
|
||||
I = std::lower_bound(kills.begin(), kills.end(), KillIdx);
|
||||
if (I == kills.end())
|
||||
return false;
|
||||
kills.erase(I);
|
||||
kills.push_back(NewKill);
|
||||
return true;
|
||||
return *I == KillIdx;
|
||||
}
|
||||
|
||||
/// removeKill - Remove the specified kill from the list of kills of
|
||||
/// the specified val#.
|
||||
static bool removeKill(VNInfo &VNI, unsigned KillIdx) {
|
||||
SmallVector<unsigned, 4> &kills = VNI.kills;
|
||||
SmallVector<unsigned, 4>::iterator
|
||||
I = std::lower_bound(kills.begin(), kills.end(), KillIdx);
|
||||
if (I != kills.end() && *I == KillIdx) {
|
||||
kills.erase(I);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// removeKillForValNum - Remove the specified kill from the list of kills
|
||||
/// of the specified val#.
|
||||
bool removeKillForValNum(unsigned ValNo, unsigned KillIdx) {
|
||||
assert(ValNo < ValueNumberInfo.size());
|
||||
return removeKill(ValueNumberInfo[ValNo], KillIdx);
|
||||
}
|
||||
|
||||
/// removeKillForValNum - Remove all the kills in specified range
|
||||
/// [Start, End] of the specified val#.
|
||||
void removeKillForValNum(unsigned ValNo, unsigned Start, unsigned End) {
|
||||
assert(ValNo < ValueNumberInfo.size());
|
||||
SmallVector<unsigned, 4> &kills = ValueNumberInfo[ValNo].kills;
|
||||
SmallVector<unsigned, 4>::iterator
|
||||
I = std::lower_bound(kills.begin(), kills.end(), Start);
|
||||
SmallVector<unsigned, 4>::iterator
|
||||
E = std::upper_bound(kills.begin(), kills.end(), End);
|
||||
kills.erase(I, E);
|
||||
}
|
||||
|
||||
/// replaceKill - Replace a kill index of the specified value# with a new
|
||||
/// kill. Returns true if OldKill was indeed a kill point.
|
||||
static bool replaceKill(VNInfo &VNI, unsigned OldKill, unsigned NewKill) {
|
||||
SmallVector<unsigned, 4> &kills = VNI.kills;
|
||||
SmallVector<unsigned, 4>::iterator
|
||||
I = std::lower_bound(kills.begin(), kills.end(), OldKill);
|
||||
if (I != kills.end() && *I == OldKill) {
|
||||
*I = NewKill;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// replaceKillForValNum - Replace a kill index of the specified value# with
|
||||
/// a new kill. Returns true if OldKill was indeed a kill point.
|
||||
bool replaceKillForValNum(unsigned ValNo, unsigned OldKill,
|
||||
unsigned NewKill) {
|
||||
assert(ValNo < ValueNumberInfo.size());
|
||||
return replaceKill(ValueNumberInfo[ValNo], OldKill, NewKill);
|
||||
}
|
||||
|
||||
/// getValNumInfo - Returns a copy of the specified val#.
|
||||
///
|
||||
VNInfo getValNumInfo(unsigned ValNo) const {
|
||||
assert(ValNo < ValueNumberInfo.size());
|
||||
return ValueNumberInfo[ValNo];
|
||||
}
|
||||
|
||||
/// setValueNumberInfo - Change the value number info for the specified
|
||||
/// setValNumInfo - Change the value number info for the specified
|
||||
/// value number.
|
||||
void setValueNumberInfo(unsigned ValNo, const VNInfo &I) {
|
||||
void setValNumInfo(unsigned ValNo, const VNInfo &I) {
|
||||
ValueNumberInfo[ValNo] = I;
|
||||
}
|
||||
|
||||
/// copyValNumInfo - Copy the value number info for one value number to
|
||||
/// another.
|
||||
void copyValNumInfo(unsigned DstValNo, unsigned SrcValNo) {
|
||||
ValueNumberInfo[DstValNo] = ValueNumberInfo[SrcValNo];
|
||||
}
|
||||
void copyValNumInfo(unsigned DstValNo, const LiveInterval &SrcLI,
|
||||
unsigned SrcValNo) {
|
||||
ValueNumberInfo[DstValNo] = SrcLI.ValueNumberInfo[SrcValNo];
|
||||
}
|
||||
|
||||
/// MergeValueNumberInto - This method is called when two value nubmers
|
||||
/// are found to be equivalent. This eliminates V1, replacing all
|
||||
/// LiveRanges with the V1 value number with the V2 value number. This can
|
||||
|
@ -121,7 +121,10 @@ void LiveInterval::extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd) {
|
||||
|
||||
// Erase any dead ranges.
|
||||
ranges.erase(next(I), MergeTo);
|
||||
|
||||
|
||||
// Update kill info.
|
||||
removeKillForValNum(ValId, I->start, I->end-1);
|
||||
|
||||
// If the newly formed range now touches the range after it and if they have
|
||||
// the same value number, merge the two ranges into one range.
|
||||
Ranges::iterator Next = next(I);
|
||||
@ -228,9 +231,10 @@ void LiveInterval::removeRange(unsigned Start, unsigned End) {
|
||||
|
||||
// If the span we are removing is at the start of the LiveRange, adjust it.
|
||||
if (I->start == Start) {
|
||||
if (I->end == End)
|
||||
if (I->end == End) {
|
||||
removeKillForValNum(I->ValId, End);
|
||||
ranges.erase(I); // Removed the whole LiveRange.
|
||||
else
|
||||
} else
|
||||
I->start = End;
|
||||
return;
|
||||
}
|
||||
@ -238,6 +242,7 @@ void LiveInterval::removeRange(unsigned Start, unsigned End) {
|
||||
// Otherwise if the span we are removing is at the end of the LiveRange,
|
||||
// adjust the other way.
|
||||
if (I->end == End) {
|
||||
replaceKillForValNum(I->ValId, End, Start);
|
||||
I->end = Start;
|
||||
return;
|
||||
}
|
||||
@ -336,7 +341,11 @@ void LiveInterval::join(LiveInterval &Other, int *LHSValNoAssignments,
|
||||
// If we merge some live ranges, chop off the end.
|
||||
ranges.erase(OutIt, end());
|
||||
}
|
||||
|
||||
|
||||
// Update val# info first. Increasing live ranges may invalidate some kills.
|
||||
ValueNumberInfo.clear();
|
||||
ValueNumberInfo.append(NewValueNumberInfo.begin(), NewValueNumberInfo.end());
|
||||
|
||||
// Okay, now insert the RHS live ranges into the LHS.
|
||||
iterator InsertPos = begin();
|
||||
for (iterator I = Other.begin(), E = Other.end(); I != E; ++I) {
|
||||
@ -345,8 +354,6 @@ void LiveInterval::join(LiveInterval &Other, int *LHSValNoAssignments,
|
||||
InsertPos = addRangeFrom(*I, InsertPos);
|
||||
}
|
||||
|
||||
ValueNumberInfo.clear();
|
||||
ValueNumberInfo.append(NewValueNumberInfo.begin(), NewValueNumberInfo.end());
|
||||
weight += Other.weight;
|
||||
if (Other.preference && !preference)
|
||||
preference = Other.preference;
|
||||
@ -417,7 +424,7 @@ void LiveInterval::MergeValueNumberInto(unsigned V1, unsigned V2) {
|
||||
|
||||
// Make sure V2 is smaller than V1.
|
||||
if (V1 < V2) {
|
||||
setValueNumberInfo(V1, getValNumInfo(V2));
|
||||
copyValNumInfo(V1, V2);
|
||||
std::swap(V1, V2);
|
||||
}
|
||||
|
||||
@ -431,6 +438,8 @@ void LiveInterval::MergeValueNumberInto(unsigned V1, unsigned V2) {
|
||||
if (LR != begin()) {
|
||||
iterator Prev = LR-1;
|
||||
if (Prev->ValId == V2 && Prev->end == LR->start) {
|
||||
bool Replaced = replaceKillForValNum(V2, Prev->end, LR->end);
|
||||
assert(Replaced);
|
||||
Prev->end = LR->end;
|
||||
|
||||
// Erase this live-range.
|
||||
@ -449,6 +458,7 @@ void LiveInterval::MergeValueNumberInto(unsigned V1, unsigned V2) {
|
||||
// of the loop.
|
||||
if (I != end()) {
|
||||
if (I->start == LR->end && I->ValId == V2) {
|
||||
removeKillForValNum(V2, LR->end);
|
||||
LR->end = I->end;
|
||||
ranges.erase(I);
|
||||
I = LR+1;
|
||||
@ -506,12 +516,23 @@ 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].def == ~0U) {
|
||||
OS << "?";
|
||||
} else if (ValueNumberInfo[i].def == ~1U) {
|
||||
if (ValueNumberInfo[i].def == ~1U) {
|
||||
OS << "x";
|
||||
} else {
|
||||
OS << ValueNumberInfo[i].def;
|
||||
if (ValueNumberInfo[i].def == ~0U)
|
||||
OS << "?";
|
||||
else
|
||||
OS << ValueNumberInfo[i].def;
|
||||
unsigned e = ValueNumberInfo[i].kills.size();
|
||||
if (e) {
|
||||
OS << "-(";
|
||||
for (unsigned j = 0; j != e; ++j) {
|
||||
OS << ValueNumberInfo[i].kills[j];
|
||||
if (j != e-1)
|
||||
OS << " ";
|
||||
}
|
||||
OS << ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -437,6 +437,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
unsigned DefIndex = getDefIndex(getInstructionIndex(vi.DefInst));
|
||||
unsigned RedefIndex = getDefIndex(MIIdx);
|
||||
|
||||
const LiveRange *OldLR = interval.getLiveRangeContaining(RedefIndex-1);
|
||||
unsigned OldEnd = OldLR->end;
|
||||
|
||||
// Delete the initial value, which should be short and continuous,
|
||||
// because the 2-addr copy must be in the same MBB as the redef.
|
||||
interval.removeRange(DefIndex, RedefIndex);
|
||||
@ -448,16 +451,18 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
// The new value number (#1) is defined by the instruction we claimed
|
||||
// defined value #0.
|
||||
unsigned ValNo = interval.getNextValue(0, 0);
|
||||
interval.setValueNumberInfo(1, interval.getValNumInfo(0));
|
||||
interval.copyValNumInfo(ValNo, 0);
|
||||
|
||||
// Value#0 is now defined by the 2-addr instruction.
|
||||
interval.setValueNumberInfo(0, LiveInterval::VNInfo(DefIndex, 0U));
|
||||
interval.setDefForValNum(0, RedefIndex);
|
||||
interval.setSrcRegForValNum(0, 0);
|
||||
|
||||
// Add the new live interval which replaces the range for the input copy.
|
||||
LiveRange LR(DefIndex, RedefIndex, ValNo);
|
||||
DOUT << " replace range with " << LR;
|
||||
interval.addRange(LR);
|
||||
interval.addKillForValNum(ValNo, RedefIndex);
|
||||
interval.removeKillForValNum(ValNo, RedefIndex, OldEnd);
|
||||
|
||||
// If this redefinition is dead, we need to add a dummy unit live
|
||||
// range covering the def slot.
|
||||
@ -482,8 +487,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
DOUT << " Removing [" << Start << "," << End << "] from: ";
|
||||
interval.print(DOUT, mri_); DOUT << "\n";
|
||||
interval.removeRange(Start, End);
|
||||
bool replaced = interval.replaceKillForValNum(0, End, Start);
|
||||
assert(replaced && "Incorrect kill info?");
|
||||
interval.addKillForValNum(0, Start);
|
||||
DOUT << " RESULT: "; interval.print(DOUT, mri_);
|
||||
|
||||
// Replace the interval with one of a NEW value number. Note that this
|
||||
|
@ -90,7 +90,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInte
|
||||
// Get the location that B is defined at. Two options: either this value has
|
||||
// an unknown definition point or it is defined at CopyIdx. If unknown, we
|
||||
// can't process it.
|
||||
unsigned BValNoDefIdx = IntB.getInstForValNum(BValNo);
|
||||
unsigned BValNoDefIdx = IntB.getDefForValNum(BValNo);
|
||||
if (!IntB.getSrcRegForValNum(BValNo)) return false;
|
||||
assert(BValNoDefIdx == CopyIdx &&
|
||||
"Copy doesn't define the value?");
|
||||
@ -112,7 +112,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInte
|
||||
if (rep(SrcReg) != IntB.reg) return false;
|
||||
|
||||
// Get the LiveRange in IntB that this value number starts with.
|
||||
unsigned AValNoInstIdx = IntA.getInstForValNum(AValNo);
|
||||
unsigned AValNoInstIdx = IntA.getDefForValNum(AValNo);
|
||||
LiveInterval::iterator ValLR = IntB.FindLiveRangeContaining(AValNoInstIdx-1);
|
||||
|
||||
// Make sure that the end of the live range is inside the same block as
|
||||
@ -132,7 +132,8 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInte
|
||||
// We are about to delete CopyMI, so need to remove it as the 'instruction
|
||||
// that defines this value #'. Update the the valnum with the new defining
|
||||
// instruction #.
|
||||
IntB.setValueNumberInfo(BValNo, LiveInterval::VNInfo(FillerStart, 0));
|
||||
IntB.setDefForValNum(BValNo, FillerStart);
|
||||
IntB.setSrcRegForValNum(BValNo, 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
|
||||
@ -399,7 +400,7 @@ bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI,
|
||||
/// contains the value number the copy is from.
|
||||
///
|
||||
static unsigned ComputeUltimateVN(unsigned VN,
|
||||
SmallVector<LiveInterval::VNInfo, 16> &ValueNumberInfo,
|
||||
SmallVector<LiveInterval::VNInfo, 16> &ValueNumberInfo,
|
||||
SmallVector<int, 16> &ThisFromOther,
|
||||
SmallVector<int, 16> &OtherFromThis,
|
||||
SmallVector<int, 16> &ThisValNoAssignments,
|
||||
@ -552,11 +553,14 @@ bool SimpleRegisterCoalescing::SimpleJoin(LiveInterval &LHS, LiveInterval &RHS)
|
||||
// Okay, now that there is a single LHS value number that we're merging the
|
||||
// RHS into, update the value number info for the LHS to indicate that the
|
||||
// value number is defined where the RHS value number was.
|
||||
LHS.setValueNumberInfo(LHSValNo, RHS.getValNumInfo(0));
|
||||
const LiveInterval::VNInfo VNI = RHS.getValNumInfo(0);
|
||||
LHS.setDefForValNum(LHSValNo, VNI.def);
|
||||
LHS.setSrcRegForValNum(LHSValNo, VNI.reg);
|
||||
|
||||
// Okay, the final step is to loop over the RHS live intervals, adding them to
|
||||
// the LHS.
|
||||
LHS.MergeRangesInAsValue(RHS, LHSValNo);
|
||||
LHS.addKillsForValNum(LHSValNo, VNI.kills);
|
||||
LHS.weight += RHS.weight;
|
||||
if (RHS.preference && !LHS.preference)
|
||||
LHS.preference = RHS.preference;
|
||||
@ -574,6 +578,8 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RH
|
||||
// coalesced.
|
||||
SmallVector<int, 16> LHSValNoAssignments;
|
||||
SmallVector<int, 16> RHSValNoAssignments;
|
||||
SmallVector<int, 16> LHSValsDefinedFromRHS;
|
||||
SmallVector<int, 16> RHSValsDefinedFromLHS;
|
||||
SmallVector<LiveInterval::VNInfo, 16> ValueNumberInfo;
|
||||
|
||||
// If a live interval is a physical register, conservatively check if any
|
||||
@ -604,6 +610,7 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RH
|
||||
// often RHS is small and LHS is large (e.g. a physreg).
|
||||
|
||||
// Find out if the RHS is defined as a copy from some value in the LHS.
|
||||
int RHSVal0DefinedFromLHS = -1;
|
||||
int RHSValID = -1;
|
||||
LiveInterval::VNInfo RHSValNoInfo;
|
||||
unsigned RHSSrcReg = RHS.getSrcRegForValNum(0);
|
||||
@ -618,9 +625,10 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RH
|
||||
}
|
||||
} else {
|
||||
// It was defined as a copy from the LHS, find out what value # it is.
|
||||
unsigned ValInst = RHS.getInstForValNum(0);
|
||||
unsigned ValInst = RHS.getDefForValNum(0);
|
||||
RHSValID = LHS.getLiveRangeContaining(ValInst-1)->ValId;
|
||||
RHSValNoInfo = LHS.getValNumInfo(RHSValID);
|
||||
RHSVal0DefinedFromLHS = RHSValID;
|
||||
}
|
||||
|
||||
LHSValNoAssignments.resize(LHS.getNumValNums(), -1);
|
||||
@ -641,13 +649,16 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RH
|
||||
// value# for it. Keep the current value number, but remember it.
|
||||
LHSValNoAssignments[VN] = RHSValID = VN;
|
||||
ValueNumberInfo[VN] = RHSValNoInfo;
|
||||
RHS.addKills(ValueNumberInfo[VN], LHS.getKillsForValNum(VN));
|
||||
} else {
|
||||
// Otherwise, use the specified value #.
|
||||
LHSValNoAssignments[VN] = RHSValID;
|
||||
if (VN != (unsigned)RHSValID)
|
||||
ValueNumberInfo[VN].def = ~1U; // Now this val# is dead.
|
||||
else
|
||||
else {
|
||||
ValueNumberInfo[VN] = RHSValNoInfo;
|
||||
RHS.addKills(ValueNumberInfo[VN], LHS.getKillsForValNum(VN));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ValueNumberInfo[VN] = LHS.getValNumInfo(VN);
|
||||
@ -657,11 +668,13 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RH
|
||||
|
||||
assert(RHSValID != -1 && "Didn't find value #?");
|
||||
RHSValNoAssignments[0] = RHSValID;
|
||||
|
||||
if (RHSVal0DefinedFromLHS != -1) {
|
||||
int LHSValId = LHSValNoAssignments[RHSVal0DefinedFromLHS];
|
||||
LHS.addKills(ValueNumberInfo[LHSValId], RHS.getKillsForValNum(0));
|
||||
}
|
||||
} else {
|
||||
// Loop over the value numbers of the LHS, seeing if any are defined from
|
||||
// the RHS.
|
||||
SmallVector<int, 16> LHSValsDefinedFromRHS;
|
||||
LHSValsDefinedFromRHS.resize(LHS.getNumValNums(), -1);
|
||||
for (unsigned VN = 0, e = LHS.getNumValNums(); VN != e; ++VN) {
|
||||
unsigned ValSrcReg = LHS.getSrcRegForValNum(VN);
|
||||
@ -674,13 +687,12 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RH
|
||||
continue;
|
||||
|
||||
// Figure out the value # from the RHS.
|
||||
unsigned ValInst = LHS.getInstForValNum(VN);
|
||||
unsigned ValInst = LHS.getDefForValNum(VN);
|
||||
LHSValsDefinedFromRHS[VN] = RHS.getLiveRangeContaining(ValInst-1)->ValId;
|
||||
}
|
||||
|
||||
// Loop over the value numbers of the RHS, seeing if any are defined from
|
||||
// the LHS.
|
||||
SmallVector<int, 16> RHSValsDefinedFromLHS;
|
||||
RHSValsDefinedFromLHS.resize(RHS.getNumValNums(), -1);
|
||||
for (unsigned VN = 0, e = RHS.getNumValNums(); VN != e; ++VN) {
|
||||
unsigned ValSrcReg = RHS.getSrcRegForValNum(VN);
|
||||
@ -693,7 +705,7 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RH
|
||||
continue;
|
||||
|
||||
// Figure out the value # from the LHS.
|
||||
unsigned ValInst = RHS.getInstForValNum(VN);
|
||||
unsigned ValInst = RHS.getDefForValNum(VN);
|
||||
RHSValsDefinedFromLHS[VN] = LHS.getLiveRangeContaining(ValInst-1)->ValId;
|
||||
}
|
||||
|
||||
@ -702,14 +714,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) == ~1U)
|
||||
if (LHSValNoAssignments[VN] >= 0 || LHS.getDefForValNum(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) == ~1U)
|
||||
if (RHSValNoAssignments[VN] >= 0 || RHS.getDefForValNum(VN) == ~1U)
|
||||
continue;
|
||||
// If this value number isn't a copy from the LHS, it's a new number.
|
||||
if (RHSValsDefinedFromLHS[VN] == -1) {
|
||||
@ -766,6 +778,22 @@ bool SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RH
|
||||
}
|
||||
}
|
||||
|
||||
// Update kill info. Some live ranges are extended due to copy coalescing.
|
||||
for (unsigned i = 0, e = RHSValsDefinedFromLHS.size(); i != e; ++i) {
|
||||
int LHSValId = RHSValsDefinedFromLHS[i];
|
||||
if (LHSValId == -1)
|
||||
continue;
|
||||
unsigned RHSValId = RHSValNoAssignments[i];
|
||||
LHS.addKills(ValueNumberInfo[RHSValId], RHS.getKillsForValNum(i));
|
||||
}
|
||||
for (unsigned i = 0, e = LHSValsDefinedFromRHS.size(); i != e; ++i) {
|
||||
int RHSValId = LHSValsDefinedFromRHS[i];
|
||||
if (RHSValId == -1)
|
||||
continue;
|
||||
unsigned LHSValId = LHSValNoAssignments[i];
|
||||
RHS.addKills(ValueNumberInfo[LHSValId], LHS.getKillsForValNum(i));
|
||||
}
|
||||
|
||||
// If we get here, we know that we can coalesce the live ranges. Ask the
|
||||
// intervals to coalesce themselves now.
|
||||
LHS.join(RHS, &LHSValNoAssignments[0], &RHSValNoAssignments[0],
|
||||
|
Loading…
Reference in New Issue
Block a user