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