Ejemplo n.º 1
0
        private bool PlaceLiveIntervalOnTrack(LiveInterval liveInterval, MoveHint[] hints)
        {
            if (hints == null)
            {
                return(false);
            }

            foreach (var moveHint in hints)
            {
                var register = (liveInterval.Start == moveHint.Slot) ? moveHint.FromRegister : moveHint.ToRegister;

                if (register == null)
                {
                    continue;                       // no usable hint
                }
                Trace?.Log($"  Trying move hint: {register}  [ {moveHint} ]");

                if (PlaceLiveIntervalOnTrack(liveInterval, LiveIntervalTracks[register.Index]))
                {
                    return(true);
                }
            }

            return(false);
        }
        private bool PlaceLiveIntervalOnTrack(LiveInterval liveInterval, MoveHint[] hints)
        {
            if (hints == null)
            {
                return(false);
            }

            foreach (var moveHint in hints)
            {
                LiveIntervalTrack track = null;

                var register = (liveInterval.Start == moveHint.Slot) ? moveHint.FromRegister : moveHint.ToRegister;

                if (register == null)
                {
                    continue;                       // no usable hint
                }
                if (Trace.Active)
                {
                    Trace.Log("  Trying move hint: " + register + "  [ " + moveHint + " ]");
                }

                if (PlaceLiveIntervalOnTrack(liveInterval, LiveIntervalTracks[register.Index]))
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 3
0
        protected override bool TrySplitInterval(LiveInterval liveInterval, int level)
        {
            //if (level <= 1)
            //	return false;

            if (liveInterval.IsEmpty)
            {
                return(false);
            }

            if (TrySimplePartialFreeIntervalSplit(liveInterval))
            {
                return(true);
            }

            if (level <= 1)
            {
                return(false);
            }

            //if (IntervalSplitAtFirstUseOrDef(liveInterval))
            //	return true;

            return(false);
        }
Ejemplo n.º 4
0
        public void Add(LiveInterval liveInterval)
        {
            Debug.Assert(!Intersects(liveInterval));

            liveIntervals.Add(liveInterval);

            liveInterval.LiveIntervalTrack = this;
        }
Ejemplo n.º 5
0
        public void Evict(LiveInterval liveInterval)
        {
            intervals.Remove(liveInterval.StartValue, liveInterval.EndValue);

            Debug.Assert(!intervals.Contains(liveInterval.StartValue, liveInterval.EndValue));

            liveInterval.LiveIntervalTrack = null;
        }
Ejemplo n.º 6
0
        public void Add(LiveInterval liveInterval)
        {
            Debug.Assert(!intervals.Contains(liveInterval.StartValue, liveInterval.EndValue));

            intervals.Add(liveInterval.StartValue, liveInterval.EndValue, liveInterval);

            liveInterval.LiveIntervalTrack = this;
        }
Ejemplo n.º 7
0
        public void Add(LiveInterval liveInterval)
        {
            Debug.Assert(!Intersects(liveInterval));

            liveIntervals.Add(liveInterval);

            liveInterval.LiveIntervalTrack = this;
        }
Ejemplo n.º 8
0
        public LiveInterval CreateExpandedLiveInterval(LiveInterval interval)
        {
            Debug.Assert(VirtualRegister == interval.VirtualRegister);

            var start = Start < interval.Start ? Start : interval.Start;
            var end   = End > interval.End ? End : interval.End;

            return(new LiveInterval(VirtualRegister, start, end));
        }
Ejemplo n.º 9
0
        public void ReplaceWithSplit(LiveInterval source, IList <LiveInterval> liveIntervals)
        {
            Remove(source);

            foreach (var liveInterval in liveIntervals)
            {
                Add(liveInterval);
            }
        }
        private void UpdateMoveHints(LiveInterval liveInterval)
        {
            if (moveHints.TryGetValue(liveInterval.Start, out MoveHint MoveHint))
            {
                MoveHint.Update(liveInterval);
            }

            if (moveHints.TryGetValue(liveInterval.End, out MoveHint))
            {
                MoveHint.Update(liveInterval);
            }
        }
Ejemplo n.º 11
0
        public bool Intersects(LiveInterval liveInterval)
        {
            foreach (var interval in liveIntervals)
            {
                if (interval.Intersects(liveInterval))
                {
                    return(true);
                }
            }

            return(false);
        }
        private SlotIndex GetLowerOptimalSplitLocation(LiveInterval liveInterval, SlotIndex at)
        {
            if (Trace.Active)
            {
                Trace.Log("--Low Splitting: " + liveInterval + " move: " + at);
            }

            //a = liveInterval.Start.IsOnHalfStep ? liveInterval.Start : liveInterval.Start.HalfStepForward;
            var a = liveInterval.Start;

            var blockStart = GetBlockStart(at);
            var b          = blockStart > liveInterval.Start ? blockStart : null;

            if (Trace.Active)
            {
                Trace.Log("   Block Start : " + (b != null ? b.ToString() : "null"));
            }

            var c = liveInterval.LiveRange.GetPreviousUsePosition(at);

            if (c != null && c.HalfStepForward <= at)
            {
                c = c.HalfStepForward;
            }

            if (Trace.Active)
            {
                Trace.Log("  Previous Use : " + (c != null ? c.ToString() : "null"));
            }

            var d = liveInterval.LiveRange.GetPreviousDefPosition(at);

            if (d != null && d.HalfStepForward <= at)
            {
                d = d.HalfStepForward;
            }

            if (Trace.Active)
            {
                Trace.Log("  Previous Def : " + (d != null ? d.ToString() : "null"));
            }

            var max = GetMaximum(a, b, c, d);

            if (Trace.Active)
            {
                Trace.Log("   Low Optimal : " + max);
            }

            return(max);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Gets the intersections.
        /// </summary>
        /// <param name="liveInterval">The live interval.</param>
        /// <returns></returns>
        public List <LiveInterval> GetIntersections(LiveInterval liveInterval)
        {
            List <LiveInterval> intersections = null;

            foreach (var interval in liveIntervals)
            {
                if (interval.Intersects(liveInterval))
                {
                    (intersections ?? (intersections = new List <LiveInterval>())).Add(interval);
                }
            }

            return(intersections);
        }
Ejemplo n.º 14
0
        public void Update(LiveInterval interval)
        {
            var updateInterval = interval.AssignedPhysicalRegister == null ? null : interval;

            if (interval.VirtualRegister == From)
            {
                FromInterval = updateInterval;
            }

            if (interval.VirtualRegister == To)
            {
                ToInterval = updateInterval;
            }
        }
        private MoveHint[] GetMoveHints(LiveInterval liveInterval)
        {
            MoveHint startMoveHint = null;
            MoveHint endMoveHint   = null;

            moveHints.TryGetValue(liveInterval.Start, out startMoveHint);

            if (!liveInterval.End.IsBlockStartInstruction)
            {
                moveHints.TryGetValue(liveInterval.End, out endMoveHint);
            }

            int cnt = (startMoveHint == null ? 0 : 1) + (endMoveHint == null ? 0 : 1);

            if (cnt == 0)
            {
                return(null);
            }

            var hints = new MoveHint[cnt];

            if (startMoveHint != null && endMoveHint != null)
            {
                // sorted by bonus
                if (startMoveHint.Bonus > endMoveHint.Bonus)
                {
                    hints[0] = startMoveHint;
                    hints[1] = endMoveHint;
                }
                else
                {
                    hints[0] = endMoveHint;
                    hints[1] = startMoveHint;
                }
            }
            else
            {
                if (startMoveHint != null)
                {
                    hints[0] = startMoveHint;
                }
                else
                {
                    hints[0] = endMoveHint;
                }
            }

            return(hints);
        }
        protected override bool PlaceLiveInterval(LiveInterval liveInterval)
        {
            // For now, empty intervals will stay spilled
            if (liveInterval.IsEmpty)
            {
                if (Trace.Active)
                {
                    Trace.Log("  Spilled");
                }

                liveInterval.VirtualRegister.IsSpilled = true;
                AddSpilledInterval(liveInterval);

                return(true);
            }

            var moveHints = GetMoveHints(liveInterval);

            // Try to place using move hints first
            if (PlaceLiveIntervalOnTrack(liveInterval, moveHints))
            {
                UpdateMoveHints(liveInterval, moveHints);
                return(true);
            }

            // TODO - try move hints first, allow evictions

            // Find any available track and place interval there
            if (PlaceLiveIntervalOnAnyAvailableTrack(liveInterval))
            {
                UpdateMoveHints(liveInterval, moveHints);
                return(true);
            }

            if (Trace.Active)
            {
                Trace.Log("  No free register available");
            }

            // No place for live interval; find live interval(s) to evict based on spill costs
            if (PlaceLiveIntervalOnTrackAllowEvictions(liveInterval))
            {
                UpdateMoveHints(liveInterval, moveHints);
                return(true);
            }

            return(false);
        }
Ejemplo n.º 17
0
        private void UpdateMoveHints(LiveInterval liveInterval, MoveHint[] moveHints)
        {
            if (moveHints == null)
            {
                return;
            }

            if (moveHints.Length >= 1)
            {
                moveHints[0].Update(liveInterval);
            }
            else if (moveHints.Length >= 2)
            {
                moveHints[1].Update(liveInterval);
            }
        }
Ejemplo n.º 18
0
        protected override void CalculateSpillCost(LiveInterval liveInterval)
        {
            int spillvalue = 0;

            foreach (var use in liveInterval.UsePositions)
            {
                spillvalue += GetSpillCost(use, 100);
            }

            foreach (var use in liveInterval.DefPositions)
            {
                spillvalue += GetSpillCost(use, 115);
            }

            liveInterval.SpillValue = spillvalue;
        }
        protected override void CalculateSpillCost(LiveInterval liveInterval)
        {
            int spillvalue = 0;

            foreach (var use in liveInterval.UsePositions)
            {
                spillvalue += GetSpillCost(use, 100);
            }

            foreach (var use in liveInterval.DefPositions)
            {
                spillvalue += GetSpillCost(use, 115);
            }

            liveInterval.SpillValue = spillvalue;
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Gets the intersections.
        /// </summary>
        /// <param name="liveInterval">The live interval.</param>
        /// <returns></returns>
        public List<LiveInterval> GetIntersections(LiveInterval liveInterval)
        {
            List<LiveInterval> intersections = null;

            foreach (var interval in liveIntervals)
            {
                if (interval.Intersects(liveInterval))
                {
                    if (intersections == null)
                        intersections = new List<LiveInterval>();

                    intersections.Add(interval);
                }
            }

            return intersections;
        }
        private SlotIndex GetUpperOptimalSplitLocation(LiveInterval liveInterval, SlotIndex at)
        {
            if (Trace.Active)
            {
                Trace.Log("--High Splitting: " + liveInterval + " move: " + at);
            }

            var a = liveInterval.End;

            var blockEnd = GetBlockEnd(at);
            var b        = blockEnd > liveInterval.End ? blockEnd : null;

            if (Trace.Active)
            {
                Trace.Log("     Block End : " + (b != null ? b.ToString() : "null"));
            }

            var c = liveInterval.LiveRange.GetNextUsePosition(at);

            if (c != null && c.HalfStepBack > at)
            {
                c = c.HalfStepBack;
            }

            if (Trace.Active)
            {
                Trace.Log("      Next Use : " + (c != null ? c.ToString() : "null"));
            }

            var d = liveInterval.LiveRange.GetNextDefPosition(at);

            if (Trace.Active)
            {
                Trace.Log("      Next Def : " + (d != null ? d.ToString() : "null"));
            }

            var min = GetMinimum(a, b, c, d);

            if (Trace.Active)
            {
                Trace.Log("  High Optimal : " + min);
            }

            return(min);
        }
Ejemplo n.º 22
0
        private bool PreferBlockBoundaryIntervalSplit(LiveInterval liveInterval, SlotIndex at, bool addToQueue)
        {
            var low  = GetLowerOptimalSplitLocation(liveInterval, at);
            var high = GetUpperOptimalSplitLocation(liveInterval, at);

            List <LiveInterval> intervals;

            if (low.IsNull && high.IsNotNull)
            {
                if (!liveInterval.LiveRange.CanSplitAt(high))
                {
                    return(false);
                }

                intervals = liveInterval.SplitAt(high);
            }
            else if (high.IsNull && low.IsNotNull)
            {
                if (!liveInterval.LiveRange.CanSplitAt(low))
                {
                    return(false);
                }

                intervals = liveInterval.SplitAt(low);
            }
            else if (low.IsNotNull && high.IsNotNull)
            {
                if (!liveInterval.LiveRange.CanSplitAt(low, high))
                {
                    return(false);
                }

                intervals = liveInterval.SplitAt(low, high);
            }
            else
            {
                return(false);
            }

            ReplaceIntervals(liveInterval, intervals, addToQueue);

            return(true);
        }
Ejemplo n.º 23
0
        protected override bool PlaceLiveInterval(LiveInterval liveInterval)
        {
            // For now, empty intervals will stay spilled
            if (liveInterval.IsEmpty)
            {
                if (Trace.Active) Trace.Log("  Spilled");

                liveInterval.VirtualRegister.IsSpilled = true;
                AddSpilledInterval(liveInterval);

                return true;
            }

            var moveHints = GetMoveHints(liveInterval);

            // Try to place using move hints first
            if (PlaceLiveIntervalOnTrack(liveInterval, moveHints))
            {
                UpdateMoveHints(liveInterval, moveHints);
                return true;
            }

            // TODO - try move hints first, allow evictions

            // Find any available track and place interval there
            if (PlaceLiveIntervalOnAnyAvailableTrack(liveInterval))
            {
                UpdateMoveHints(liveInterval, moveHints);
                return true;
            }

            if (Trace.Active) Trace.Log("  No free register available");

            // No place for live interval; find live interval(s) to evict based on spill costs
            if (PlaceLiveIntervalOnTrackAllowEvictions(liveInterval))
            {
                UpdateMoveHints(liveInterval, moveHints);
                return true;
            }

            return false;
        }
        private bool IntervalSplitAtFirstUseOrDef(LiveInterval liveInterval)
        {
            if (liveInterval.IsEmpty)
            {
                return(false);
            }

            SlotIndex at = null;

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

            if (at == null)
            {
                at = firstUse;
            }

            if (at != null && firstDef != null && firstDef < at)
            {
                at = firstDef;
            }

            if (at >= liveInterval.End)
            {
                return(false);
            }

            if (at <= liveInterval.Start)
            {
                return(false);
            }

            if (Trace.Active)
            {
                Trace.Log(" Splitting around first use/def");
            }

            return(PreferBlockBoundaryIntervalSplit(liveInterval, at, true));
        }
Ejemplo n.º 25
0
        private SlotIndex GetLowerOptimalSplitLocation(LiveInterval liveInterval, SlotIndex at)
        {
            Trace?.Log($"--Low Splitting: {liveInterval} at: {at}");

            var max = SlotIndex.NullSlot;

            var blockStart = GetBlockStart(at);

            Trace?.Log($"   Block Start : {blockStart}");

            if (blockStart < at && blockStart > liveInterval.Start)
            {
                max = blockStart;
            }

            var prevUse = liveInterval.LiveRange.GetPreviousUsePosition(at);

            Trace?.Log($"  Previous Use : {prevUse}");

            if (prevUse.IsNotNull && prevUse.After < at && (max.IsNull || prevUse.After > max))
            {
                max = prevUse.After;
            }

            var prevDef = liveInterval.LiveRange.GetPreviousDefPosition(at);

            Trace?.Log($"  Previous Def : {prevDef}");

            if (prevDef.IsNotNull && prevDef.After < at && (max.IsNull || prevDef.After > max))
            {
                max = prevDef.After;
            }

            Trace?.Log($"   Low Optimal : {max}");

            return(max);
        }
Ejemplo n.º 26
0
        private SlotIndex GetUpperOptimalSplitLocation(LiveInterval liveInterval, SlotIndex at)
        {
            Trace?.Log($"--High Splitting: {liveInterval} at: {at}");

            var min = SlotIndex.NullSlot;

            var blockEnd = GetBlockEnd(at);

            Trace?.Log($"     Block End : {blockEnd}");

            if (blockEnd > at && blockEnd < liveInterval.End)
            {
                min = blockEnd;
            }

            var nextUse = liveInterval.LiveRange.GetNextUsePosition(at);

            Trace?.Log($"      Next Use : {nextUse}");

            if (nextUse.IsNotNull && nextUse.Before > at && (min.IsNull || nextUse.Before < min))
            {
                min = nextUse.Before;
            }

            var nextDef = liveInterval.LiveRange.GetNextDefPosition(at);

            Trace?.Log($"      Next Def : {nextDef}");

            if (nextDef.IsNotNull && nextDef > at && (min.IsNull || nextDef < min))
            {
                min = nextDef;
            }

            Trace?.Log($"  High Optimal : {min}");

            return(min);
        }
Ejemplo n.º 27
0
        private bool IntervalSplitAtFirstUseOrDef(LiveInterval liveInterval)
        {
            if (liveInterval.IsEmpty)
            {
                return(false);
            }

            var at = SlotIndex.NullSlot;

            var firstUse = liveInterval.LiveRange.FirstUse;
            var firstDef = liveInterval.LiveRange.FirstDef;

            if (at.IsNull)
            {
                at = firstUse;
            }

            if (at.IsNotNull && firstDef.IsNotNull && firstDef < at)
            {
                at = firstDef;
            }

            if (at >= liveInterval.End)
            {
                return(false);
            }

            if (at <= liveInterval.Start)
            {
                return(false);
            }

            Trace?.Log(" Splitting around first use/def");

            return(PreferBlockBoundaryIntervalSplit(liveInterval, at, true));
        }
Ejemplo n.º 28
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;
        }
Ejemplo n.º 29
0
 public void Remove(LiveInterval liveInterval)
 {
     LiveIntervals.Remove(liveInterval);
 }
Ejemplo n.º 30
0
 public bool IsAdjacent(LiveInterval other)
 {
     return LiveRange.IsAdjacent(other.LiveRange);
 }
Ejemplo n.º 31
0
        public LiveInterval CreateExpandedLiveInterval(LiveInterval interval)
        {
            Debug.Assert(VirtualRegister == interval.VirtualRegister);

            var start = Start < interval.Start ? Start : interval.Start;
            var end = End > interval.End ? End : interval.End;

            return new LiveInterval(VirtualRegister, start, end);
        }
Ejemplo n.º 32
0
        private bool PreferBlockBoundaryIntervalSplit(LiveInterval liveInterval, SlotIndex at, bool addToQueue)
        {
            var low = GetLowerOptimalSplitLocation(liveInterval, at);
            var high = GetUpperOptimalSplitLocation(liveInterval, at);

            IList<LiveInterval> intervals;

            if (liveInterval.Start == low)
            {
                if (!liveInterval.LiveRange.CanSplitAt(high))
                    return false;

                intervals = liveInterval.SplitAt(high);
            }
            else if (high == liveInterval.End)
            {
                if (!liveInterval.LiveRange.CanSplitAt(low))
                    return false;

                intervals = liveInterval.SplitAt(low);
            }
            else
            {
                if (!liveInterval.LiveRange.CanSplitAt(low, high))
                {
                    return false;
                }

                intervals = liveInterval.SplitAt(low, high);
            }

            ReplaceIntervals(liveInterval, intervals, addToQueue);

            return true;
        }
Ejemplo n.º 33
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;
            }

            if (furthestUsed.IsBlockStartInstruction)
            {
                return false;
            }

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

            if (Trace.Active) Trace.Log("  Partial free up destination: " + furthestUsed.ToString());

            if (liveInterval.UsePositions.Contains(furthestUsed) && liveInterval.Contains(furthestUsed.HalfStepBack))
                furthestUsed = furthestUsed.HalfStepBack;

            return PreferBlockBoundaryIntervalSplit(liveInterval, furthestUsed, true);
        }
Ejemplo n.º 34
0
        private void UpdateMoveHints(LiveInterval liveInterval, MoveHint[] moveHints)
        {
            if (moveHints == null)
                return;

            if (moveHints.Length >= 1)
                moveHints[0].Update(liveInterval);
            else
                if (moveHints.Length >= 2)
                    moveHints[1].Update(liveInterval);
        }
Ejemplo n.º 35
0
        private SlotIndex GetLowOptimalSplitLocation(LiveInterval liveInterval, SlotIndex from, bool check)
        {
            Debug.Assert(liveInterval.Start != from);

            if (trace.Active) trace.Log("--Low Splitting: " + liveInterval.ToString() + " move: " + from.ToString());

            if (check)
            {
                if (liveInterval.UsePositions.Contains(from) || liveInterval.DefPositions.Contains(from))
                {
                    if (trace.Active) trace.Log("  No optimal. Split move: " + from.ToString());
                    return from;
                }
            }

            SlotIndex blockStart = GetBlockStart(from);
            if (trace.Active) trace.Log("  Block Start : " + blockStart.ToString());

            SlotIndex lowerBound = blockStart > liveInterval.Start ? blockStart : liveInterval.Start.Next;
            if (trace.Active) trace.Log("  Lower Bound : " + lowerBound.ToString());

            SlotIndex previousUse = liveInterval.GetPreviousDefOrUsePosition(from);
            if (trace.Active) trace.Log("  Previous Use: " + (previousUse != null ? previousUse.ToString() : "null"));

            if (previousUse != null && previousUse >= lowerBound)
            {
                if (trace.Active) trace.Log("  Low Optimal : " + previousUse.Next.ToString());
                return previousUse.Next;
            }

            if (trace.Active) trace.Log("  Low Optimal : " + lowerBound.ToString());
            return lowerBound;
        }
Ejemplo n.º 36
0
        private MoveHint[] GetMoveHints(LiveInterval liveInterval)
        {
            MoveHint startMoveHint = null;
            MoveHint endMoveHint = null;
            moveHints.TryGetValue(liveInterval.Start, out startMoveHint);

            if (!liveInterval.End.IsBlockStartInstruction)
                moveHints.TryGetValue(liveInterval.End.Previous, out endMoveHint);

            int cnt = (startMoveHint == null ? 0 : 1) + (endMoveHint == null ? 0 : 1);

            if (cnt == 0)
                return null;

            MoveHint[] hints = new MoveHint[cnt];

            if (startMoveHint != null && endMoveHint != null)
            {
                // sorted by bonus
                if (startMoveHint.Bonus > endMoveHint.Bonus)
                {
                    hints[0] = startMoveHint;
                    hints[1] = endMoveHint;
                }
                else
                {
                    hints[0] = endMoveHint;
                    hints[1] = startMoveHint;
                }
            }
            else
            {
                if (startMoveHint != null)
                {
                    hints[0] = startMoveHint;
                }
                else
                {
                    hints[0] = endMoveHint;
                }
            }

            return hints;
        }
Ejemplo n.º 37
0
 protected override bool TrySplitInterval(LiveInterval liveInterval, int level)
 {
     return false;
 }
Ejemplo n.º 38
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.º 39
0
        private bool PlaceLiveIntervalOnTrackAllowEvictions(LiveInterval liveInterval)
        {
            // find live interval(s) to evict based on spill costs
            foreach (var track in liveIntervalTracks)
            {
                if (track.IsReserved)
                    continue;

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

                var intersections = track.GetIntersections(liveInterval);

                bool evict = true;

                foreach (var intersection in intersections)
                {
                    if (intersection.SpillCost >= liveInterval.SpillCost || intersection.SpillCost == Int32.MaxValue || intersection.VirtualRegister.IsPhysicalRegister || intersection.IsPhysicalRegister)
                    {
                        evict = false;
                        break;
                    }
                }

                if (evict)
                {
                    if (intersections.Count != 0)
                    {
                        if (trace.Active) trace.Log("  Evicting live intervals");

                        track.Evict(intersections);

                        foreach (var intersection in intersections)
                        {
                            if (trace.Active) trace.Log("  Evicted: " + intersection.ToString());

                            liveInterval.Stage = LiveInterval.AllocationStage.Initial;
                            AddPriorityQueue(intersection);
                        };
                    }

                    track.Add(liveInterval);

                    if (trace.Active) trace.Log("  Assigned live interval to: " + track.ToString());

                    return true;
                }
            }

            return false;
        }
Ejemplo n.º 40
0
        private bool PlaceLiveIntervalOnTrack(LiveInterval liveInterval, MoveHint[] hints)
        {
            if (hints == null)
                return false;

            foreach (var moveHint in hints)
            {
                LiveIntervalTrack track = null;

                var register = (liveInterval.Start == moveHint.Slot) ? moveHint.FromRegister : moveHint.ToRegister;

                if (register == null)
                    continue;	// no usable hint

                if (trace.Active) trace.Log("  Trying move hint: " + register.ToString() + "  [ " + moveHint.ToString() + " ]");

                if (PlaceLiveIntervalOnTrack(liveInterval, liveIntervalTracks[register.Index]))
                {
                    return true;
                }
            }

            return false;
        }
Ejemplo n.º 41
0
        private bool PlaceLiveIntervalOnTrack(LiveInterval liveInterval, LiveIntervalTrack track)
        {
            if (track.IsReserved)
                return false;

            if (track.IsFloatingPoint != liveInterval.VirtualRegister.IsFloatingPoint)
                return false;

            if (track.Intersects(liveInterval))
                return false;

            if (trace.Active) trace.Log("  Assigned live interval to: " + track.ToString());

            track.Add(liveInterval);

            return true;
        }
Ejemplo n.º 42
0
 protected virtual void SplitIntervalAtCallSite(LiveInterval liveInterval, SlotIndex callSite)
 {
 }
Ejemplo n.º 43
0
 protected override int CalculatePriorityValue(LiveInterval liveInterval)
 {
     return liveInterval.Length | ((int)(((int)LiveInterval.AllocationStage.Max - liveInterval.Stage)) << 28);
 }
 protected override bool TrySplitInterval(LiveInterval liveInterval, int level)
 {
     return(false);
 }
Ejemplo n.º 45
0
        private bool TrySplitInterval(LiveInterval liveInterval, int level)
        {
            if (liveInterval.IsEmpty)
                return false;

            if (TrySimplePartialFreeIntervalSplit(liveInterval))
                return true;

            if (level <= 1)
                return false;

            if (IntervalSplitAtFirstUseOrDef(liveInterval))
                return true;

            return false;
        }
Ejemplo n.º 46
0
 private void AddPriorityQueue(LiveInterval liveInterval)
 {
     // priority is based on allocation stage (primary, lower first) and interval size (secondary, higher first)
     priorityQueue.Enqueue(liveInterval.Length | ((int)(((int)LiveInterval.AllocationStage.Max - liveInterval.Stage)) << 28), liveInterval);
 }
Ejemplo n.º 47
0
        public void Evict(LiveInterval liveInterval)
        {
            liveIntervals.Remove(liveInterval);

            liveInterval.LiveIntervalTrack = null;
        }
Ejemplo n.º 48
0
        public void Update(LiveInterval interval)
        {
            LiveInterval updateInterval = interval.AssignedPhysicalRegister == null ? null : interval;

            if (interval.VirtualRegister == From)
            {
                FromInterval = updateInterval;
            }

            if (interval.VirtualRegister == To)
            {
                ToInterval = updateInterval;
            }
        }
Ejemplo n.º 49
0
        private bool IntervalSplitAtFirstUseOrDef(LiveInterval liveInterval)
        {
            if (liveInterval.IsEmpty)
                return false;

            SlotIndex at = null;

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

            if (at == null)
            {
                at = firstUse;
            }

            if (at != null && firstDef != null && firstDef < at)
            {
                at = firstDef;
            }

            if (at >= liveInterval.End)
                return false;

            if (at <= liveInterval.Start)
                return false;

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

            return PreferBlockBoundaryIntervalSplit(liveInterval, at, true);
        }
Ejemplo n.º 50
0
        private SlotIndex GetHighOptimalSplitLocation(LiveInterval liveInterval, SlotIndex after, bool check)
        {
            Debug.Assert(liveInterval.End != after);

            if (trace.Active) trace.Log("--High Splitting: " + liveInterval.ToString() + " move: " + after.ToString());

            SlotIndex blockEnd = GetBlockEnd(after);
            if (trace.Active) trace.Log("  Block End   : " + blockEnd.ToString());

            SlotIndex higherBound = blockEnd < liveInterval.End ? blockEnd : liveInterval.End.Previous;
            if (trace.Active) trace.Log("  Higher Bound: " + higherBound.ToString());

            SlotIndex nextUse = liveInterval.GetNextDefOrUsePosition(after);
            if (trace.Active) trace.Log("  Next Use    : " + (nextUse != null ? nextUse.ToString() : "null"));

            if (nextUse != null && nextUse <= higherBound)
            {
                if (trace.Active) trace.Log("  High Optimal: " + nextUse.Previous.ToString());
                return nextUse;
            }

            if (trace.Active) trace.Log("  High Optimal: " + higherBound.ToString());
            return higherBound;
        }
Ejemplo n.º 51
0
 public bool Intersects(LiveInterval other)
 {
     return LiveRange.Intersects(other.LiveRange);
 }
Ejemplo n.º 52
0
 private SlotIndex FindCallSiteInInterval(LiveInterval liveInterval)
 {
     foreach (SlotIndex slot in callSlots)
     {
         if (liveInterval.Contains(slot))
             return slot;
     }
     return null;
 }
Ejemplo n.º 53
0
 public void Add(LiveInterval liveInterval)
 {
     LiveIntervals.Add(liveInterval);
 }
        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 + " free up to " + next);
                }

                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);
            }

            if (furthestUsed.IsBlockStartInstruction)
            {
                return(false);
            }

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

            if (Trace.Active)
            {
                Trace.Log("  Partial free up destination: " + furthestUsed);
            }

            if (liveInterval.UsePositions.Contains(furthestUsed) && liveInterval.Contains(furthestUsed.HalfStepBack))
            {
                furthestUsed = furthestUsed.HalfStepBack;
            }

            return(PreferBlockBoundaryIntervalSplit(liveInterval, furthestUsed, true));
        }
Ejemplo n.º 55
0
        private SlotIndex GetUpperOptimalSplitLocation(LiveInterval liveInterval, SlotIndex at)
        {
            if (Trace.Active) Trace.Log("--High Splitting: " + liveInterval.ToString() + " move: " + at.ToString());

            var a = liveInterval.End;

            var blockEnd = GetBlockEnd(at);
            var b = blockEnd > liveInterval.End ? blockEnd : null;
            if (Trace.Active) Trace.Log("     Block End : " + (b != null ? b.ToString() : "null"));

            var c = liveInterval.LiveRange.GetNextUsePosition(at);
            if (c != null && c.HalfStepBack > at)
                c = c.HalfStepBack;
            if (Trace.Active) Trace.Log("      Next Use : " + (c != null ? c.ToString() : "null"));

            var d = liveInterval.LiveRange.GetNextDefPosition(at);
            if (Trace.Active) Trace.Log("      Next Def : " + (d != null ? d.ToString() : "null"));

            var min = GetMinimum(a, b, c, d);

            if (Trace.Active) Trace.Log("  High Optimal : " + min.ToString());

            return min;
        }
Ejemplo n.º 56
0
        private void UpdateMoveHints(LiveInterval liveInterval)
        {
            MoveHint MoveHint = null;

            if (moveHints.TryGetValue(liveInterval.Start, out MoveHint))
            {
                MoveHint.Update(liveInterval);
            }

            if (moveHints.TryGetValue(liveInterval.End, out MoveHint))
            {
                MoveHint.Update(liveInterval);
            }
        }
 protected override int CalculatePriorityValue(LiveInterval liveInterval)
 {
     return(liveInterval.Length | ((int)(((int)LiveInterval.AllocationStage.Max - liveInterval.Stage)) << 28));
 }
Ejemplo n.º 58
0
        private bool PlaceLiveIntervalOnAnyAvailableTrack(LiveInterval liveInterval)
        {
            foreach (var track in liveIntervalTracks)
            {
                if (PlaceLiveIntervalOnTrack(liveInterval, track))
                {
                    return true;
                }
            }

            return false;
        }
 protected virtual void SplitIntervalAtCallSite(LiveInterval liveInterval, SlotIndex callSite)
 {
 }
Ejemplo n.º 60
0
        private void ProcessLiveInterval(LiveInterval liveInterval)
        {
            if (trace.Active)
            {
                trace.Log("Processing Interval: " + liveInterval.ToString() + " / Length: " + liveInterval.Length.ToString() + " / Spill Cost: " + liveInterval.SpillCost.ToString() + " / Stage: " + liveInterval.Stage.ToString());
                trace.Log("  Defs (" + liveInterval.DefPositions.Count.ToString() + "): " + SlotsToString(liveInterval.DefPositions));
                trace.Log("  Uses (" + liveInterval.UsePositions.Count.ToString() + "): " + SlotsToString(liveInterval.UsePositions));
            }

            if (liveInterval.ForceSpilled)
            {
                if (trace.Active) trace.Log("  Forced spilled interval");

                liveInterval.VirtualRegister.IsSpilled = true;
                spilledIntervals.Add(liveInterval);
                return;
            }

            // For now, empty intervals will stay spilled
            if (liveInterval.IsEmpty)
            {
                if (trace.Active) trace.Log("  Spilled");

                liveInterval.VirtualRegister.IsSpilled = true;
                spilledIntervals.Add(liveInterval);

                return;
            }

            var moveHints = GetMoveHints(liveInterval);

            // Try to place using move hints first
            if (PlaceLiveIntervalOnTrack(liveInterval, moveHints))
            {
                UpdateMoveHints(liveInterval, moveHints);
                return;
            }

            // TODO - try move hints first, allow evictions

            // Find any available track and place interval there
            if (PlaceLiveIntervalOnAnyAvailableTrack(liveInterval))
            {
                UpdateMoveHints(liveInterval, moveHints);
                return;
            }

            if (trace.Active) trace.Log("  No free register available");

            // No place for live interval; find live interval(s) to evict based on spill costs
            if (PlaceLiveIntervalOnTrackAllowEvictions(liveInterval))
            {
                UpdateMoveHints(liveInterval, moveHints);
                return;
            }

            if (trace.Active) trace.Log("  No live intervals to evicts");

            // No live intervals to evict!

            // prepare to split live interval
            if (liveInterval.Stage == LiveInterval.AllocationStage.Initial)
            {
                if (trace.Active) trace.Log("  Re-queued for split level 1 stage");
                liveInterval.Stage = LiveInterval.AllocationStage.SplitLevel1;
                AddPriorityQueue(liveInterval);
                return;
            }

            // split live interval - level 1
            if (liveInterval.Stage == LiveInterval.AllocationStage.SplitLevel1)
            {
                if (trace.Active) trace.Log("  Attempting to split interval - level 1");

                if (TrySplitInterval(liveInterval, 1))
                {
                    return;
                }

                // Move to split level 2 stage
                if (trace.Active) trace.Log("  Re-queued for split interval - level 2");

                liveInterval.Stage = LiveInterval.AllocationStage.SplitLevel2;
                AddPriorityQueue(liveInterval);
                return;
            }

            // split live interval - level 2
            if (liveInterval.Stage == LiveInterval.AllocationStage.SplitLevel2)
            {
                if (trace.Active) trace.Log("  Attempting to split interval - level 2");

                if (TrySplitInterval(liveInterval, 2))
                {
                    return;
                }

                // Move to spill stage
                if (trace.Active) trace.Log("  Re-queued for spillable stage");

                liveInterval.Stage = LiveInterval.AllocationStage.Spillable;
                AddPriorityQueue(liveInterval);
                return;
            }

            // spill interval to stack slot
            if (liveInterval.Stage == LiveInterval.AllocationStage.Spillable)
            {
                if (trace.Active) trace.Log("  Spilled interval");

                //liveInterval.Stage = LiveInterval.AllocationStage.Spilled
                liveInterval.VirtualRegister.IsSpilled = true;
                spilledIntervals.Add(liveInterval);

                return;
            }

            // TODO
            return;
        }