forked from OSchip/llvm-project
LiveInterval: Implement feedback by Quentin Colombet.
llvm-svn: 225413
This commit is contained in:
parent
76ebd15437
commit
4fe686af00
|
@ -635,9 +635,8 @@ static VNInfo *searchForVNI(const SlotIndexes &Indexes, LiveRange &LR,
|
||||||
// Continue at predecessors (we could even go to idom with domtree available).
|
// Continue at predecessors (we could even go to idom with domtree available).
|
||||||
for (const MachineBasicBlock *Pred : MBB->predecessors()) {
|
for (const MachineBasicBlock *Pred : MBB->predecessors()) {
|
||||||
// Avoid going in circles.
|
// Avoid going in circles.
|
||||||
if (Visited.count(Pred))
|
if (!Visited.insert(Pred).second)
|
||||||
continue;
|
continue;
|
||||||
Visited.insert(Pred);
|
|
||||||
|
|
||||||
VNI = searchForVNI(Indexes, LR, Pred, Visited);
|
VNI = searchForVNI(Indexes, LR, Pred, Visited);
|
||||||
if (VNI != nullptr) {
|
if (VNI != nullptr) {
|
||||||
|
@ -649,6 +648,27 @@ static VNInfo *searchForVNI(const SlotIndexes &Indexes, LiveRange &LR,
|
||||||
return VNI;
|
return VNI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void determineMissingVNIs(const SlotIndexes &Indexes, LiveInterval &LI) {
|
||||||
|
SmallPtrSet<const MachineBasicBlock*, 5> Visited;
|
||||||
|
for (LiveRange::Segment &S : LI.segments) {
|
||||||
|
if (S.valno != nullptr)
|
||||||
|
continue;
|
||||||
|
// This can only happen at the begin of a basic block.
|
||||||
|
assert(S.start.isBlock() && "valno should only be missing at block begin");
|
||||||
|
|
||||||
|
Visited.clear();
|
||||||
|
const MachineBasicBlock *MBB = Indexes.getMBBFromIndex(S.start);
|
||||||
|
for (const MachineBasicBlock *Pred : MBB->predecessors()) {
|
||||||
|
VNInfo *VNI = searchForVNI(Indexes, LI, Pred, Visited);
|
||||||
|
if (VNI != nullptr) {
|
||||||
|
S.valno = VNI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(S.valno != nullptr && "could not determine valno");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LiveInterval::constructMainRangeFromSubranges(
|
void LiveInterval::constructMainRangeFromSubranges(
|
||||||
const SlotIndexes &Indexes, VNInfo::Allocator &VNIAllocator) {
|
const SlotIndexes &Indexes, VNInfo::Allocator &VNIAllocator) {
|
||||||
// The basic observations on which this algorithm is based:
|
// The basic observations on which this algorithm is based:
|
||||||
|
@ -659,7 +679,7 @@ void LiveInterval::constructMainRangeFromSubranges(
|
||||||
// live either.
|
// live either.
|
||||||
// We do this by scannig through all the subranges simultaneously creating new
|
// We do this by scannig through all the subranges simultaneously creating new
|
||||||
// segments in the main range as segments start/ends come up in the subranges.
|
// segments in the main range as segments start/ends come up in the subranges.
|
||||||
assert(hasSubRanges());
|
assert(hasSubRanges() && "expected subranges to be present");
|
||||||
assert(segments.empty() && valnos.empty() && "expected empty main range");
|
assert(segments.empty() && valnos.empty() && "expected empty main range");
|
||||||
|
|
||||||
// Collect subrange, iterator pairs for the walk and determine first and last
|
// Collect subrange, iterator pairs for the walk and determine first and last
|
||||||
|
@ -690,7 +710,9 @@ void LiveInterval::constructMainRangeFromSubranges(
|
||||||
BEGIN_SEGMENT,
|
BEGIN_SEGMENT,
|
||||||
END_SEGMENT,
|
END_SEGMENT,
|
||||||
} Event = NOTHING;
|
} Event = NOTHING;
|
||||||
|
// Which subregister lanes are affected by the current event.
|
||||||
unsigned EventMask = 0;
|
unsigned EventMask = 0;
|
||||||
|
// Whether a BEGIN_SEGMENT is also a valno definition point.
|
||||||
bool IsDef = false;
|
bool IsDef = false;
|
||||||
// Find the next begin or end of a subrange segment. Combine masks if we
|
// Find the next begin or end of a subrange segment. Combine masks if we
|
||||||
// have multiple begins/ends at the same position. Ends take precedence over
|
// have multiple begins/ends at the same position. Ends take precedence over
|
||||||
|
@ -698,6 +720,8 @@ void LiveInterval::constructMainRangeFromSubranges(
|
||||||
for (auto &SRP : SRs) {
|
for (auto &SRP : SRs) {
|
||||||
const SubRange &SR = *SRP.first;
|
const SubRange &SR = *SRP.first;
|
||||||
const_iterator &I = SRP.second;
|
const_iterator &I = SRP.second;
|
||||||
|
// Advance iterator of subrange to a segment involving Pos; the earlier
|
||||||
|
// segments are already merged at this point.
|
||||||
while (I != SR.end() &&
|
while (I != SR.end() &&
|
||||||
(I->end < Pos ||
|
(I->end < Pos ||
|
||||||
(I->end == Pos && (ActiveMask & SR.LaneMask) == 0)))
|
(I->end == Pos && (ActiveMask & SR.LaneMask) == 0)))
|
||||||
|
@ -706,7 +730,7 @@ void LiveInterval::constructMainRangeFromSubranges(
|
||||||
continue;
|
continue;
|
||||||
if ((ActiveMask & SR.LaneMask) == 0 &&
|
if ((ActiveMask & SR.LaneMask) == 0 &&
|
||||||
Pos <= I->start && I->start <= NextPos) {
|
Pos <= I->start && I->start <= NextPos) {
|
||||||
// Merge multiple begins at the same position
|
// Merge multiple begins at the same position.
|
||||||
if (I->start == NextPos && Event == BEGIN_SEGMENT) {
|
if (I->start == NextPos && Event == BEGIN_SEGMENT) {
|
||||||
EventMask |= SR.LaneMask;
|
EventMask |= SR.LaneMask;
|
||||||
IsDef |= I->valno->def == I->start;
|
IsDef |= I->valno->def == I->start;
|
||||||
|
@ -789,27 +813,10 @@ void LiveInterval::constructMainRangeFromSubranges(
|
||||||
// We might not be able to assign new valnos for all segments if the basic
|
// We might not be able to assign new valnos for all segments if the basic
|
||||||
// block containing the definition comes after a segment using the valno.
|
// block containing the definition comes after a segment using the valno.
|
||||||
// Do a fixup pass for this uncommon case.
|
// Do a fixup pass for this uncommon case.
|
||||||
if (NeedVNIFixup) {
|
if (NeedVNIFixup)
|
||||||
SmallPtrSet<const MachineBasicBlock*, 5> Visited;
|
determineMissingVNIs(Indexes, *this);
|
||||||
for (Segment &S : segments) {
|
|
||||||
if (S.valno != nullptr)
|
|
||||||
continue;
|
|
||||||
// This can only happen at the begin of a basic block.
|
|
||||||
assert(S.start.isBlock());
|
|
||||||
|
|
||||||
Visited.clear();
|
assert(ActiveMask == 0 && !ConstructingSegment && "all segments ended");
|
||||||
const MachineBasicBlock *MBB = Indexes.getMBBFromIndex(S.start);
|
|
||||||
for (const MachineBasicBlock *Pred : MBB->predecessors()) {
|
|
||||||
VNInfo *VNI = searchForVNI(Indexes, *this, Pred, Visited);
|
|
||||||
if (VNI != nullptr) {
|
|
||||||
S.valno = VNI;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(S.valno != nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(ActiveMask == 0 && !ConstructingSegment);
|
|
||||||
verify();
|
verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue