public int GetOverlapPosition(LiveInterval other) { LiveRange a = CurrRange; LiveRange b = other.CurrRange; while (a != default) { while (b != default && b.Start < a.Start) { if (a.Overlaps(b)) { return(a.Start); } b = b.Next; } if (b == default) { break; } else if (a.Overlaps(b)) { return(a.Start); } a = a.Next; } return(NotFound); }
public void AddRange(int start, int end) { Debug.Assert(start < end, $"Invalid range start position {start}, {end}"); if (FirstRange != default) { // If the new range ends exactly where the first range start, then coalesce together. if (end == FirstRange.Start) { FirstRange.Start = start; return; } // If the new range is already contained, then coalesce together. else if (FirstRange.Overlaps(start, end)) { FirstRange.Start = Math.Min(FirstRange.Start, start); FirstRange.End = Math.Max(FirstRange.End, end); End = Math.Max(End, end); Debug.Assert(FirstRange.Next == default || !FirstRange.Overlaps(FirstRange.Next)); return; } } FirstRange = new LiveRange(start, end, FirstRange); End = Math.Max(End, end); Debug.Assert(FirstRange.Next == default || !FirstRange.Overlaps(FirstRange.Next)); }
public LiveInterval Split(int position) { LiveInterval right = new LiveInterval(Local, _parent); int splitIndex = 0; for (; splitIndex < _ranges.Count; splitIndex++) { LiveRange range = _ranges[splitIndex]; if (position > range.Start && position < range.End) { right._ranges.Add(new LiveRange(position, range.End)); range = new LiveRange(range.Start, position); _ranges[splitIndex++] = range; break; } if (range.Start >= position) { break; } } if (splitIndex < _ranges.Count) { int count = _ranges.Count - splitIndex; right._ranges.AddRange(_ranges.GetRange(splitIndex, count)); _ranges.RemoveRange(splitIndex, count); } int addAfter = _usePositions.FindLessEqualIndex(-position); for (int index = addAfter; index >= 0; index--) { int usePosition = _usePositions[index]; right._usePositions.Add(usePosition); } RemoveAfter(position); Debug.Assert(_ranges.Count != 0, "Left interval is empty after split."); Debug.Assert(right._ranges.Count != 0, "Right interval is empty after split."); AddSplitChild(right); return(right); }
public void SetStart(int position) { if (_ranges.Count != 0) { Debug.Assert(position != _ranges[0].End); _ranges[0] = new LiveRange(position, _ranges[0].End); } else { _ranges.Add(new LiveRange(position, position + 1)); } }
public LiveInterval Split(int position) { LiveInterval right = new LiveInterval(Local, _parent); int splitIndex = 0; for (; splitIndex < _ranges.Count; splitIndex++) { LiveRange range = _ranges[splitIndex]; if (position > range.Start && position <= range.End) { right._ranges.Add(new LiveRange(position, range.End)); range = new LiveRange(range.Start, position); _ranges[splitIndex++] = range; break; } if (range.Start >= position) { break; } } if (splitIndex < _ranges.Count) { int count = _ranges.Count - splitIndex; right._ranges.AddRange(_ranges.GetRange(splitIndex, count)); _ranges.RemoveRange(splitIndex, count); } foreach (int usePosition in _usePositions.Where(x => x >= position)) { right._usePositions.Add(usePosition); } _usePositions.RemoveWhere(x => x >= position); Debug.Assert(_ranges.Count != 0, "Left interval is empty after split."); Debug.Assert(right._ranges.Count != 0, "Right interval is empty after split."); AddSplitChild(right); return(right); }
public void Forward(int position) { LiveRange prev = PrevRange; LiveRange curr = CurrRange; while (curr != default && curr.Start < position && !curr.Overlaps(position)) { prev = curr; curr = curr.Next; } PrevRange = prev; CurrRange = curr; }
public void SetStart(int position) { if (FirstRange != default) { Debug.Assert(position != FirstRange.End); FirstRange.Start = position; } else { FirstRange = new LiveRange(position, position + 1); End = position + 1; } }
public void SetEnd(int position) { if (_ranges.Count != 0) { int lastIdx = _ranges.Count - 1; Debug.Assert(position != _ranges[lastIdx].Start); _ranges[lastIdx] = new LiveRange(_ranges[lastIdx].Start, position); } else { _ranges.Add(new LiveRange(position, position + 1)); } }
public bool Overlaps(int position) { LiveRange curr = CurrRange; while (curr != default && curr.Start <= position) { if (curr.Overlaps(position)) { return(true); } curr = curr.Next; } return(false); }
public LiveInterval Split(int position) { LiveInterval result = new(Local, Parent); result.End = End; LiveRange prev = PrevRange; LiveRange curr = CurrRange; while (curr != default && curr.Start < position && !curr.Overlaps(position)) { prev = curr; curr = curr.Next; } if (curr.Start >= position) { prev.Next = default; result.FirstRange = curr; End = prev.End; } else { result.FirstRange = new LiveRange(position, curr.End, curr.Next); curr.End = position; curr.Next = default; End = curr.End; } result.Uses = Uses.Split(position); AddSplitChild(result); Debug.Assert(!IsEmpty, "Left interval is empty after split."); Debug.Assert(!result.IsEmpty, "Right interval is empty after split."); // Make sure the iterator in the new split is pointing to the start. result.Reset(); return(result); }
public LiveInterval(Operand local = default, LiveInterval parent = default) { _data = Allocators.LiveIntervals.Allocate <Data>(); *_data = default; _data->IsFixed = false; _data->Local = local; Parent = parent == default ? this : parent; Uses = new UseList(); Children = new LiveIntervalList(); FirstRange = default; CurrRange = default; PrevRange = default; SpillOffset = -1; }
public int GetOverlapPosition(LiveInterval other) { foreach (LiveRange range in other._ranges) { int overlapIndex = _ranges.BinarySearch(range); if (overlapIndex >= 0) { // It's possible that we have multiple overlaps within a single interval, // in this case, we pick the one with the lowest start position, since // we return the first overlap position. while (overlapIndex > 0 && _ranges[overlapIndex - 1].End > range.Start) { overlapIndex--; } LiveRange overlappingRange = _ranges[overlapIndex]; return(overlappingRange.Start); } } return(NotFound); }
public void Reset() { PrevRange = default; CurrRange = FirstRange; }