1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

LiveInterval: Implement feedback by Quentin Colombet.

llvm-svn: 225413
This commit is contained in:
Matthias Braun 2015-01-07 23:35:11 +00:00
parent 2ad347b060
commit 8e4dd54b28

View File

@ -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();
} }