@@ -355,6 +355,7 @@ impl Operand {
355
355
356
356
#[ inline( always) ]
357
357
pub fn from_bits ( bits : u32 ) -> Self {
358
+ debug_assert ! ( bits >> 29 <= 4 ) ;
358
359
Operand { bits }
359
360
}
360
361
}
@@ -429,9 +430,9 @@ pub struct Allocation {
429
430
/// `policy` field in `Operand`, and we are careful to use
430
431
/// disjoint ranges of values in this field for each type. We also
431
432
/// leave the def-or-use bit (`kind` for `Operand`) unused here so
432
- /// that the client may use it to mark `Allocation`s on
433
- /// instructions as read or write when it edits instructions
434
- /// (which is sometimes useful for post-allocation analyses ).
433
+ /// that we can use it below in `OperandOrAllocation` to record
434
+ /// whether `Allocation`s are defs or uses (which is often useful
435
+ /// to know ).
435
436
///
436
437
/// kind:3 unused:1 index:28
437
438
bits : u32 ,
@@ -532,6 +533,7 @@ impl Allocation {
532
533
533
534
#[ inline( always) ]
534
535
pub fn from_bits ( bits : u32 ) -> Self {
536
+ debug_assert ! ( bits >> 29 >= 5 ) ;
535
537
Self { bits }
536
538
}
537
539
}
@@ -566,11 +568,13 @@ pub struct OperandOrAllocation {
566
568
567
569
impl OperandOrAllocation {
568
570
pub fn from_operand ( operand : Operand ) -> Self {
571
+ debug_assert ! ( operand. bits( ) >> 29 <= 4 ) ;
569
572
Self {
570
573
bits : operand. bits ( ) ,
571
574
}
572
575
}
573
576
pub fn from_alloc ( alloc : Allocation ) -> Self {
577
+ debug_assert ! ( alloc. bits( ) >> 29 >= 5 ) ;
574
578
Self { bits : alloc. bits ( ) }
575
579
}
576
580
pub fn is_operand ( & self ) -> bool {
@@ -588,6 +592,10 @@ impl OperandOrAllocation {
588
592
}
589
593
pub fn as_allocation ( & self ) -> Option < Allocation > {
590
594
if self . is_allocation ( ) {
595
+ // Remove the def/use bit -- the canonical `Allocation`
596
+ // does not have this, and we want allocs to continue to
597
+ // be comparable whether they are used for reads or
598
+ // writes.
591
599
Some ( Allocation :: from_bits ( self . bits & !( 1 << 28 ) ) )
592
600
} else {
593
601
None
@@ -612,6 +620,9 @@ impl OperandOrAllocation {
612
620
613
621
/// A trait defined by the regalloc client to provide access to its
614
622
/// machine-instruction / CFG representation.
623
+ ///
624
+ /// (This trait's design is inspired by, and derives heavily from, the
625
+ /// trait of the same name in regalloc.rs.)
615
626
pub trait Function {
616
627
// -------------
617
628
// CFG traversal
@@ -669,10 +680,7 @@ pub trait Function {
669
680
/// Get the clobbers for an instruction.
670
681
fn inst_clobbers ( & self , insn : Inst ) -> & [ PReg ] ;
671
682
672
- /// Get the precise number of `VReg` in use in this function, to allow
673
- /// preallocating data structures. This number *must* be a correct
674
- /// lower-bound, otherwise invalid index failures may happen; it is of
675
- /// course better if it is exact.
683
+ /// Get the number of `VReg` in use in this function.
676
684
fn num_vregs ( & self ) -> usize ;
677
685
678
686
/// Get the VRegs that are pointer/reference types. This has the
@@ -724,6 +732,9 @@ pub trait Function {
724
732
/// but we also use them for F32 and F64 values, we may use a different
725
733
/// store-slot size and smaller-operand store/load instructions for an F64
726
734
/// than for a true V128.
735
+ ///
736
+ /// (This trait method's design and doc text derives from
737
+ /// regalloc.rs' trait of the same name.)
727
738
fn spillslot_size ( & self , regclass : RegClass , for_vreg : VReg ) -> usize ;
728
739
729
740
/// When providing a spillslot number for a multi-slot spillslot,
0 commit comments