Пример #1
0
        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);
        }
Пример #2
0
        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));
        }
Пример #3
0
        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);
        }
Пример #4
0
        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));
            }
        }
Пример #5
0
        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);
        }
Пример #6
0
        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;
        }
Пример #7
0
        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;
            }
        }
Пример #8
0
        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));
            }
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
        }
Пример #11
0
        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;
        }
Пример #12
0
        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);
        }
Пример #13
0
 public void Reset()
 {
     PrevRange = default;
     CurrRange = FirstRange;
 }