aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SplitKit.cpp15
-rw-r--r--lib/CodeGen/SplitKit.h15
2 files changed, 28 insertions, 2 deletions
diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp
index 4bf3a7a..89e85bd 100644
--- a/lib/CodeGen/SplitKit.cpp
+++ b/lib/CodeGen/SplitKit.cpp
@@ -317,6 +317,7 @@ void SplitEditor::reset(LiveRangeEdit &LRE, ComplementSpillMode SM) {
Edit = &LRE;
SpillMode = SM;
OpenIdx = 0;
+ OverlappedComplement.clear();
RegAssign.clear();
Values.clear();
@@ -391,6 +392,16 @@ void SplitEditor::markComplexMapped(unsigned RegIdx, const VNInfo *ParentVNI) {
VNI = 0;
}
+void SplitEditor::markOverlappedComplement(const VNInfo *ParentVNI) {
+ if (OverlappedComplement.insert(ParentVNI))
+ markComplexMapped(0, ParentVNI);
+}
+
+bool SplitEditor::needsRecompute(unsigned RegIdx, const VNInfo *ParentVNI) {
+ return (RegIdx == 0 && OverlappedComplement.count(ParentVNI)) ||
+ Edit->didRematerialize(ParentVNI);
+}
+
VNInfo *SplitEditor::defFromParent(unsigned RegIdx,
VNInfo *ParentVNI,
SlotIndex UseIdx,
@@ -575,7 +586,7 @@ void SplitEditor::overlapIntv(SlotIndex Start, SlotIndex End) {
// The complement interval will be extended as needed by LRCalc.extend().
if (ParentVNI)
- markComplexMapped(0, ParentVNI);
+ markOverlappedComplement(ParentVNI);
DEBUG(dbgs() << " overlapIntv [" << Start << ';' << End << "):");
RegAssign.insert(Start, End, OpenIdx);
DEBUG(dump());
@@ -623,7 +634,7 @@ bool SplitEditor::transferValues() {
// Skip rematerialized values, we need to use LRCalc.extend() and
// extendPHIKillRanges() to completely recompute the live ranges.
- if (Edit->didRematerialize(ParentVNI)) {
+ if (needsRecompute(RegIdx, ParentVNI)) {
DEBUG(dbgs() << "(remat)");
Skipped = true;
Start = End;
diff --git a/lib/CodeGen/SplitKit.h b/lib/CodeGen/SplitKit.h
index 1a4937c..5abdd4c 100644
--- a/lib/CodeGen/SplitKit.h
+++ b/lib/CodeGen/SplitKit.h
@@ -250,6 +250,10 @@ private:
/// The current spill mode, selected by reset().
ComplementSpillMode SpillMode;
+ /// Parent interval values where the complement interval may be overlapping
+ /// other intervals.
+ SmallPtrSet<const VNInfo*, 8> OverlappedComplement;
+
typedef IntervalMap<SlotIndex, unsigned> RegAssignMap;
/// Allocator for the interval map. This will eventually be shared with
@@ -296,6 +300,17 @@ private:
/// of the number of defs.
void markComplexMapped(unsigned RegIdx, const VNInfo *ParentVNI);
+ /// markOverlappedComplement - Mark ParentVNI as being overlapped in the
+ /// complement interval. The complement interval may overlap other intervals
+ /// after overlapIntv has been called, or when in spill mode.
+ void markOverlappedComplement(const VNInfo *ParentVNI);
+
+ /// needsRecompute - Returns true if the live range of ParentVNI needs to be
+ /// recomputed in RegIdx using LiveRangeCalc::extend. This is the case if
+ /// the value has been rematerialized, or when back-copies have been hoisted
+ /// in spill mode.
+ bool needsRecompute(unsigned RegIdx, const VNInfo *ParentVNI);
+
/// defFromParent - Define Reg from ParentVNI at UseIdx using either
/// rematerialization or a COPY from parent. Return the new value.
VNInfo *defFromParent(unsigned RegIdx,