@@ -38,7 +38,7 @@ pub struct CodeRange {
3838impl CodeRange {
3939 #[ inline( always) ]
4040 pub fn is_empty ( & self ) -> bool {
41- self . from = = self . to
41+ self . from > = self . to
4242 }
4343 #[ inline( always) ]
4444 pub fn contains ( & self , other : & Self ) -> bool {
@@ -64,6 +64,15 @@ impl CodeRange {
6464 to : pos. next ( ) ,
6565 }
6666 }
67+
68+ /// Join two [CodeRange] values together, producing a [CodeRange] that includes both.
69+ #[ inline( always) ]
70+ pub fn join ( & self , other : CodeRange ) -> Self {
71+ CodeRange {
72+ from : self . from . min ( other. from ) ,
73+ to : self . to . max ( other. to ) ,
74+ }
75+ }
6776}
6877
6978impl core:: cmp:: PartialOrd for CodeRange {
@@ -153,6 +162,9 @@ impl LiveRange {
153162 }
154163 #[ inline( always) ]
155164 pub fn uses_spill_weight ( & self ) -> SpillWeight {
165+ // NOTE: the spill weight is technically stored in 29 bits, but we ignore the sign bit as
166+ // we will always be dealing with positive values. Thus we mask out the top 3 bits to
167+ // ensure that the sign bit is clear, then shift left by only two.
156168 let bits = ( self . uses_spill_weight_and_flags & 0x1fff_ffff ) << 2 ;
157169 SpillWeight :: from_f32 ( f32:: from_bits ( bits) )
158170 }
@@ -285,17 +297,22 @@ const fn no_bloat_capacity<T>() -> usize {
285297
286298#[ derive( Clone , Debug ) ]
287299pub struct SpillSet {
288- pub vregs : SmallVec < [ VRegIndex ; no_bloat_capacity :: < VRegIndex > ( ) ] > ,
289300 pub slot : SpillSlotIndex ,
290301 pub reg_hint : PReg ,
291302 pub class : RegClass ,
292303 pub spill_bundle : LiveBundleIndex ,
293304 pub required : bool ,
294305 pub size : u8 ,
295306 pub splits : u8 ,
307+
308+ /// The aggregate [`CodeRange`] of all involved [`LiveRange`]s. The effect of this abstraction
309+ /// is that we attempt to allocate one spill slot for the extent of a bundle. For fragmented
310+ /// bundles with lots of open space this abstraction is pessimistic, but when bundles are small
311+ /// or dense this yields similar results to tracking individual live ranges.
312+ pub range : CodeRange ,
296313}
297314
298- pub ( crate ) const MAX_SPLITS_PER_SPILLSET : u8 = 10 ;
315+ pub ( crate ) const MAX_SPLITS_PER_SPILLSET : u8 = 2 ;
299316
300317#[ derive( Clone , Debug ) ]
301318pub struct VRegData {
@@ -466,9 +483,22 @@ impl<'a, F: Function> Env<'a, F> {
466483 }
467484}
468485
486+ #[ derive( Clone , Debug ) ]
487+ pub struct SpillSetRanges {
488+ pub btree : BTreeMap < LiveRangeKey , SpillSetIndex > ,
489+ }
490+
491+ impl SpillSetRanges {
492+ pub fn new ( ) -> Self {
493+ Self {
494+ btree : BTreeMap :: new ( ) ,
495+ }
496+ }
497+ }
498+
469499#[ derive( Clone , Debug ) ]
470500pub struct SpillSlotData {
471- pub ranges : LiveRangeSet ,
501+ pub ranges : SpillSetRanges ,
472502 pub slots : u32 ,
473503 pub alloc : Allocation ,
474504}
0 commit comments