summaryrefslogtreecommitdiff
path: root/lib/CodeGen/LiveInterval.cpp
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2015-01-07 23:35:11 +0000
committerMatthias Braun <matze@braunis.de>2015-01-07 23:35:11 +0000
commitb6eccdd6b0f82d80082e4aa30210254e0ca34069 (patch)
treeda391e41d0832ae35903073cf8d11a2f921beacc /lib/CodeGen/LiveInterval.cpp
parenta7f8f932a67badb25ac005186e39ed419ea15681 (diff)
LiveInterval: Implement feedback by Quentin Colombet.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225413 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LiveInterval.cpp')
-rw-r--r--lib/CodeGen/LiveInterval.cpp57
1 files changed, 32 insertions, 25 deletions
diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp
index 68513956af6..9423edc3091 100644
--- a/lib/CodeGen/LiveInterval.cpp
+++ b/lib/CodeGen/LiveInterval.cpp
@@ -635,9 +635,8 @@ static VNInfo *searchForVNI(const SlotIndexes &Indexes, LiveRange &LR,
// Continue at predecessors (we could even go to idom with domtree available).
for (const MachineBasicBlock *Pred : MBB->predecessors()) {
// Avoid going in circles.
- if (Visited.count(Pred))
+ if (!Visited.insert(Pred).second)
continue;
- Visited.insert(Pred);
VNI = searchForVNI(Indexes, LR, Pred, Visited);
if (VNI != nullptr) {
@@ -649,6 +648,27 @@ static VNInfo *searchForVNI(const SlotIndexes &Indexes, LiveRange &LR,
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(
const SlotIndexes &Indexes, VNInfo::Allocator &VNIAllocator) {
// The basic observations on which this algorithm is based:
@@ -659,7 +679,7 @@ void LiveInterval::constructMainRangeFromSubranges(
// live either.
// 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.
- assert(hasSubRanges());
+ assert(hasSubRanges() && "expected subranges to be present");
assert(segments.empty() && valnos.empty() && "expected empty main range");
// Collect subrange, iterator pairs for the walk and determine first and last
@@ -690,7 +710,9 @@ void LiveInterval::constructMainRangeFromSubranges(
BEGIN_SEGMENT,
END_SEGMENT,
} Event = NOTHING;
+ // Which subregister lanes are affected by the current event.
unsigned EventMask = 0;
+ // Whether a BEGIN_SEGMENT is also a valno definition point.
bool IsDef = false;
// 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
@@ -698,6 +720,8 @@ void LiveInterval::constructMainRangeFromSubranges(
for (auto &SRP : SRs) {
const SubRange &SR = *SRP.first;
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() &&
(I->end < Pos ||
(I->end == Pos && (ActiveMask & SR.LaneMask) == 0)))
@@ -706,7 +730,7 @@ void LiveInterval::constructMainRangeFromSubranges(
continue;
if ((ActiveMask & SR.LaneMask) == 0 &&
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) {
EventMask |= SR.LaneMask;
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
// block containing the definition comes after a segment using the valno.
// Do a fixup pass for this uncommon case.
- if (NeedVNIFixup) {
- SmallPtrSet<const MachineBasicBlock*, 5> Visited;
- 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();
- 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);
+ if (NeedVNIFixup)
+ determineMissingVNIs(Indexes, *this);
+
+ assert(ActiveMask == 0 && !ConstructingSegment && "all segments ended");
verify();
}