@@ -26,7 +26,7 @@ use alloc::vec::Vec;
26
26
use core:: cmp:: Ordering ;
27
27
use core:: fmt:: Debug ;
28
28
use hashbrown:: { HashMap , HashSet } ;
29
- use smallvec:: SmallVec ;
29
+ use smallvec:: { smallvec , SmallVec } ;
30
30
31
31
/// A range from `from` (inclusive) to `to` (exclusive).
32
32
#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
@@ -94,11 +94,11 @@ impl core::cmp::Ord for CodeRange {
94
94
}
95
95
}
96
96
97
- define_index ! ( LiveBundleIndex ) ;
98
- define_index ! ( LiveRangeIndex ) ;
99
- define_index ! ( SpillSetIndex ) ;
97
+ define_index ! ( LiveBundleIndex , LiveBundles , LiveBundle ) ;
98
+ define_index ! ( LiveRangeIndex , LiveRanges , LiveRange ) ;
99
+ define_index ! ( SpillSetIndex , SpillSets , SpillSet ) ;
100
100
define_index ! ( UseIndex ) ;
101
- define_index ! ( VRegIndex ) ;
101
+ define_index ! ( VRegIndex , VRegs , VRegData ) ;
102
102
define_index ! ( PRegIndex ) ;
103
103
define_index ! ( SpillSlotIndex ) ;
104
104
@@ -396,6 +396,55 @@ impl BlockparamIn {
396
396
}
397
397
}
398
398
399
+ impl LiveRanges {
400
+ pub fn add ( & mut self , range : CodeRange ) -> LiveRangeIndex {
401
+ self . push ( LiveRange {
402
+ range,
403
+ vreg : VRegIndex :: invalid ( ) ,
404
+ bundle : LiveBundleIndex :: invalid ( ) ,
405
+ uses_spill_weight_and_flags : 0 ,
406
+
407
+ uses : smallvec ! [ ] ,
408
+ } )
409
+ }
410
+ }
411
+
412
+ impl LiveBundles {
413
+ pub fn add ( & mut self ) -> LiveBundleIndex {
414
+ self . push ( LiveBundle {
415
+ allocation : Allocation :: none ( ) ,
416
+ ranges : smallvec ! [ ] ,
417
+ spillset : SpillSetIndex :: invalid ( ) ,
418
+ prio : 0 ,
419
+ spill_weight_and_props : 0 ,
420
+ } )
421
+ }
422
+ }
423
+
424
+ impl VRegs {
425
+ pub fn add ( & mut self , reg : VReg , data : VRegData ) -> VRegIndex {
426
+ let idx = self . push ( data) ;
427
+ debug_assert_eq ! ( reg. vreg( ) , idx. index( ) ) ;
428
+ idx
429
+ }
430
+ }
431
+
432
+ impl core:: ops:: Index < VReg > for VRegs {
433
+ type Output = VRegData ;
434
+
435
+ #[ inline( always) ]
436
+ fn index ( & self , idx : VReg ) -> & Self :: Output {
437
+ & self . storage [ idx. vreg ( ) ]
438
+ }
439
+ }
440
+
441
+ impl core:: ops:: IndexMut < VReg > for VRegs {
442
+ #[ inline( always) ]
443
+ fn index_mut ( & mut self , idx : VReg ) -> & mut Self :: Output {
444
+ & mut self . storage [ idx. vreg ( ) ]
445
+ }
446
+ }
447
+
399
448
#[ derive( Clone , Debug ) ]
400
449
pub struct Env < ' a , F : Function > {
401
450
pub func : & ' a F ,
@@ -406,10 +455,10 @@ pub struct Env<'a, F: Function> {
406
455
pub blockparam_outs : Vec < BlockparamOut > ,
407
456
pub blockparam_ins : Vec < BlockparamIn > ,
408
457
409
- pub ranges : Vec < LiveRange > ,
410
- pub bundles : Vec < LiveBundle > ,
411
- pub spillsets : Vec < SpillSet > ,
412
- pub vregs : Vec < VRegData > ,
458
+ pub ranges : LiveRanges ,
459
+ pub bundles : LiveBundles ,
460
+ pub spillsets : SpillSets ,
461
+ pub vregs : VRegs ,
413
462
pub pregs : Vec < PRegData > ,
414
463
pub allocation_queue : PrioQueue ,
415
464
pub safepoints : Vec < Inst > , // Sorted list of safepoint insts.
@@ -457,7 +506,7 @@ impl<'a, F: Function> Env<'a, F> {
457
506
/// Get the VReg (with bundled RegClass) from a vreg index.
458
507
#[ inline]
459
508
pub fn vreg ( & self , index : VRegIndex ) -> VReg {
460
- let class = self . vregs [ index. index ( ) ]
509
+ let class = self . vregs [ index]
461
510
. class
462
511
. expect ( "trying to get a VReg before observing its class" ) ;
463
512
VReg :: new ( index. index ( ) , class)
@@ -466,15 +515,15 @@ impl<'a, F: Function> Env<'a, F> {
466
515
/// Record the class of a VReg. We learn this only when we observe
467
516
/// the VRegs in use.
468
517
pub fn observe_vreg_class ( & mut self , vreg : VReg ) {
469
- let old_class = self . vregs [ vreg. vreg ( ) ] . class . replace ( vreg. class ( ) ) ;
518
+ let old_class = self . vregs [ vreg] . class . replace ( vreg. class ( ) ) ;
470
519
// We should never observe two different classes for two
471
520
// mentions of a VReg in the source program.
472
521
debug_assert ! ( old_class == None || old_class == Some ( vreg. class( ) ) ) ;
473
522
}
474
523
475
524
/// Is this vreg actually used in the source program?
476
525
pub fn is_vreg_used ( & self , index : VRegIndex ) -> bool {
477
- self . vregs [ index. index ( ) ] . class . is_some ( )
526
+ self . vregs [ index] . class . is_some ( )
478
527
}
479
528
}
480
529
0 commit comments