Ejemplo n.º 1
0
        private bool IntervalSplitAtFirstUseOrDef(LiveInterval liveInterval)
        {
            // last resort

            if (liveInterval.IsEmpty)
                return false;

            SlotIndex at;

            var firstUse = liveInterval.UsePositions.Count != 0 ? liveInterval.UsePositions[0] : null;
            var firstDef = liveInterval.DefPositions.Count != 0 ? liveInterval.DefPositions[0] : null;

            at = firstDef;

            if (at == null)
                at = firstUse;
            else if (firstUse != null && firstUse < at)
                at = firstUse;

            var atNext = at.Next;

            if (liveInterval.Start == at && liveInterval.End == atNext)
            {
                if (trace.Active) trace.Log("  Interval already smallest");
                return false;
            }

            if (trace.Active) trace.Log(" Splitting around first use/def");

            var virtualRegister = liveInterval.VirtualRegister;

            virtualRegister.Remove(liveInterval);

            if (liveInterval.Start != at)
            {
                var first = liveInterval.Split(liveInterval.Start, at);
                CalculateSpillCost(first);
                virtualRegister.Add(first);
                AddPriorityQueue(first);
                if (trace.Active) trace.Log("  First Split : " + first.ToString());
            }

            var middle = liveInterval.Split(at, atNext);
            CalculateSpillCost(middle);
            virtualRegister.Add(middle);
            AddPriorityQueue(middle);
            if (trace.Active) trace.Log("  Middle Split: " + middle.ToString());

            if (liveInterval.End != atNext)
            {
                var last = liveInterval.Split(atNext, liveInterval.End);
                CalculateSpillCost(last);
                virtualRegister.Add(last);
                AddPriorityQueue(last);
                if (trace.Active) trace.Log("  Last Split  : " + last.ToString());
            }

            return true;
        }
Ejemplo n.º 2
0
        private bool TrySimplePartialFreeIntervalSplit(LiveInterval liveInterval)
        {
            SlotIndex furthestUsed = null;

            foreach (var track in liveIntervalTracks)
            {
                if (track.IsReserved)
                    continue;

                if (track.IsFloatingPoint != liveInterval.VirtualRegister.IsFloatingPoint)
                    continue;

                var next = track.GetNextLiveRange(liveInterval.Start);

                if (next == null)
                    continue;

                Debug.Assert(next > liveInterval.Start);

                if (trace.Active) trace.Log("  Register " + track.ToString() + " free up to " + next.ToString());

                if (furthestUsed == null || furthestUsed < next)
                    furthestUsed = next;
            }

            if (furthestUsed == null)
            {
                if (trace.Active) trace.Log("  No partial free space available");
                return false;
            }

            if (furthestUsed < liveInterval.Minimum)
            {
                if (trace.Active) trace.Log("  No partial free space available");
                return false;
            }

            //Debug.Assert(!furthestUsed.IsBlockStartInstruction);
            if (furthestUsed.IsBlockStartInstruction)
            {
                return false;
            }

            var lastFree = furthestUsed.Previous;

            if (lastFree <= liveInterval.Start)
            {
                if (trace.Active) trace.Log("  No partial free space available");
                return false;
            }

            if (trace.Active) trace.Log("  Partial free up to: " + furthestUsed.ToString());

            var low = GetLowOptimalSplitLocation(liveInterval, lastFree, true);
            var high = GetHighOptimalSplitLocation(liveInterval, lastFree, true);

            var first = liveInterval.Split(liveInterval.Start, low);
            var last = liveInterval.Split(high, liveInterval.End);
            var middle = (low != high) ? liveInterval.Split(low, high) : null;

            if (trace.Active) trace.Log("  Low Split   : " + first.ToString());
            if (trace.Active) trace.Log("  Middle Split: " + (middle == null ? "n/a" : middle.ToString()));
            if (trace.Active) trace.Log("  High Split  : " + last.ToString());

            var virtualRegister = liveInterval.VirtualRegister;

            CalculateSpillCost(first);
            CalculateSpillCost(last);

            virtualRegister.Remove(liveInterval);
            virtualRegister.Add(first);
            virtualRegister.Add(last);

            AddPriorityQueue(first);
            AddPriorityQueue(last);

            if (middle != null)
            {
                //middle.ForceSpilled = true;
                CalculateSpillCost(middle);
                virtualRegister.Add(middle);
                AddPriorityQueue(middle);
            }

            return true;
        }