1 //! Data structures for the whole crate.
2 
3 use rustc_hash::FxHashMap;
4 use rustc_hash::FxHashSet;
5 use smallvec::SmallVec;
6 
7 use std::cmp::Ordering;
8 use std::collections::VecDeque;
9 use std::fmt;
10 use std::hash::Hash;
11 use std::marker::PhantomData;
12 use std::ops::Index;
13 use std::ops::IndexMut;
14 use std::slice::{Iter, IterMut};
15 
16 use crate::{Function, RegUsageMapper};
17 
18 #[cfg(feature = "enable-serde")]
19 use serde::{Deserialize, Serialize};
20 
21 //=============================================================================
22 // Queues
23 
24 pub type Queue<T> = VecDeque<T>;
25 
26 //=============================================================================
27 // Maps
28 
29 // NOTE: plain HashMap is nondeterministic, even in a single-threaded
30 // scenario, which can make debugging code that uses it really confusing.  So
31 // we use FxHashMap instead, as it *is* deterministic, and, allegedly, faster
32 // too.
33 pub type Map<K, V> = FxHashMap<K, V>;
34 
35 //=============================================================================
36 // Sets of things
37 
38 // Same comment as above for FxHashMap.
39 #[derive(Clone)]
40 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
41 pub struct Set<T: Eq + Hash> {
42     set: FxHashSet<T>,
43 }
44 
45 impl<T: Eq + Ord + Hash + Copy + fmt::Debug> Set<T> {
46     #[inline(never)]
empty() -> Self47     pub fn empty() -> Self {
48         Self {
49             set: FxHashSet::<T>::default(),
50         }
51     }
52 
53     #[inline(never)]
unit(item: T) -> Self54     pub fn unit(item: T) -> Self {
55         let mut s = Self::empty();
56         s.insert(item);
57         s
58     }
59 
60     #[inline(never)]
two(item1: T, item2: T) -> Self61     pub fn two(item1: T, item2: T) -> Self {
62         let mut s = Self::empty();
63         s.insert(item1);
64         s.insert(item2);
65         s
66     }
67 
68     #[inline(never)]
card(&self) -> usize69     pub fn card(&self) -> usize {
70         self.set.len()
71     }
72 
73     #[inline(never)]
insert(&mut self, item: T)74     pub fn insert(&mut self, item: T) {
75         self.set.insert(item);
76     }
77 
78     #[inline(never)]
delete(&mut self, item: T)79     pub fn delete(&mut self, item: T) {
80         self.set.remove(&item);
81     }
82 
83     #[inline(never)]
is_empty(&self) -> bool84     pub fn is_empty(&self) -> bool {
85         self.set.is_empty()
86     }
87 
88     #[inline(never)]
contains(&self, item: T) -> bool89     pub fn contains(&self, item: T) -> bool {
90         self.set.contains(&item)
91     }
92 
93     #[inline(never)]
intersect(&mut self, other: &Self)94     pub fn intersect(&mut self, other: &Self) {
95         let mut res = FxHashSet::<T>::default();
96         for item in self.set.iter() {
97             if other.set.contains(item) {
98                 res.insert(*item);
99             }
100         }
101         self.set = res;
102     }
103 
104     #[inline(never)]
union(&mut self, other: &Self)105     pub fn union(&mut self, other: &Self) {
106         for item in other.set.iter() {
107             self.set.insert(*item);
108         }
109     }
110 
111     #[inline(never)]
remove(&mut self, other: &Self)112     pub fn remove(&mut self, other: &Self) {
113         for item in other.set.iter() {
114             self.set.remove(item);
115         }
116     }
117 
118     #[inline(never)]
intersects(&self, other: &Self) -> bool119     pub fn intersects(&self, other: &Self) -> bool {
120         !self.set.is_disjoint(&other.set)
121     }
122 
123     #[inline(never)]
is_subset_of(&self, other: &Self) -> bool124     pub fn is_subset_of(&self, other: &Self) -> bool {
125         self.set.is_subset(&other.set)
126     }
127 
128     #[inline(never)]
to_vec(&self) -> Vec<T>129     pub fn to_vec(&self) -> Vec<T> {
130         let mut res = Vec::<T>::new();
131         for item in self.set.iter() {
132             res.push(*item)
133         }
134         // Don't delete this.  It is important.
135         res.sort_unstable();
136         res
137     }
138 
139     #[inline(never)]
from_vec(vec: Vec<T>) -> Self140     pub fn from_vec(vec: Vec<T>) -> Self {
141         let mut res = Set::<T>::empty();
142         for x in vec {
143             res.insert(x);
144         }
145         res
146     }
147 
148     #[inline(never)]
equals(&self, other: &Self) -> bool149     pub fn equals(&self, other: &Self) -> bool {
150         self.set == other.set
151     }
152 
153     #[inline(never)]
retain<F>(&mut self, f: F) where F: FnMut(&T) -> bool,154     pub fn retain<F>(&mut self, f: F)
155     where
156         F: FnMut(&T) -> bool,
157     {
158         self.set.retain(f)
159     }
160 
161     #[inline(never)]
map<F, U>(&self, f: F) -> Set<U> where F: Fn(&T) -> U, U: Eq + Ord + Hash + Copy + fmt::Debug,162     pub fn map<F, U>(&self, f: F) -> Set<U>
163     where
164         F: Fn(&T) -> U,
165         U: Eq + Ord + Hash + Copy + fmt::Debug,
166     {
167         Set {
168             set: self.set.iter().map(f).collect(),
169         }
170     }
171 
172     #[inline(never)]
filter_map<F, U>(&self, f: F) -> Set<U> where F: Fn(&T) -> Option<U>, U: Eq + Ord + Hash + Copy + fmt::Debug,173     pub fn filter_map<F, U>(&self, f: F) -> Set<U>
174     where
175         F: Fn(&T) -> Option<U>,
176         U: Eq + Ord + Hash + Copy + fmt::Debug,
177     {
178         Set {
179             set: self.set.iter().filter_map(f).collect(),
180         }
181     }
182 
clear(&mut self)183     pub fn clear(&mut self) {
184         self.set.clear();
185     }
186 }
187 
188 impl<T: Eq + Ord + Hash + Copy + fmt::Debug> fmt::Debug for Set<T> {
189     #[inline(never)]
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result190     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
191         // Print the elements in some way which depends only on what is
192         // present in the set, and not on any other factor.  In particular,
193         // <Debug for FxHashSet> has been observed to to print the elements
194         // of a two element set in both orders on different occasions.
195         let sorted_vec = self.to_vec();
196         let mut s = "{".to_string();
197         for i in 0..sorted_vec.len() {
198             if i > 0 {
199                 s = s + &", ".to_string();
200             }
201             s = s + &format!("{:?}", &sorted_vec[i]);
202         }
203         s = s + &"}".to_string();
204         write!(fmt, "{}", s)
205     }
206 }
207 
208 pub struct SetIter<'a, T> {
209     set_iter: std::collections::hash_set::Iter<'a, T>,
210 }
211 impl<T: Eq + Hash> Set<T> {
iter(&self) -> SetIter<T>212     pub fn iter(&self) -> SetIter<T> {
213         SetIter {
214             set_iter: self.set.iter(),
215         }
216     }
217 }
218 impl<'a, T> Iterator for SetIter<'a, T> {
219     type Item = &'a T;
next(&mut self) -> Option<Self::Item>220     fn next(&mut self) -> Option<Self::Item> {
221         self.set_iter.next()
222     }
223 }
224 
225 //=============================================================================
226 // Iteration boilerplate for entities.  The only purpose of this is to support
227 // constructions of the form
228 //
229 //   for ent in startEnt .dotdot( endPlus1Ent ) {
230 //   }
231 //
232 // until such time as `trait Step` is available in stable Rust.  At that point
233 // `fn dotdot` and all of the following can be removed, and the loops
234 // rewritten using the standard syntax:
235 //
236 //   for ent in startEnt .. endPlus1Ent {
237 //   }
238 
239 pub trait Zero {
zero() -> Self240     fn zero() -> Self;
241 }
242 
243 pub trait PlusN {
plus_n(&self, n: usize) -> Self244     fn plus_n(&self, n: usize) -> Self;
245 }
246 
247 #[derive(Clone, Copy)]
248 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
249 pub struct Range<T> {
250     first: T,
251     len: usize,
252 }
253 
254 impl<T: Copy + PartialOrd + PlusN> IntoIterator for Range<T> {
255     type Item = T;
256     type IntoIter = MyIterator<T>;
into_iter(self) -> Self::IntoIter257     fn into_iter(self) -> Self::IntoIter {
258         MyIterator {
259             range: self,
260             next: self.first,
261         }
262     }
263 }
264 
265 impl<T: Copy + Eq + Ord + PlusN> Range<T> {
266     /// Create a new range object.
new(from: T, len: usize) -> Range<T>267     pub fn new(from: T, len: usize) -> Range<T> {
268         Range { first: from, len }
269     }
270 
start(&self) -> T271     pub fn start(&self) -> T {
272         self.first
273     }
274 
first(&self) -> T275     pub fn first(&self) -> T {
276         assert!(self.len() > 0);
277         self.start()
278     }
279 
last(&self) -> T280     pub fn last(&self) -> T {
281         assert!(self.len() > 0);
282         self.start().plus_n(self.len() - 1)
283     }
284 
last_plus1(&self) -> T285     pub fn last_plus1(&self) -> T {
286         self.start().plus_n(self.len())
287     }
288 
len(&self) -> usize289     pub fn len(&self) -> usize {
290         self.len
291     }
292 
contains(&self, t: T) -> bool293     pub fn contains(&self, t: T) -> bool {
294         t >= self.first && t < self.first.plus_n(self.len)
295     }
296 }
297 
298 pub struct MyIterator<T> {
299     range: Range<T>,
300     next: T,
301 }
302 impl<T: Copy + PartialOrd + PlusN> Iterator for MyIterator<T> {
303     type Item = T;
next(&mut self) -> Option<Self::Item>304     fn next(&mut self) -> Option<Self::Item> {
305         if self.next >= self.range.first.plus_n(self.range.len) {
306             None
307         } else {
308             let res = Some(self.next);
309             self.next = self.next.plus_n(1);
310             res
311         }
312     }
313 }
314 
315 //=============================================================================
316 // Vectors where both the index and element types can be specified (and at
317 // most 2^32-1 elems can be stored.  What if this overflows?)
318 
319 pub struct TypedIxVec<TyIx, Ty> {
320     vek: Vec<Ty>,
321     ty_ix: PhantomData<TyIx>,
322 }
323 
324 impl<TyIx, Ty> TypedIxVec<TyIx, Ty>
325 where
326     Ty: Clone,
327     TyIx: Copy + Eq + Ord + Zero + PlusN + Into<u32>,
328 {
new() -> Self329     pub fn new() -> Self {
330         Self {
331             vek: Vec::new(),
332             ty_ix: PhantomData::<TyIx>,
333         }
334     }
from_vec(vek: Vec<Ty>) -> Self335     pub fn from_vec(vek: Vec<Ty>) -> Self {
336         Self {
337             vek,
338             ty_ix: PhantomData::<TyIx>,
339         }
340     }
append(&mut self, other: &mut TypedIxVec<TyIx, Ty>)341     pub fn append(&mut self, other: &mut TypedIxVec<TyIx, Ty>) {
342         // FIXME what if this overflows?
343         self.vek.append(&mut other.vek);
344     }
iter(&self) -> Iter<Ty>345     pub fn iter(&self) -> Iter<Ty> {
346         self.vek.iter()
347     }
iter_mut(&mut self) -> IterMut<Ty>348     pub fn iter_mut(&mut self) -> IterMut<Ty> {
349         self.vek.iter_mut()
350     }
len(&self) -> u32351     pub fn len(&self) -> u32 {
352         // FIXME what if this overflows?
353         self.vek.len() as u32
354     }
push(&mut self, item: Ty)355     pub fn push(&mut self, item: Ty) {
356         // FIXME what if this overflows?
357         self.vek.push(item);
358     }
resize(&mut self, new_len: u32, value: Ty)359     pub fn resize(&mut self, new_len: u32, value: Ty) {
360         self.vek.resize(new_len as usize, value);
361     }
reserve(&mut self, additional: usize)362     pub fn reserve(&mut self, additional: usize) {
363         self.vek.reserve(additional);
364     }
elems(&self) -> &[Ty]365     pub fn elems(&self) -> &[Ty] {
366         &self.vek[..]
367     }
elems_mut(&mut self) -> &mut [Ty]368     pub fn elems_mut(&mut self) -> &mut [Ty] {
369         &mut self.vek[..]
370     }
range(&self) -> Range<TyIx>371     pub fn range(&self) -> Range<TyIx> {
372         Range::new(TyIx::zero(), self.len() as usize)
373     }
remove(&mut self, idx: TyIx) -> Ty374     pub fn remove(&mut self, idx: TyIx) -> Ty {
375         self.vek.remove(idx.into() as usize)
376     }
sort_by<F: FnMut(&Ty, &Ty) -> Ordering>(&mut self, compare: F)377     pub fn sort_by<F: FnMut(&Ty, &Ty) -> Ordering>(&mut self, compare: F) {
378         self.vek.sort_by(compare)
379     }
sort_unstable_by<F: FnMut(&Ty, &Ty) -> Ordering>(&mut self, compare: F)380     pub fn sort_unstable_by<F: FnMut(&Ty, &Ty) -> Ordering>(&mut self, compare: F) {
381         self.vek.sort_unstable_by(compare)
382     }
clear(&mut self)383     pub fn clear(&mut self) {
384         self.vek.clear();
385     }
386 }
387 
388 impl<TyIx, Ty> Index<TyIx> for TypedIxVec<TyIx, Ty>
389 where
390     TyIx: Into<u32>,
391 {
392     type Output = Ty;
index(&self, ix: TyIx) -> &Ty393     fn index(&self, ix: TyIx) -> &Ty {
394         &self.vek[ix.into() as usize]
395     }
396 }
397 
398 impl<TyIx, Ty> IndexMut<TyIx> for TypedIxVec<TyIx, Ty>
399 where
400     TyIx: Into<u32>,
401 {
index_mut(&mut self, ix: TyIx) -> &mut Ty402     fn index_mut(&mut self, ix: TyIx) -> &mut Ty {
403         &mut self.vek[ix.into() as usize]
404     }
405 }
406 
407 impl<TyIx, Ty> Clone for TypedIxVec<TyIx, Ty>
408 where
409     Ty: Clone,
410 {
411     // This is only needed for debug printing.
clone(&self) -> Self412     fn clone(&self) -> Self {
413         Self {
414             vek: self.vek.clone(),
415             ty_ix: PhantomData::<TyIx>,
416         }
417     }
418 }
419 
420 //=============================================================================
421 
422 macro_rules! generate_boilerplate {
423     ($TypeIx:ident, $Type:ident, $PrintingPrefix:expr) => {
424         #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
425         #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
426         // Firstly, the indexing type (TypeIx)
427         pub enum $TypeIx {
428             $TypeIx(u32),
429         }
430         impl $TypeIx {
431             #[allow(dead_code)]
432             #[inline(always)]
433             pub fn new(n: u32) -> Self {
434                 debug_assert!(n != u32::max_value());
435                 Self::$TypeIx(n)
436             }
437             #[allow(dead_code)]
438             #[inline(always)]
439             pub const fn max_value() -> Self {
440                 Self::$TypeIx(u32::max_value() - 1)
441             }
442             #[allow(dead_code)]
443             #[inline(always)]
444             pub const fn min_value() -> Self {
445                 Self::$TypeIx(u32::min_value())
446             }
447             #[allow(dead_code)]
448             #[inline(always)]
449             pub const fn invalid_value() -> Self {
450                 Self::$TypeIx(u32::max_value())
451             }
452             #[allow(dead_code)]
453             #[inline(always)]
454             pub fn is_valid(self) -> bool {
455                 self != Self::invalid_value()
456             }
457             #[allow(dead_code)]
458             #[inline(always)]
459             pub fn is_invalid(self) -> bool {
460                 self == Self::invalid_value()
461             }
462             #[allow(dead_code)]
463             #[inline(always)]
464             pub fn get(self) -> u32 {
465                 debug_assert!(self.is_valid());
466                 match self {
467                     $TypeIx::$TypeIx(n) => n,
468                 }
469             }
470             #[allow(dead_code)]
471             #[inline(always)]
472             pub fn plus(self, delta: u32) -> $TypeIx {
473                 debug_assert!(self.is_valid());
474                 $TypeIx::$TypeIx(self.get() + delta)
475             }
476             #[allow(dead_code)]
477             #[inline(always)]
478             pub fn minus(self, delta: u32) -> $TypeIx {
479                 debug_assert!(self.is_valid());
480                 $TypeIx::$TypeIx(self.get() - delta)
481             }
482             #[allow(dead_code)]
483             pub fn dotdot(&self, last_plus1: $TypeIx) -> Range<$TypeIx> {
484                 debug_assert!(self.is_valid());
485                 let len = (last_plus1.get() - self.get()) as usize;
486                 Range::new(*self, len)
487             }
488         }
489         impl fmt::Debug for $TypeIx {
490             fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
491                 if self.is_invalid() {
492                     write!(fmt, "{}<NONE>", $PrintingPrefix)
493                 } else {
494                     write!(fmt, "{}{}", $PrintingPrefix, &self.get())
495                 }
496             }
497         }
498         impl PlusN for $TypeIx {
499             #[inline(always)]
500             fn plus_n(&self, n: usize) -> Self {
501                 debug_assert!(self.is_valid());
502                 self.plus(n as u32)
503             }
504         }
505         impl Into<u32> for $TypeIx {
506             #[inline(always)]
507             fn into(self) -> u32 {
508                 debug_assert!(self.is_valid());
509                 self.get()
510             }
511         }
512         impl Zero for $TypeIx {
513             #[inline(always)]
514             fn zero() -> Self {
515                 $TypeIx::new(0)
516             }
517         }
518     };
519 }
520 
521 generate_boilerplate!(InstIx, Inst, "i");
522 
523 generate_boilerplate!(BlockIx, Block, "b");
524 
525 generate_boilerplate!(RangeFragIx, RangeFrag, "f");
526 
527 generate_boilerplate!(VirtualRangeIx, VirtualRange, "vr");
528 
529 generate_boilerplate!(RealRangeIx, RealRange, "rr");
530 
531 impl<TyIx, Ty: fmt::Debug> fmt::Debug for TypedIxVec<TyIx, Ty> {
532     // This is something of a hack in the sense that it doesn't show the
533     // indices, but oh well ..
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result534     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
535         write!(fmt, "{:?}", self.vek)
536     }
537 }
538 
539 //=============================================================================
540 // Definitions of register classes, registers and stack slots, and printing
541 // thereof. Note that this register class definition is meant to be
542 // architecture-independent: it simply captures common integer/float/vector
543 // types that machines are likely to use. TODO: investigate whether we need a
544 // more flexible register-class definition mechanism.
545 
546 #[derive(PartialEq, Eq, Debug, Clone, Copy)]
547 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
548 pub enum RegClass {
549     I32 = 0,
550     F32 = 1,
551     I64 = 2,
552     F64 = 3,
553     V128 = 4,
554     INVALID = 5,
555 }
556 
557 /// The number of register classes that exist.
558 /// N.B.: must be <= 7 (fit into 3 bits) for 32-bit VReg/RReg packed format!
559 pub const NUM_REG_CLASSES: usize = 5;
560 
561 impl RegClass {
562     /// Convert a register class to a u32 index.
563     #[inline(always)]
rc_to_u32(self) -> u32564     pub fn rc_to_u32(self) -> u32 {
565         self as u32
566     }
567     /// Convert a register class to a usize index.
568     #[inline(always)]
rc_to_usize(self) -> usize569     pub fn rc_to_usize(self) -> usize {
570         self as usize
571     }
572     /// Construct a register class from a u32.
573     #[inline(always)]
rc_from_u32(rc: u32) -> RegClass574     pub fn rc_from_u32(rc: u32) -> RegClass {
575         match rc {
576             0 => RegClass::I32,
577             1 => RegClass::F32,
578             2 => RegClass::I64,
579             3 => RegClass::F64,
580             4 => RegClass::V128,
581             _ => panic!("RegClass::rc_from_u32"),
582         }
583     }
584 
short_name(self) -> &'static str585     pub fn short_name(self) -> &'static str {
586         match self {
587             RegClass::I32 => "I",
588             RegClass::I64 => "J",
589             RegClass::F32 => "F",
590             RegClass::F64 => "D",
591             RegClass::V128 => "V",
592             RegClass::INVALID => panic!("RegClass::short_name"),
593         }
594     }
595 
long_name(self) -> &'static str596     pub fn long_name(self) -> &'static str {
597         match self {
598             RegClass::I32 => "I32",
599             RegClass::I64 => "I32",
600             RegClass::F32 => "F32",
601             RegClass::F64 => "F32",
602             RegClass::V128 => "V128",
603             RegClass::INVALID => panic!("RegClass::long_name"),
604         }
605     }
606 }
607 
608 // Reg represents both real and virtual registers.  For compactness and speed,
609 // these fields are packed into a single u32.  The format is:
610 //
611 // Virtual Reg:   1  rc:3                index:28
612 // Real Reg:      0  rc:3  uu:12  enc:8  index:8
613 //
614 // `rc` is the register class.  `uu` means "unused".  `enc` is the hardware
615 // encoding for the reg.  `index` is a zero based index which has the
616 // following meanings:
617 //
618 // * for a Virtual Reg, `index` is just the virtual register number.
619 // * for a Real Reg, `index` is the entry number in the associated
620 //   `RealRegUniverse`.
621 //
622 // This scheme gives us:
623 //
624 // * a compact (32-bit) representation for registers
625 // * fast equality tests for registers
626 // * ability to handle up to 2^28 (268.4 million) virtual regs per function
627 // * ability to handle up to 8 register classes
628 // * ability to handle targets with up to 256 real registers
629 // * ability to emit instructions containing real regs without having to
630 //   look up encodings in any side tables, since a real reg carries its
631 //   encoding
632 // * efficient bitsets and arrays of virtual registers, since each has a
633 //   zero-based index baked in
634 // * efficient bitsets and arrays of real registers, for the same reason
635 //
636 // This scheme makes it impossible to represent overlapping register classes,
637 // but that doesn't seem important.  AFAIK only ARM32 VFP/Neon has that.
638 
639 #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
640 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
641 pub struct Reg {
642     bits: u32,
643 }
644 
645 static INVALID_REG: u32 = 0xffffffff;
646 
647 impl Reg {
648     #[inline(always)]
is_virtual(self) -> bool649     pub fn is_virtual(self) -> bool {
650         self.is_valid() && (self.bits & 0x8000_0000) != 0
651     }
652     #[inline(always)]
is_real(self) -> bool653     pub fn is_real(self) -> bool {
654         self.is_valid() && (self.bits & 0x8000_0000) == 0
655     }
new_real(rc: RegClass, enc: u8, index: u8) -> Self656     pub fn new_real(rc: RegClass, enc: u8, index: u8) -> Self {
657         let n = (0 << 31) | (rc.rc_to_u32() << 28) | ((enc as u32) << 8) | ((index as u32) << 0);
658         Reg { bits: n }
659     }
new_virtual(rc: RegClass, index: u32) -> Self660     pub fn new_virtual(rc: RegClass, index: u32) -> Self {
661         if index >= (1 << 28) {
662             panic!("new_virtual(): index too large");
663         }
664         let n = (1 << 31) | (rc.rc_to_u32() << 28) | (index << 0);
665         Reg { bits: n }
666     }
invalid() -> Reg667     pub fn invalid() -> Reg {
668         Reg { bits: INVALID_REG }
669     }
670     #[inline(always)]
is_invalid(self) -> bool671     pub fn is_invalid(self) -> bool {
672         self.bits == INVALID_REG
673     }
674     #[inline(always)]
is_valid(self) -> bool675     pub fn is_valid(self) -> bool {
676         !self.is_invalid()
677     }
is_virtual_or_invalid(self) -> bool678     pub fn is_virtual_or_invalid(self) -> bool {
679         self.is_virtual() || self.is_invalid()
680     }
is_real_or_invalid(self) -> bool681     pub fn is_real_or_invalid(self) -> bool {
682         self.is_real() || self.is_invalid()
683     }
684     #[inline(always)]
get_class(self) -> RegClass685     pub fn get_class(self) -> RegClass {
686         debug_assert!(self.is_valid());
687         RegClass::rc_from_u32((self.bits >> 28) & 0x7)
688     }
689     #[inline(always)]
get_index(self) -> usize690     pub fn get_index(self) -> usize {
691         debug_assert!(self.is_valid());
692         // Return type is usize because typically we will want to use the
693         // result for indexing into a Vec
694         if self.is_virtual() {
695             (self.bits & ((1 << 28) - 1)) as usize
696         } else {
697             (self.bits & ((1 << 8) - 1)) as usize
698         }
699     }
700     #[inline(always)]
get_index_u32(self) -> u32701     pub fn get_index_u32(self) -> u32 {
702         debug_assert!(self.is_valid());
703         if self.is_virtual() {
704             self.bits & ((1 << 28) - 1)
705         } else {
706             self.bits & ((1 << 8) - 1)
707         }
708     }
get_hw_encoding(self) -> u8709     pub fn get_hw_encoding(self) -> u8 {
710         debug_assert!(self.is_valid());
711         if self.is_virtual() {
712             panic!("Virtual register does not have a hardware encoding")
713         } else {
714             ((self.bits >> 8) & ((1 << 8) - 1)) as u8
715         }
716     }
as_virtual_reg(self) -> Option<VirtualReg>717     pub fn as_virtual_reg(self) -> Option<VirtualReg> {
718         // Allow invalid virtual regs as well.
719         if self.is_virtual_or_invalid() {
720             Some(VirtualReg { reg: self })
721         } else {
722             None
723         }
724     }
as_real_reg(self) -> Option<RealReg>725     pub fn as_real_reg(self) -> Option<RealReg> {
726         // Allow invalid real regs as well.
727         if self.is_real_or_invalid() {
728             Some(RealReg { reg: self })
729         } else {
730             None
731         }
732     }
show_with_rru(self, univ: &RealRegUniverse) -> String733     pub fn show_with_rru(self, univ: &RealRegUniverse) -> String {
734         if self.is_real() && self.get_index() < univ.regs.len() {
735             univ.regs[self.get_index()].1.clone()
736         } else if self.is_valid() {
737             format!("{:?}", self)
738         } else {
739             "rINVALID".to_string()
740         }
741     }
742 }
743 
744 impl fmt::Debug for Reg {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result745     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
746         if self.is_valid() {
747             write!(
748                 fmt,
749                 "{}{}{}",
750                 if self.is_virtual() { "v" } else { "r" },
751                 self.get_index(),
752                 self.get_class().short_name(),
753             )
754         } else {
755             write!(fmt, "rINVALID")
756         }
757     }
758 }
759 
760 // RealReg and VirtualReg are merely wrappers around Reg, which try to
761 // dynamically ensure that they are really wrapping the correct flavour of
762 // register.
763 
764 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
765 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
766 pub struct RealReg {
767     reg: Reg,
768 }
769 impl Reg /* !!not RealReg!! */ {
to_real_reg(self) -> RealReg770     pub fn to_real_reg(self) -> RealReg {
771         if self.is_virtual() {
772             panic!("Reg::to_real_reg: this is a virtual register")
773         } else {
774             RealReg { reg: self }
775         }
776     }
777 }
778 impl RealReg {
get_class(self) -> RegClass779     pub fn get_class(self) -> RegClass {
780         self.reg.get_class()
781     }
782     #[inline(always)]
get_index(self) -> usize783     pub fn get_index(self) -> usize {
784         self.reg.get_index()
785     }
get_hw_encoding(self) -> usize786     pub fn get_hw_encoding(self) -> usize {
787         self.reg.get_hw_encoding() as usize
788     }
789     #[inline(always)]
to_reg(self) -> Reg790     pub fn to_reg(self) -> Reg {
791         self.reg
792     }
invalid() -> RealReg793     pub fn invalid() -> RealReg {
794         RealReg {
795             reg: Reg::invalid(),
796         }
797     }
is_valid(self) -> bool798     pub fn is_valid(self) -> bool {
799         self.reg.is_valid()
800     }
is_invalid(self) -> bool801     pub fn is_invalid(self) -> bool {
802         self.reg.is_invalid()
803     }
maybe_valid(self) -> Option<RealReg>804     pub fn maybe_valid(self) -> Option<RealReg> {
805         if self == RealReg::invalid() {
806             None
807         } else {
808             Some(self)
809         }
810     }
811 }
812 impl fmt::Debug for RealReg {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result813     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
814         write!(fmt, "{:?}", self.reg)
815     }
816 }
817 
818 #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
819 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
820 pub struct VirtualReg {
821     reg: Reg,
822 }
823 impl Reg /* !!not VirtualReg!! */ {
824     #[inline(always)]
to_virtual_reg(self) -> VirtualReg825     pub fn to_virtual_reg(self) -> VirtualReg {
826         if self.is_virtual() {
827             VirtualReg { reg: self }
828         } else {
829             panic!("Reg::to_virtual_reg: this is a real register")
830         }
831     }
832 }
833 impl VirtualReg {
get_class(self) -> RegClass834     pub fn get_class(self) -> RegClass {
835         self.reg.get_class()
836     }
837     #[inline(always)]
get_index(self) -> usize838     pub fn get_index(self) -> usize {
839         self.reg.get_index()
840     }
841     #[inline(always)]
to_reg(self) -> Reg842     pub fn to_reg(self) -> Reg {
843         self.reg
844     }
invalid() -> VirtualReg845     pub fn invalid() -> VirtualReg {
846         VirtualReg {
847             reg: Reg::invalid(),
848         }
849     }
is_valid(self) -> bool850     pub fn is_valid(self) -> bool {
851         self.reg.is_valid()
852     }
is_invalid(self) -> bool853     pub fn is_invalid(self) -> bool {
854         self.reg.is_invalid()
855     }
maybe_valid(self) -> Option<VirtualReg>856     pub fn maybe_valid(self) -> Option<VirtualReg> {
857         if self == VirtualReg::invalid() {
858             None
859         } else {
860             Some(self)
861         }
862     }
863 }
864 impl fmt::Debug for VirtualReg {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result865     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
866         write!(fmt, "{:?}", self.reg)
867     }
868 }
869 
870 impl Reg {
871     /// Apply a vreg-rreg mapping to a Reg.  This is used for registers used in
872     /// a read-role.
apply_uses<RUM: RegUsageMapper>(&mut self, mapper: &RUM)873     pub fn apply_uses<RUM: RegUsageMapper>(&mut self, mapper: &RUM) {
874         self.apply(|vreg| mapper.get_use(vreg));
875     }
876 
877     /// Apply a vreg-rreg mapping to a Reg.  This is used for registers used in
878     /// a write-role.
apply_defs<RUM: RegUsageMapper>(&mut self, mapper: &RUM)879     pub fn apply_defs<RUM: RegUsageMapper>(&mut self, mapper: &RUM) {
880         self.apply(|vreg| mapper.get_def(vreg));
881     }
882 
883     /// Apply a vreg-rreg mapping to a Reg.  This is used for registers used in
884     /// a modify-role.
apply_mods<RUM: RegUsageMapper>(&mut self, mapper: &RUM)885     pub fn apply_mods<RUM: RegUsageMapper>(&mut self, mapper: &RUM) {
886         self.apply(|vreg| mapper.get_mod(vreg));
887     }
888 
apply<F: Fn(VirtualReg) -> Option<RealReg>>(&mut self, f: F)889     fn apply<F: Fn(VirtualReg) -> Option<RealReg>>(&mut self, f: F) {
890         if let Some(vreg) = self.as_virtual_reg() {
891             if let Some(rreg) = f(vreg) {
892                 debug_assert!(rreg.get_class() == vreg.get_class());
893                 *self = rreg.to_reg();
894             } else {
895                 panic!("Reg::apply: no mapping for {:?}", self);
896             }
897         }
898     }
899 }
900 
901 /// A "writable register". This is a zero-cost wrapper that can be used to
902 /// create a distinction, at the Rust type level, between a plain "register"
903 /// and a "writable register".
904 ///
905 /// Only structs that implement the `WritableBase` trait can be wrapped with
906 /// `Writable`. These are the Reg, RealReg and VirtualReg data structures only,
907 /// since `WritableBase` is not exposed to end users.
908 ///
909 /// Writable<..> can be used by the client to ensure that, internally, it only
910 /// generates instructions that write to registers that should be written. The
911 /// `InstRegUses` below, which must be implemented for every instruction,
912 /// requires a `Writable<Reg>` (not just `Reg`) in its `defined` and
913 /// `modified` sets. While we cannot hide the constructor for `Writable<..>`
914 /// from certain parts of the client while exposing it to others, the client
915 /// *can* adopt conventions to e.g. only ever call the Writable<..>
916 /// constructor from its central vreg-management logic, and decide that any
917 /// invocation of this constructor in a machine backend (for example) is an
918 /// error.
919 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
920 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
921 pub struct Writable<R: WritableBase> {
922     reg: R,
923 }
924 
925 /// Set of requirements for types that can be wrapped in Writable.
926 pub trait WritableBase:
927     Copy + Clone + PartialEq + Eq + Hash + PartialOrd + Ord + fmt::Debug
928 {
929 }
930 
931 impl WritableBase for Reg {}
932 impl WritableBase for RealReg {}
933 impl WritableBase for VirtualReg {}
934 
935 impl<R: WritableBase> Writable<R> {
936     /// Create a Writable<R> from an R. The client should carefully audit where
937     /// it calls this constructor to ensure correctness (see `Writable<..>`
938     /// struct documentation).
939     #[inline(always)]
from_reg(reg: R) -> Writable<R>940     pub fn from_reg(reg: R) -> Writable<R> {
941         Writable { reg }
942     }
943 
944     /// Get the inner Reg.
to_reg(&self) -> R945     pub fn to_reg(&self) -> R {
946         self.reg
947     }
948 
map<F, U>(&self, f: F) -> Writable<U> where F: Fn(R) -> U, U: WritableBase,949     pub fn map<F, U>(&self, f: F) -> Writable<U>
950     where
951         F: Fn(R) -> U,
952         U: WritableBase,
953     {
954         Writable { reg: f(self.reg) }
955     }
956 }
957 
958 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
959 pub struct SpillSlot(u32);
960 
961 impl SpillSlot {
962     #[inline(always)]
new(n: u32) -> Self963     pub fn new(n: u32) -> Self {
964         Self(n)
965     }
966     #[inline(always)]
get(self) -> u32967     pub fn get(self) -> u32 {
968         self.0
969     }
970     #[inline(always)]
get_usize(self) -> usize971     pub fn get_usize(self) -> usize {
972         self.get() as usize
973     }
round_up(self, num_slots: u32) -> SpillSlot974     pub fn round_up(self, num_slots: u32) -> SpillSlot {
975         assert!(num_slots > 0);
976         SpillSlot::new((self.get() + num_slots - 1) / num_slots * num_slots)
977     }
inc(self, num_slots: u32) -> SpillSlot978     pub fn inc(self, num_slots: u32) -> SpillSlot {
979         SpillSlot::new(self.get() + num_slots)
980     }
981 }
982 
983 impl fmt::Debug for SpillSlot {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result984     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
985         write!(fmt, "S{}", self.get())
986     }
987 }
988 
989 //=============================================================================
990 // Register uses: low level interface
991 
992 // This minimal struct is visible from outside the regalloc.rs interface.  It
993 // is intended to be a safe wrapper around `RegVecs`, which isn't externally
994 // visible.  It is used to collect unsanitized reg use info from client
995 // instructions.
996 pub struct RegUsageCollector<'a> {
997     pub reg_vecs: &'a mut RegVecs,
998 }
999 
1000 impl<'a> RegUsageCollector<'a> {
new(reg_vecs: &'a mut RegVecs) -> Self1001     pub fn new(reg_vecs: &'a mut RegVecs) -> Self {
1002         Self { reg_vecs }
1003     }
add_use(&mut self, r: Reg)1004     pub fn add_use(&mut self, r: Reg) {
1005         self.reg_vecs.uses.push(r);
1006     }
add_uses(&mut self, regs: &[Reg])1007     pub fn add_uses(&mut self, regs: &[Reg]) {
1008         self.reg_vecs.uses.extend(regs.iter());
1009     }
add_def(&mut self, r: Writable<Reg>)1010     pub fn add_def(&mut self, r: Writable<Reg>) {
1011         self.reg_vecs.defs.push(r.to_reg());
1012     }
add_defs(&mut self, regs: &[Writable<Reg>])1013     pub fn add_defs(&mut self, regs: &[Writable<Reg>]) {
1014         self.reg_vecs.defs.reserve(regs.len());
1015         for r in regs {
1016             self.reg_vecs.defs.push(r.to_reg());
1017         }
1018     }
add_mod(&mut self, r: Writable<Reg>)1019     pub fn add_mod(&mut self, r: Writable<Reg>) {
1020         self.reg_vecs.mods.push(r.to_reg());
1021     }
add_mods(&mut self, regs: &[Writable<Reg>])1022     pub fn add_mods(&mut self, regs: &[Writable<Reg>]) {
1023         self.reg_vecs.mods.reserve(regs.len());
1024         for r in regs {
1025             self.reg_vecs.mods.push(r.to_reg());
1026         }
1027     }
1028 
1029     // The presence of the following two is a hack, needed to support fuzzing
1030     // in the test framework.  Real clients should not call them.
get_use_def_mod_vecs_test_framework_only(&self) -> (Vec<Reg>, Vec<Reg>, Vec<Reg>)1031     pub fn get_use_def_mod_vecs_test_framework_only(&self) -> (Vec<Reg>, Vec<Reg>, Vec<Reg>) {
1032         (
1033             self.reg_vecs.uses.clone(),
1034             self.reg_vecs.defs.clone(),
1035             self.reg_vecs.mods.clone(),
1036         )
1037     }
1038 
get_empty_reg_vecs_test_framework_only(sanitized: bool) -> RegVecs1039     pub fn get_empty_reg_vecs_test_framework_only(sanitized: bool) -> RegVecs {
1040         RegVecs::new(sanitized)
1041     }
1042 }
1043 
1044 // Everything else is not visible outside the regalloc.rs interface.
1045 
1046 // There is one of these per function.  Note that `defs` and `mods` lose the
1047 // `Writable` constraint at this point.  This is for convenience of having all
1048 // three vectors be the same type, but comes at the cost of the loss of being
1049 // able to differentiate readonly vs read/write registers in the Rust type
1050 // system.
1051 #[derive(Debug)]
1052 pub struct RegVecs {
1053     pub uses: Vec<Reg>,
1054     pub defs: Vec<Reg>,
1055     pub mods: Vec<Reg>,
1056     sanitized: bool,
1057 }
1058 
1059 impl RegVecs {
new(sanitized: bool) -> Self1060     pub fn new(sanitized: bool) -> Self {
1061         Self {
1062             uses: vec![],
1063             defs: vec![],
1064             mods: vec![],
1065             sanitized,
1066         }
1067     }
is_sanitized(&self) -> bool1068     pub fn is_sanitized(&self) -> bool {
1069         self.sanitized
1070     }
set_sanitized(&mut self, sanitized: bool)1071     pub fn set_sanitized(&mut self, sanitized: bool) {
1072         self.sanitized = sanitized;
1073     }
clear(&mut self)1074     pub fn clear(&mut self) {
1075         self.uses.clear();
1076         self.defs.clear();
1077         self.mods.clear();
1078     }
1079 }
1080 
1081 // There is one of these per insn, so try and keep it as compact as possible.
1082 // I think this should fit in 16 bytes.
1083 #[derive(Clone, Debug)]
1084 pub struct RegVecBounds {
1085     // These are the group start indices in RegVecs.{uses, defs, mods}.
1086     pub uses_start: u32,
1087     pub defs_start: u32,
1088     pub mods_start: u32,
1089     // And these are the group lengths.  This does limit each instruction to
1090     // mentioning only 256 registers in any group, but that does not seem like a
1091     // problem.
1092     pub uses_len: u8,
1093     pub defs_len: u8,
1094     pub mods_len: u8,
1095 }
1096 
1097 impl RegVecBounds {
new() -> Self1098     pub fn new() -> Self {
1099         Self {
1100             uses_start: 0,
1101             defs_start: 0,
1102             mods_start: 0,
1103             uses_len: 0,
1104             defs_len: 0,
1105             mods_len: 0,
1106         }
1107     }
1108 }
1109 
1110 // This is the primary structure.  We compute just one of these for an entire
1111 // function.
1112 pub struct RegVecsAndBounds {
1113     // The three vectors of registers.  These can be arbitrarily long.
1114     pub vecs: RegVecs,
1115     // Admin info which tells us the location, for each insn, of its register
1116     // groups in `vecs`.
1117     pub bounds: TypedIxVec<InstIx, RegVecBounds>,
1118 }
1119 
1120 impl RegVecsAndBounds {
new(vecs: RegVecs, bounds: TypedIxVec<InstIx, RegVecBounds>) -> Self1121     pub fn new(vecs: RegVecs, bounds: TypedIxVec<InstIx, RegVecBounds>) -> Self {
1122         Self { vecs, bounds }
1123     }
is_sanitized(&self) -> bool1124     pub fn is_sanitized(&self) -> bool {
1125         self.vecs.sanitized
1126     }
1127     #[allow(dead_code)] // XXX for some reason, Rustc 1.43.1 thinks this is currently unused.
num_insns(&self) -> u321128     pub fn num_insns(&self) -> u32 {
1129         self.bounds.len()
1130     }
1131 }
1132 
1133 //=============================================================================
1134 // Register uses: convenience interface
1135 
1136 // Some call sites want to get reg use information as three Sets.  This is a
1137 // "convenience facility" which is easier to use but much slower than working
1138 // with a whole-function `RegVecsAndBounds`.  It shouldn't be used on critical
1139 // paths.
1140 #[derive(Debug)]
1141 pub struct RegSets {
1142     pub uses: Set<Reg>, // registers that are read.
1143     pub defs: Set<Reg>, // registers that are written.
1144     pub mods: Set<Reg>, // registers that are modified.
1145     sanitized: bool,
1146 }
1147 
1148 impl RegSets {
new(sanitized: bool) -> Self1149     pub fn new(sanitized: bool) -> Self {
1150         Self {
1151             uses: Set::<Reg>::empty(),
1152             defs: Set::<Reg>::empty(),
1153             mods: Set::<Reg>::empty(),
1154             sanitized,
1155         }
1156     }
1157 
is_sanitized(&self) -> bool1158     pub fn is_sanitized(&self) -> bool {
1159         self.sanitized
1160     }
1161 }
1162 
1163 impl RegVecsAndBounds {
1164     /* !!not RegSets!! */
1165     #[inline(never)]
1166     // Convenience function.  Try to avoid using this.
get_reg_sets_for_iix(&self, iix: InstIx) -> RegSets1167     pub fn get_reg_sets_for_iix(&self, iix: InstIx) -> RegSets {
1168         let bounds = &self.bounds[iix];
1169         let mut regsets = RegSets::new(self.vecs.sanitized);
1170         for i in bounds.uses_start as usize..bounds.uses_start as usize + bounds.uses_len as usize {
1171             regsets.uses.insert(self.vecs.uses[i]);
1172         }
1173         for i in bounds.defs_start as usize..bounds.defs_start as usize + bounds.defs_len as usize {
1174             regsets.defs.insert(self.vecs.defs[i]);
1175         }
1176         for i in bounds.mods_start as usize..bounds.mods_start as usize + bounds.mods_len as usize {
1177             regsets.mods.insert(self.vecs.mods[i]);
1178         }
1179         regsets
1180     }
1181 }
1182 
1183 //=============================================================================
1184 // Definitions of the "real register universe".
1185 
1186 // A "Real Register Universe" is a read-only structure that contains all
1187 // information about real registers on a given host.  It serves several
1188 // purposes:
1189 //
1190 // * defines the mapping from real register indices to the registers
1191 //   themselves
1192 //
1193 // * defines the size of the initial section of that mapping that is available
1194 //   to the register allocator for use, so that it can treat the registers
1195 //   under its control as a zero based, contiguous array.  This is important
1196 //   for its efficiency.
1197 //
1198 // * gives meaning to Set<RealReg>, which otherwise would merely be a bunch of
1199 //   bits.
1200 
1201 #[derive(Clone, Debug)]
1202 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
1203 pub struct RealRegUniverse {
1204     // The registers themselves.  All must be real registers, and all must
1205     // have their index number (.get_index()) equal to the array index here,
1206     // since this is the only place where we map index numbers to actual
1207     // registers.
1208     pub regs: Vec<(RealReg, String)>,
1209 
1210     // This is the size of the initial section of `regs` that is available to
1211     // the allocator.  It must be <= `regs`.len().
1212     pub allocable: usize,
1213 
1214     // Information about groups of allocable registers. Used to quickly address
1215     // only a group of allocable registers belonging to the same register class.
1216     // Indexes into `allocable_by_class` are RegClass values, such as
1217     // RegClass::F32. If the resulting entry is `None` then there are no
1218     // registers in that class.  Otherwise the value is a `RegClassInfo`, which
1219     // provides a register range and possibly information about fixed uses.
1220     pub allocable_by_class: [Option<RegClassInfo>; NUM_REG_CLASSES],
1221 }
1222 
1223 /// Information about a single register class in the `RealRegUniverse`.
1224 #[derive(Clone, Copy, Debug)]
1225 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
1226 pub struct RegClassInfo {
1227     // Range of allocatable registers in this register class, in terms of
1228     // register indices.
1229     //
1230     // A range (first, last) specifies the range of entries in
1231     // `RealRegUniverse.regs` corresponding to that class.  The range includes
1232     // both `first` and `last`.
1233     //
1234     // In all cases, `last` must be < `RealRegUniverse.allocable`.  In other
1235     // words, all ranges together in `allocable_by_class` must describe only the
1236     // allocable prefix of `regs`.
1237     //
1238     // For example, let's say
1239     //    allocable_by_class[RegClass::F32] ==
1240     //      Some(RegClassInfo { first: 10, last: 14, .. })
1241     // Then regs[10], regs[11], regs[12], regs[13], and regs[14] give all
1242     // registers of register class RegClass::F32.
1243     //
1244     // The effect of the above is that registers in `regs` must form
1245     // contiguous groups. This is checked by RealRegUniverse::check_is_sane().
1246     pub first: usize,
1247     pub last: usize,
1248 
1249     // A register, if any, that is *guaranteed* not to be used as a fixed use
1250     // in any code, and so that the register allocator can statically reserve
1251     // for its own use as a temporary. Some register allocators may need such
1252     // a register for various maneuvers, for example a spillslot-to-spillslot
1253     // move when no (other) registers are free.
1254     pub suggested_scratch: Option<usize>,
1255 }
1256 
1257 impl RealRegUniverse {
1258     /// Show it in a pretty way.
show(&self) -> Vec<String>1259     pub fn show(&self) -> Vec<String> {
1260         let mut res = vec![];
1261         // Show the allocables
1262         for class_num in 0..NUM_REG_CLASSES {
1263             let class_info = match &self.allocable_by_class[class_num] {
1264                 None => continue,
1265                 Some(info) => info,
1266             };
1267             let class = RegClass::rc_from_u32(class_num as u32);
1268             let mut class_str = "class ".to_string()
1269                 + &class.long_name().to_string()
1270                 + &"(".to_string()
1271                 + &class.short_name().to_string()
1272                 + &") at ".to_string();
1273             class_str = class_str + &format!("[{} .. {}]: ", class_info.first, class_info.last);
1274             for ix in class_info.first..=class_info.last {
1275                 class_str = class_str + &self.regs[ix].1;
1276                 if let Some(suggested_ix) = class_info.suggested_scratch {
1277                     if ix == suggested_ix {
1278                         class_str = class_str + "*";
1279                     }
1280                 }
1281                 class_str = class_str + " ";
1282             }
1283             res.push(class_str);
1284         }
1285         // And the non-allocables
1286         if self.allocable < self.regs.len() {
1287             let mut stragglers = format!(
1288                 "not allocable at [{} .. {}]: ",
1289                 self.allocable,
1290                 self.regs.len() - 1
1291             );
1292             for ix in self.allocable..self.regs.len() {
1293                 stragglers = stragglers + &self.regs[ix].1 + &" ".to_string();
1294             }
1295             res.push(stragglers);
1296         }
1297         res
1298     }
1299 
1300     /// Check that the given universe satisfies various invariants, and panic
1301     /// if not.  All the invariants are important.
check_is_sane(&self)1302     pub fn check_is_sane(&self) {
1303         let regs_len = self.regs.len();
1304         let regs_allocable = self.allocable;
1305         // The universe must contain at most 256 registers.  That's because
1306         // `Reg` only has an 8-bit index value field, so if the universe
1307         // contained more than 256 registers, we'd never be able to index into
1308         // entries 256 and above.  This is no limitation in practice since all
1309         // targets we're interested in contain (many) fewer than 256 regs in
1310         // total.
1311         let mut ok = regs_len <= 256;
1312         // The number of allocable registers must not exceed the number of
1313         // `regs` presented.  In general it will be less, since the universe
1314         // will list some registers (stack pointer, etc) which are not
1315         // available for allocation.
1316         if ok {
1317             ok = regs_allocable <= regs_len;
1318         }
1319         // All registers must have an index value which points back at the
1320         // `regs` slot they are in.  Also they really must be real regs.
1321         if ok {
1322             for i in 0..regs_len {
1323                 let (reg, _name) = &self.regs[i];
1324                 if ok && (reg.to_reg().is_virtual() || reg.get_index() != i) {
1325                     ok = false;
1326                 }
1327             }
1328         }
1329         // The allocatable regclass groupings defined by `allocable_first` and
1330         // `allocable_last` must be contiguous.
1331         if ok {
1332             let mut regclass_used = [false; NUM_REG_CLASSES];
1333             for rc in 0..NUM_REG_CLASSES {
1334                 regclass_used[rc] = false;
1335             }
1336             for i in 0..regs_allocable {
1337                 let (reg, _name) = &self.regs[i];
1338                 let rc = reg.get_class().rc_to_u32() as usize;
1339                 regclass_used[rc] = true;
1340             }
1341             // Scan forward through each grouping, checking that the listed
1342             // registers really are of the claimed class.  Also count the
1343             // total number visited.  This seems a fairly reliable way to
1344             // ensure that the groupings cover all allocated registers exactly
1345             // once, and that all classes are contiguous groups.
1346             let mut regs_visited = 0;
1347             for rc in 0..NUM_REG_CLASSES {
1348                 match &self.allocable_by_class[rc] {
1349                     &None => {
1350                         if regclass_used[rc] {
1351                             ok = false;
1352                         }
1353                     }
1354                     &Some(RegClassInfo {
1355                         first,
1356                         last,
1357                         suggested_scratch,
1358                     }) => {
1359                         if !regclass_used[rc] {
1360                             ok = false;
1361                         }
1362                         if ok {
1363                             for i in first..last + 1 {
1364                                 let (reg, _name) = &self.regs[i];
1365                                 if ok && RegClass::rc_from_u32(rc as u32) != reg.get_class() {
1366                                     ok = false;
1367                                 }
1368                                 regs_visited += 1;
1369                             }
1370                         }
1371                         if ok {
1372                             if let Some(s) = suggested_scratch {
1373                                 if s < first || s > last {
1374                                     ok = false;
1375                                 }
1376                             }
1377                         }
1378                     }
1379                 }
1380             }
1381             if ok && regs_visited != regs_allocable {
1382                 ok = false;
1383             }
1384         }
1385         // So finally ..
1386         if !ok {
1387             panic!("RealRegUniverse::check_is_sane: invalid RealRegUniverse");
1388         }
1389     }
1390 }
1391 
1392 //=============================================================================
1393 // Representing and printing of live range fragments.
1394 
1395 #[derive(Copy, Clone, Hash, PartialEq, Eq, Ord)]
1396 // There are four "points" within an instruction that are of interest, and
1397 // these have a total ordering: R < U < D < S.  They are:
1398 //
1399 // * R(eload): this is where any reload insns for the insn itself are
1400 //   considered to live.
1401 //
1402 // * U(se): this is where the insn is considered to use values from those of
1403 //   its register operands that appear in a Read or Modify role.
1404 //
1405 // * D(ef): this is where the insn is considered to define new values for
1406 //   those of its register operands that appear in a Write or Modify role.
1407 //
1408 // * S(pill): this is where any spill insns for the insn itself are considered
1409 //   to live.
1410 //
1411 // Instructions in the incoming Func may only exist at the U and D points,
1412 // and so their associated live range fragments will only mention the U and D
1413 // points.  However, when adding spill code, we need a way to represent live
1414 // ranges involving the added spill and reload insns, in which case R and S
1415 // come into play:
1416 //
1417 // * A reload for instruction i is considered to be live from i.R to i.U.
1418 //
1419 // * A spill for instruction i is considered to be live from i.D to i.S.
1420 
1421 pub enum Point {
1422     // The values here are important.  Don't change them.
1423     Reload = 0,
1424     Use = 1,
1425     Def = 2,
1426     Spill = 3,
1427 }
1428 
1429 impl Point {
1430     #[inline(always)]
is_reload(self) -> bool1431     pub fn is_reload(self) -> bool {
1432         match self {
1433             Point::Reload => true,
1434             _ => false,
1435         }
1436     }
1437     #[inline(always)]
is_use(self) -> bool1438     pub fn is_use(self) -> bool {
1439         match self {
1440             Point::Use => true,
1441             _ => false,
1442         }
1443     }
1444     #[inline(always)]
is_def(self) -> bool1445     pub fn is_def(self) -> bool {
1446         match self {
1447             Point::Def => true,
1448             _ => false,
1449         }
1450     }
1451     #[inline(always)]
is_spill(self) -> bool1452     pub fn is_spill(self) -> bool {
1453         match self {
1454             Point::Spill => true,
1455             _ => false,
1456         }
1457     }
1458     #[inline(always)]
is_use_or_def(self) -> bool1459     pub fn is_use_or_def(self) -> bool {
1460         self.is_use() || self.is_def()
1461     }
1462 }
1463 
1464 impl PartialOrd for Point {
1465     // In short .. R < U < D < S.  This is probably what would be #derive'd
1466     // anyway, but we need to be sure.
partial_cmp(&self, other: &Self) -> Option<Ordering>1467     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1468         (*self as u32).partial_cmp(&(*other as u32))
1469     }
1470 }
1471 
1472 // See comments below on `RangeFrag` for the meaning of `InstPoint`.
1473 #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
1474 pub struct InstPoint {
1475     /// This is conceptually:
1476     ///   pub iix: InstIx,
1477     ///   pub pt: Point,
1478     ///
1479     /// but packed into a single 32 bit word, so as
1480     /// (1) to ensure it is only 32 bits (and hence to guarantee that `RangeFrag`
1481     ///     is 64 bits), and
1482     /// (2) to make it possible to implement `PartialOrd` using `PartialOrd`
1483     ///     directly on 32 bit words (and hence we let it be derived).
1484     ///
1485     /// This has the format:
1486     ///    InstIx as bits 31:2,  Point as bits 1:0.
1487     ///
1488     /// It does give the slight limitation that all InstIxs must be < 2^30, but
1489     /// that's hardly a big deal: the analysis module rejects any input with 2^24
1490     /// or more Insns.
1491     ///
1492     /// Do not access this directly:
1493     bits: u32,
1494 }
1495 
1496 impl InstPoint {
1497     #[inline(always)]
new(iix: InstIx, pt: Point) -> Self1498     pub fn new(iix: InstIx, pt: Point) -> Self {
1499         let iix_n = iix.get();
1500         assert!(iix_n < 0x4000_0000u32);
1501         let pt_n = pt as u32;
1502         InstPoint {
1503             bits: (iix_n << 2) | pt_n,
1504         }
1505     }
1506     #[inline(always)]
iix(self) -> InstIx1507     pub fn iix(self) -> InstIx {
1508         InstIx::new(self.bits >> 2)
1509     }
1510     #[inline(always)]
pt(self) -> Point1511     pub fn pt(self) -> Point {
1512         match self.bits & 3 {
1513             0 => Point::Reload,
1514             1 => Point::Use,
1515             2 => Point::Def,
1516             3 => Point::Spill,
1517             // This can never happen, but rustc doesn't seem to know that.
1518             _ => panic!("InstPt::pt: unreachable case"),
1519         }
1520     }
1521     #[inline(always)]
set_iix(&mut self, iix: InstIx)1522     pub fn set_iix(&mut self, iix: InstIx) {
1523         let iix_n = iix.get();
1524         assert!(iix_n < 0x4000_0000u32);
1525         self.bits = (iix_n << 2) | (self.bits & 3);
1526     }
1527     #[inline(always)]
set_pt(&mut self, pt: Point)1528     pub fn set_pt(&mut self, pt: Point) {
1529         self.bits = (self.bits & 0xFFFF_FFFCu32) | pt as u32;
1530     }
1531     #[inline(always)]
new_reload(iix: InstIx) -> Self1532     pub fn new_reload(iix: InstIx) -> Self {
1533         InstPoint::new(iix, Point::Reload)
1534     }
1535     #[inline(always)]
new_use(iix: InstIx) -> Self1536     pub fn new_use(iix: InstIx) -> Self {
1537         InstPoint::new(iix, Point::Use)
1538     }
1539     #[inline(always)]
new_def(iix: InstIx) -> Self1540     pub fn new_def(iix: InstIx) -> Self {
1541         InstPoint::new(iix, Point::Def)
1542     }
1543     #[inline(always)]
new_spill(iix: InstIx) -> Self1544     pub fn new_spill(iix: InstIx) -> Self {
1545         InstPoint::new(iix, Point::Spill)
1546     }
1547     #[inline(always)]
invalid_value() -> Self1548     pub fn invalid_value() -> Self {
1549         Self {
1550             bits: 0xFFFF_FFFFu32,
1551         }
1552     }
1553     #[inline(always)]
max_value() -> Self1554     pub fn max_value() -> Self {
1555         Self {
1556             bits: 0xFFFF_FFFFu32,
1557         }
1558     }
1559     #[inline(always)]
min_value() -> Self1560     pub fn min_value() -> Self {
1561         Self { bits: 0u32 }
1562     }
1563 }
1564 
1565 impl fmt::Debug for InstPoint {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result1566     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1567         write!(
1568             fmt,
1569             "{:?}{}",
1570             self.iix(),
1571             match self.pt() {
1572                 Point::Reload => ".r",
1573                 Point::Use => ".u",
1574                 Point::Def => ".d",
1575                 Point::Spill => ".s",
1576             }
1577         )
1578     }
1579 }
1580 
1581 //=============================================================================
1582 // Live Range Fragments, and their metrics
1583 
1584 // A Live Range Fragment (RangeFrag) describes a consecutive sequence of one or
1585 // more instructions, in which a Reg is "live".  The sequence must exist
1586 // entirely inside only one basic block.
1587 //
1588 // However, merely indicating the start and end instruction numbers isn't
1589 // enough: we must also include a "Use or Def" indication.  These indicate two
1590 // different "points" within each instruction: the Use position, where
1591 // incoming registers are read, and the Def position, where outgoing registers
1592 // are written.  The Use position is considered to come before the Def
1593 // position, as described for `Point` above.
1594 //
1595 // When we come to generate spill/restore live ranges, Point::S and Point::R
1596 // also come into play.  Live ranges (and hence, RangeFrags) that do not perform
1597 // spills or restores should not use either of Point::S or Point::R.
1598 //
1599 // The set of positions denoted by
1600 //
1601 //    {0 .. #insns-1} x {Reload point, Use point, Def point, Spill point}
1602 //
1603 // is exactly the set of positions that we need to keep track of when mapping
1604 // live ranges to registers.  This the reason for the type InstPoint.  Note
1605 // that InstPoint values have a total ordering, at least within a single basic
1606 // block: the insn number is used as the primary key, and the Point part is
1607 // the secondary key, with Reload < Use < Def < Spill.
1608 #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
1609 pub struct RangeFrag {
1610     pub first: InstPoint,
1611     pub last: InstPoint,
1612 }
1613 
1614 impl fmt::Debug for RangeFrag {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result1615     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1616         write!(fmt, "(RF: {:?}-{:?})", self.first, self.last)
1617     }
1618 }
1619 
1620 impl RangeFrag {
1621     #[allow(dead_code)] // XXX for some reason, Rustc 1.43.1 thinks this is unused.
new(first: InstPoint, last: InstPoint) -> Self1622     pub fn new(first: InstPoint, last: InstPoint) -> Self {
1623         debug_assert!(first <= last);
1624         RangeFrag { first, last }
1625     }
1626 
invalid_value() -> Self1627     pub fn invalid_value() -> Self {
1628         Self {
1629             first: InstPoint::invalid_value(),
1630             last: InstPoint::invalid_value(),
1631         }
1632     }
1633 
new_with_metrics<F: Function>( f: &F, bix: BlockIx, first: InstPoint, last: InstPoint, count: u16, ) -> (Self, RangeFragMetrics)1634     pub fn new_with_metrics<F: Function>(
1635         f: &F,
1636         bix: BlockIx,
1637         first: InstPoint,
1638         last: InstPoint,
1639         count: u16,
1640     ) -> (Self, RangeFragMetrics) {
1641         debug_assert!(f.block_insns(bix).len() >= 1);
1642         debug_assert!(f.block_insns(bix).contains(first.iix()));
1643         debug_assert!(f.block_insns(bix).contains(last.iix()));
1644         debug_assert!(first <= last);
1645         if first == last {
1646             debug_assert!(count == 1);
1647         }
1648         let first_iix_in_block = f.block_insns(bix).first();
1649         let last_iix_in_block = f.block_insns(bix).last();
1650         let first_pt_in_block = InstPoint::new_use(first_iix_in_block);
1651         let last_pt_in_block = InstPoint::new_def(last_iix_in_block);
1652         let kind = match (first == first_pt_in_block, last == last_pt_in_block) {
1653             (false, false) => RangeFragKind::Local,
1654             (false, true) => RangeFragKind::LiveOut,
1655             (true, false) => RangeFragKind::LiveIn,
1656             (true, true) => RangeFragKind::Thru,
1657         };
1658         (
1659             RangeFrag { first, last },
1660             RangeFragMetrics { bix, kind, count },
1661         )
1662     }
1663 }
1664 
1665 // Comparison of RangeFrags.  They form a partial order.
1666 
cmp_range_frags(f1: &RangeFrag, f2: &RangeFrag) -> Option<Ordering>1667 pub fn cmp_range_frags(f1: &RangeFrag, f2: &RangeFrag) -> Option<Ordering> {
1668     if f1.last < f2.first {
1669         return Some(Ordering::Less);
1670     }
1671     if f1.first > f2.last {
1672         return Some(Ordering::Greater);
1673     }
1674     if f1.first == f2.first && f1.last == f2.last {
1675         return Some(Ordering::Equal);
1676     }
1677     None
1678 }
1679 
1680 impl RangeFrag {
contains(&self, ipt: &InstPoint) -> bool1681     pub fn contains(&self, ipt: &InstPoint) -> bool {
1682         self.first <= *ipt && *ipt <= self.last
1683     }
1684 }
1685 
1686 // A handy summary hint for a RangeFrag.  Note that none of these are correct
1687 // if the RangeFrag has been extended so as to cover multiple basic blocks.
1688 // But that ("RangeFrag compression") is something done locally within each
1689 // algorithm (BT and LSRA).  The analysis-phase output will not include any
1690 // such compressed RangeFrags.
1691 #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
1692 pub enum RangeFragKind {
1693     Local,   // Fragment exists entirely inside one block
1694     LiveIn,  // Fragment is live in to a block, but ends inside it
1695     LiveOut, // Fragment is live out of a block, but starts inside it
1696     Thru,    // Fragment is live through the block (starts and ends outside it)
1697 }
1698 
1699 impl fmt::Debug for RangeFragKind {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result1700     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1701         match self {
1702             RangeFragKind::Local => write!(fmt, "Local"),
1703             RangeFragKind::LiveIn => write!(fmt, "LiveIn"),
1704             RangeFragKind::LiveOut => write!(fmt, "LiveOut"),
1705             RangeFragKind::Thru => write!(fmt, "Thru"),
1706         }
1707     }
1708 }
1709 
1710 // `RangeFrags` resulting from the initial analysis phase (analysis_data_flow.rs)
1711 // exist only within single basic blocks, and therefore have some associated
1712 // metrics, held by `RangeFragMetrics`:
1713 //
1714 // * a `count` field, which is a u16 indicating how often the associated storage
1715 //   unit (Reg) is mentioned inside the RangeFrag.  It is assumed that the RangeFrag
1716 //   is associated with some Reg.  If not, the `count` field is meaningless.  This
1717 //   field has no effect on the correctness of the resulting allocation.  It is used
1718 //   however in the estimation of `VirtualRange` spill costs, which are important
1719 //   for prioritising which `VirtualRange`s get assigned a register vs which have
1720 //   to be spilled.
1721 //
1722 // * `bix` field, which indicates which `Block` the fragment exists in.  This
1723 //   field is actually redundant, since the containing `Block` can be inferred,
1724 //   laboriously, from the associated `RangeFrag`s `first` and `last` fields,
1725 //   providing you have an `InstIxToBlockIx` mapping table to hand.  It is included
1726 //   here for convenience.
1727 //
1728 // * `kind` is another convenience field, indicating how the range is included
1729 //   within its owning block.
1730 //
1731 // The analysis phase (fn `deref_and_compress_sorted_range_frag_ixs`)
1732 // compresses ranges and as a result breaks the invariant that a `RangeFrag`
1733 // exists only within a single `Block`.  For a `RangeFrag` spanning multiple
1734 // `Block`s, all three `RangeFragMetric` fields are meaningless.  This is the
1735 // reason for separating `RangeFrag` and `RangeFragMetrics` -- so that it is
1736 // possible to merge `RangeFrag`s without being forced to create fake values
1737 // for the metrics fields.
1738 #[derive(Clone, PartialEq)]
1739 pub struct RangeFragMetrics {
1740     pub bix: BlockIx,
1741     pub kind: RangeFragKind,
1742     pub count: u16,
1743 }
1744 
1745 impl fmt::Debug for RangeFragMetrics {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result1746     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1747         write!(
1748             fmt,
1749             "(RFM: {:?}, count={}, {:?})",
1750             self.kind, self.count, self.bix
1751         )
1752     }
1753 }
1754 
1755 //=============================================================================
1756 // Vectors of RangeFragIxs, sorted so that the associated RangeFrags are in
1757 // ascending order, per their InstPoint fields.  The associated RangeFrags may
1758 // not overlap.
1759 //
1760 // The "fragment environment" (usually called "frag_env"), to which the
1761 // RangeFragIxs refer, is not stored here.
1762 
1763 #[derive(Clone)]
1764 pub struct SortedRangeFragIxs {
1765     pub frag_ixs: SmallVec<[RangeFragIx; 4]>,
1766 }
1767 
1768 impl fmt::Debug for SortedRangeFragIxs {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result1769     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1770         self.frag_ixs.fmt(fmt)
1771     }
1772 }
1773 
1774 impl SortedRangeFragIxs {
check(&self, fenv: &TypedIxVec<RangeFragIx, RangeFrag>)1775     pub(crate) fn check(&self, fenv: &TypedIxVec<RangeFragIx, RangeFrag>) {
1776         for i in 1..self.frag_ixs.len() {
1777             let prev_frag = &fenv[self.frag_ixs[i - 1]];
1778             let this_frag = &fenv[self.frag_ixs[i]];
1779             if cmp_range_frags(prev_frag, this_frag) != Some(Ordering::Less) {
1780                 panic!("SortedRangeFragIxs::check: vector not ok");
1781             }
1782         }
1783     }
1784 
sort(&mut self, fenv: &TypedIxVec<RangeFragIx, RangeFrag>)1785     pub fn sort(&mut self, fenv: &TypedIxVec<RangeFragIx, RangeFrag>) {
1786         self.frag_ixs.sort_unstable_by(|fix_a, fix_b| {
1787             match cmp_range_frags(&fenv[*fix_a], &fenv[*fix_b]) {
1788                 Some(Ordering::Less) => Ordering::Less,
1789                 Some(Ordering::Greater) => Ordering::Greater,
1790                 Some(Ordering::Equal) | None => {
1791                     panic!("SortedRangeFragIxs::sort: overlapping Frags!")
1792                 }
1793             }
1794         });
1795     }
1796 
new( frag_ixs: SmallVec<[RangeFragIx; 4]>, fenv: &TypedIxVec<RangeFragIx, RangeFrag>, ) -> Self1797     pub fn new(
1798         frag_ixs: SmallVec<[RangeFragIx; 4]>,
1799         fenv: &TypedIxVec<RangeFragIx, RangeFrag>,
1800     ) -> Self {
1801         let mut res = SortedRangeFragIxs { frag_ixs };
1802         // check the source is ordered, and clone (or sort it)
1803         res.sort(fenv);
1804         res.check(fenv);
1805         res
1806     }
1807 
unit(fix: RangeFragIx, fenv: &TypedIxVec<RangeFragIx, RangeFrag>) -> Self1808     pub fn unit(fix: RangeFragIx, fenv: &TypedIxVec<RangeFragIx, RangeFrag>) -> Self {
1809         let mut res = SortedRangeFragIxs {
1810             frag_ixs: SmallVec::<[RangeFragIx; 4]>::new(),
1811         };
1812         res.frag_ixs.push(fix);
1813         res.check(fenv);
1814         res
1815     }
1816 
1817     /// Does this sorted list of range fragments contain the given instruction point?
contains_pt(&self, fenv: &TypedIxVec<RangeFragIx, RangeFrag>, pt: InstPoint) -> bool1818     pub fn contains_pt(&self, fenv: &TypedIxVec<RangeFragIx, RangeFrag>, pt: InstPoint) -> bool {
1819         self.frag_ixs
1820             .binary_search_by(|&ix| {
1821                 let frag = &fenv[ix];
1822                 if pt < frag.first {
1823                     Ordering::Greater
1824                 } else if pt >= frag.first && pt <= frag.last {
1825                     Ordering::Equal
1826                 } else {
1827                     Ordering::Less
1828                 }
1829             })
1830             .is_ok()
1831     }
1832 }
1833 
1834 //=============================================================================
1835 // Vectors of RangeFrags, sorted so that they are in ascending order, per
1836 // their InstPoint fields.  The RangeFrags may not overlap.
1837 
1838 #[derive(Clone)]
1839 pub struct SortedRangeFrags {
1840     pub frags: SmallVec<[RangeFrag; 4]>,
1841 }
1842 
1843 impl fmt::Debug for SortedRangeFrags {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result1844     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1845         self.frags.fmt(fmt)
1846     }
1847 }
1848 
1849 impl SortedRangeFrags {
unit(frag: RangeFrag) -> Self1850     pub fn unit(frag: RangeFrag) -> Self {
1851         let mut res = SortedRangeFrags {
1852             frags: SmallVec::<[RangeFrag; 4]>::new(),
1853         };
1854         res.frags.push(frag);
1855         res
1856     }
1857 
empty() -> Self1858     pub fn empty() -> Self {
1859         Self {
1860             frags: SmallVec::<[RangeFrag; 4]>::new(),
1861         }
1862     }
1863 
overlaps(&self, other: &Self) -> bool1864     pub fn overlaps(&self, other: &Self) -> bool {
1865         // Since both vectors are sorted and individually non-overlapping, we
1866         // can establish that they are mutually non-overlapping by walking
1867         // them simultaneously and checking, at each step, that there is a
1868         // unique "next lowest" frag available.
1869         let frags1 = &self.frags;
1870         let frags2 = &other.frags;
1871         let n1 = frags1.len();
1872         let n2 = frags2.len();
1873         let mut c1 = 0;
1874         let mut c2 = 0;
1875         loop {
1876             if c1 >= n1 || c2 >= n2 {
1877                 // We made it to the end of one (or both) vectors without
1878                 // finding any conflicts.
1879                 return false; // "no overlaps"
1880             }
1881             let f1 = &frags1[c1];
1882             let f2 = &frags2[c2];
1883             match cmp_range_frags(f1, f2) {
1884                 Some(Ordering::Less) => c1 += 1,
1885                 Some(Ordering::Greater) => c2 += 1,
1886                 _ => {
1887                     // There's no unique "next frag" -- either they are
1888                     // identical, or they overlap.  So we're done.
1889                     return true; // "there's an overlap"
1890                 }
1891             }
1892         }
1893     }
1894 
1895     /// Does this sorted list of range fragments contain the given instruction point?
contains_pt(&self, pt: InstPoint) -> bool1896     pub fn contains_pt(&self, pt: InstPoint) -> bool {
1897         self.frags
1898             .binary_search_by(|frag| {
1899                 if pt < frag.first {
1900                     Ordering::Greater
1901                 } else if pt >= frag.first && pt <= frag.last {
1902                     Ordering::Equal
1903                 } else {
1904                     Ordering::Less
1905                 }
1906             })
1907             .is_ok()
1908     }
1909 }
1910 
1911 //=============================================================================
1912 // Representing spill costs.  A spill cost can either be infinite, in which
1913 // case the associated VirtualRange may not be spilled, because it's already a
1914 // spill/reload range.  Or it can be finite, in which case it must be a 32-bit
1915 // floating point number, which is (in the IEEE754 meaning of the terms)
1916 // non-infinite, non-NaN and it must be non negative.  In fact it's
1917 // meaningless for a VLR to have a zero spill cost (how could that really be
1918 // the case?) but we allow it here for convenience.
1919 
1920 #[derive(Copy, Clone)]
1921 pub enum SpillCost {
1922     Infinite,    // Infinite, positive
1923     Finite(f32), // Finite, non-negative
1924 }
1925 
1926 impl fmt::Debug for SpillCost {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result1927     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1928         match self {
1929             SpillCost::Infinite => write!(fmt, "INFINITY"),
1930             SpillCost::Finite(c) => write!(fmt, "{:<.3}", c),
1931         }
1932     }
1933 }
1934 
1935 impl SpillCost {
1936     #[inline(always)]
zero() -> Self1937     pub fn zero() -> Self {
1938         SpillCost::Finite(0.0)
1939     }
1940     #[inline(always)]
infinite() -> Self1941     pub fn infinite() -> Self {
1942         SpillCost::Infinite
1943     }
1944     #[inline(always)]
finite(cost: f32) -> Self1945     pub fn finite(cost: f32) -> Self {
1946         // "`is_normal` returns true if the number is neither zero, infinite,
1947         // subnormal, or NaN."
1948         assert!(cost.is_normal() || cost == 0.0);
1949         // And also it can't be negative.
1950         assert!(cost >= 0.0);
1951         // Somewhat arbitrarily ..
1952         assert!(cost < 1e18);
1953         SpillCost::Finite(cost)
1954     }
1955     #[inline(always)]
is_zero(&self) -> bool1956     pub fn is_zero(&self) -> bool {
1957         match self {
1958             SpillCost::Infinite => false,
1959             SpillCost::Finite(c) => *c == 0.0,
1960         }
1961     }
1962     #[inline(always)]
is_infinite(&self) -> bool1963     pub fn is_infinite(&self) -> bool {
1964         match self {
1965             SpillCost::Infinite => true,
1966             SpillCost::Finite(_) => false,
1967         }
1968     }
1969     #[inline(always)]
is_finite(&self) -> bool1970     pub fn is_finite(&self) -> bool {
1971         !self.is_infinite()
1972     }
1973     #[inline(always)]
is_less_than(&self, other: &Self) -> bool1974     pub fn is_less_than(&self, other: &Self) -> bool {
1975         match (self, other) {
1976             // Dubious .. both are infinity
1977             (SpillCost::Infinite, SpillCost::Infinite) => false,
1978             // finite < inf
1979             (SpillCost::Finite(_), SpillCost::Infinite) => true,
1980             // inf is not < finite
1981             (SpillCost::Infinite, SpillCost::Finite(_)) => false,
1982             // straightforward
1983             (SpillCost::Finite(c1), SpillCost::Finite(c2)) => c1 < c2,
1984         }
1985     }
1986     #[inline(always)]
add(&mut self, other: &Self)1987     pub fn add(&mut self, other: &Self) {
1988         match (*self, other) {
1989             (SpillCost::Finite(c1), SpillCost::Finite(c2)) => {
1990                 // The 10^18 limit above gives us a lot of headroom here, since max
1991                 // f32 is around 10^37.
1992                 *self = SpillCost::Finite(c1 + c2);
1993             }
1994             (_, _) => {
1995                 // All other cases produce an infinity.
1996                 *self = SpillCost::Infinite;
1997             }
1998         }
1999     }
2000 }
2001 
2002 //=============================================================================
2003 // Representing and printing live ranges.  These are represented by two
2004 // different but closely related types, RealRange and VirtualRange.
2005 
2006 // RealRanges are live ranges for real regs (RealRegs).  VirtualRanges are
2007 // live ranges for virtual regs (VirtualRegs).  VirtualRanges are the
2008 // fundamental unit of allocation.
2009 //
2010 // A RealRange pairs a RealReg with a vector of RangeFragIxs in which it is
2011 // live.  The RangeFragIxs are indices into some vector of RangeFrags (a
2012 // "fragment environment", 'fenv'), which is not specified here.  They are
2013 // sorted so as to give ascending order to the RangeFrags which they refer to.
2014 //
2015 // A VirtualRange pairs a VirtualReg with a vector of RangeFrags in which it
2016 // is live.  Same scheme as for a RealRange, except it avoids the overhead of
2017 // having to indirect into the fragment environment.
2018 //
2019 // VirtualRanges also contain metrics:
2020 //
2021 // * `size` is the number of instructions in total spanned by the LR.  It must
2022 //   not be zero.
2023 //
2024 // * `total cost` is an abstractified measure of the cost of the LR.  Each
2025 //   basic block in which the range exists gives a contribution to the `total
2026 //   cost`, which is the number of times the register is mentioned in this
2027 //   block, multiplied by the estimated execution frequency for the block.
2028 //
2029 // * `spill_cost` is an abstractified measure of the cost of spilling the LR,
2030 //   and is the `total cost` divided by the `size`. The only constraint
2031 //   (w.r.t. correctness) is that normal LRs have a `Some` value, whilst
2032 //   `None` is reserved for live ranges created for spills and reloads and
2033 //   interpreted to mean "infinity".  This is needed to guarantee that
2034 //   allocation can always succeed in the worst case, in which all of the
2035 //   original live ranges of the program are spilled.
2036 //
2037 // RealRanges don't carry any metrics info since we are not trying to allocate
2038 // them.  We merely need to work around them.
2039 //
2040 // I find it helpful to think of a live range, both RealRange and
2041 // VirtualRange, as a "renaming equivalence class".  That is, if you rename
2042 // `reg` at some point inside `sorted_frags`, then you must rename *all*
2043 // occurrences of `reg` inside `sorted_frags`, since otherwise the program will
2044 // no longer work.
2045 
2046 #[derive(Clone)]
2047 pub struct RealRange {
2048     pub rreg: RealReg,
2049     pub sorted_frags: SortedRangeFragIxs,
2050     pub is_ref: bool,
2051 }
2052 
2053 impl fmt::Debug for RealRange {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result2054     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
2055         write!(
2056             fmt,
2057             "(RR: {:?}{}, {:?})",
2058             self.rreg,
2059             if self.is_ref { " REF" } else { "" },
2060             self.sorted_frags
2061         )
2062     }
2063 }
2064 
2065 impl RealRange {
show_with_rru(&self, univ: &RealRegUniverse) -> String2066     pub fn show_with_rru(&self, univ: &RealRegUniverse) -> String {
2067         format!(
2068             "(RR: {}{}, {:?})",
2069             self.rreg.to_reg().show_with_rru(univ),
2070             if self.is_ref { " REF" } else { "" },
2071             self.sorted_frags
2072         )
2073     }
2074 }
2075 
2076 // VirtualRanges are live ranges for virtual regs (VirtualRegs).  This does
2077 // carry metrics info and also the identity of the RealReg to which it
2078 // eventually got allocated.  (Or in the backtracking allocator, the identity
2079 // of the RealReg to which it is *currently* assigned; that may be undone at
2080 // some later point.)
2081 
2082 #[derive(Clone)]
2083 pub struct VirtualRange {
2084     pub vreg: VirtualReg,
2085     pub rreg: Option<RealReg>,
2086     pub sorted_frags: SortedRangeFrags,
2087     pub is_ref: bool,
2088     pub size: u16,
2089     pub total_cost: u32,
2090     pub spill_cost: SpillCost, // == total_cost / size
2091 }
2092 
2093 impl VirtualRange {
overlaps(&self, other: &Self) -> bool2094     pub fn overlaps(&self, other: &Self) -> bool {
2095         self.sorted_frags.overlaps(&other.sorted_frags)
2096     }
2097 }
2098 
2099 impl fmt::Debug for VirtualRange {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result2100     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
2101         write!(
2102             fmt,
2103             "(VR: {:?}{},",
2104             self.vreg,
2105             if self.is_ref { " REF" } else { "" }
2106         )?;
2107         if self.rreg.is_some() {
2108             write!(fmt, " -> {:?}", self.rreg.unwrap())?;
2109         }
2110         write!(
2111             fmt,
2112             " sz={}, tc={}, sc={:?}, {:?})",
2113             self.size, self.total_cost, self.spill_cost, self.sorted_frags
2114         )
2115     }
2116 }
2117 
2118 //=============================================================================
2119 // Some auxiliary/miscellaneous data structures that are useful: RegToRangesMaps
2120 
2121 // Mappings from RealRegs and VirtualRegs to the sets of RealRanges and VirtualRanges that
2122 // belong to them.  These are needed for BT's coalescing analysis and for the dataflow analysis
2123 // that supports reftype handling.
2124 
2125 pub struct RegToRangesMaps {
2126     // This maps RealReg indices to the set of RealRangeIxs for that RealReg.  Valid indices are
2127     // real register indices for all non-sanitised real regs; that is,
2128     // 0 .. RealRegUniverse::allocable, for ".." having the Rust meaning.  The Vecs of
2129     // RealRangeIxs are duplicate-free.  The SmallVec capacity of 6 was chosen after quite
2130     // some profiling, of CL/x64/newBE compiling ZenGarden.wasm -- a huge input, with many
2131     // relatively small functions.  Profiling was performed in August 2020, using Valgrind/DHAT.
2132     pub rreg_to_rlrs_map: Vec</*real reg ix, */ SmallVec<[RealRangeIx; 6]>>,
2133 
2134     // This maps VirtualReg indices to the set of VirtualRangeIxs for that VirtualReg.  Valid
2135     // indices are 0 .. Function::get_num_vregs().  For functions mostly translated from SSA,
2136     // most VirtualRegs will have just one VirtualRange, and there are a lot of VirtualRegs in
2137     // general.  So SmallVec is a definite benefit here.
2138     pub vreg_to_vlrs_map: Vec</*virtual reg ix, */ SmallVec<[VirtualRangeIx; 3]>>,
2139 
2140     // As an optimisation heuristic for BT's coalescing analysis, these indicate which
2141     // real/virtual registers have "many" `RangeFrag`s in their live ranges.  For some
2142     // definition of "many", perhaps "200 or more".  This is not important for overall
2143     // allocation result or correctness: it merely allows the coalescing analysis to switch
2144     // between two search strategies, one of which is fast for regs with few `RangeFrag`s (the
2145     // vast majority) and the other of which has better asymptotic behaviour for regs with many
2146     // `RangeFrag`s (in order to keep out of trouble on some pathological inputs).  These
2147     // vectors are duplicate-free but the elements may be in an arbitrary order.
2148     pub rregs_with_many_frags: Vec<u32 /*RealReg index*/>,
2149     pub vregs_with_many_frags: Vec<u32 /*VirtualReg index*/>,
2150 
2151     // And this indicates what the thresh is actually set to.  A frag will be in
2152     // `r/vregs_with_many_frags` if it has `many_frags_thresh` or more RangeFrags.
2153     pub many_frags_thresh: usize,
2154 }
2155 
2156 //=============================================================================
2157 // Some auxiliary/miscellaneous data structures that are useful: MoveInfo
2158 
2159 // `MoveInfoElem` holds info about the two registers connected a move: the source and destination
2160 // of the move, the insn performing the move, and the estimated execution frequency of the
2161 // containing block.  In `MoveInfo`, the moves are not presented in any particular order, but
2162 // they are duplicate-free in that each such instruction will be listed only once.
2163 
2164 pub struct MoveInfoElem {
2165     pub dst: Reg,
2166     pub src: Reg,
2167     pub iix: InstIx,
2168     pub est_freq: u32,
2169 }
2170 
2171 pub struct MoveInfo {
2172     pub moves: Vec<MoveInfoElem>,
2173 }
2174 
2175 // Something that can be either a VirtualRangeIx or a RealRangeIx, whilst still being 32 bits
2176 // (by stealing one bit from those spaces).  Note that the resulting thing no longer denotes a
2177 // contiguous index space, and so it has a name that indicates it is an identifier rather than
2178 // an index.
2179 
2180 #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
2181 pub struct RangeId {
2182     // 1 X--(31)--X is a RealRangeIx with value X--(31)--X
2183     // 0 X--(31)--X is a VirtualRangeIx with value X--(31)--X
2184     bits: u32,
2185 }
2186 
2187 impl RangeId {
2188     #[inline(always)]
new_real(rlrix: RealRangeIx) -> Self2189     pub fn new_real(rlrix: RealRangeIx) -> Self {
2190         let n = rlrix.get();
2191         assert!(n <= 0x7FFF_FFFF);
2192         Self {
2193             bits: n | 0x8000_0000,
2194         }
2195     }
2196     #[inline(always)]
new_virtual(vlrix: VirtualRangeIx) -> Self2197     pub fn new_virtual(vlrix: VirtualRangeIx) -> Self {
2198         let n = vlrix.get();
2199         assert!(n <= 0x7FFF_FFFF);
2200         Self { bits: n }
2201     }
2202     #[inline(always)]
is_real(self) -> bool2203     pub fn is_real(self) -> bool {
2204         self.bits & 0x8000_0000 != 0
2205     }
2206     #[allow(dead_code)]
2207     #[inline(always)]
is_virtual(self) -> bool2208     pub fn is_virtual(self) -> bool {
2209         self.bits & 0x8000_0000 == 0
2210     }
2211     #[inline(always)]
to_real(self) -> RealRangeIx2212     pub fn to_real(self) -> RealRangeIx {
2213         assert!(self.bits & 0x8000_0000 != 0);
2214         RealRangeIx::new(self.bits & 0x7FFF_FFFF)
2215     }
2216     #[inline(always)]
to_virtual(self) -> VirtualRangeIx2217     pub fn to_virtual(self) -> VirtualRangeIx {
2218         assert!(self.bits & 0x8000_0000 == 0);
2219         VirtualRangeIx::new(self.bits)
2220     }
2221     #[inline(always)]
invalid_value() -> Self2222     pub fn invalid_value() -> Self {
2223         // Real, and inplausibly huge
2224         Self { bits: 0xFFFF_FFFF }
2225     }
2226 }
2227 
2228 impl fmt::Debug for RangeId {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result2229     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
2230         if self.is_real() {
2231             self.to_real().fmt(fmt)
2232         } else {
2233             self.to_virtual().fmt(fmt)
2234         }
2235     }
2236 }
2237 
2238 //=============================================================================
2239 // Test cases
2240 
2241 // sewardj 2020Mar04: these are commented out for now, as they no longer
2242 // compile.  They may be useful later though, once BT acquires an interval
2243 // tree implementation for its CommitmentMap.
2244 
2245 /*
2246 #[test]
2247 fn test_sorted_frag_ranges() {
2248   // Create a RangeFrag and RangeFragIx from two InstPoints.
2249   fn gen_fix(
2250     fenv: &mut TypedIxVec<RangeFragIx, RangeFrag>, first: InstPoint,
2251     last: InstPoint,
2252   ) -> RangeFragIx {
2253     assert!(first <= last);
2254     let res = RangeFragIx::new(fenv.len() as u32);
2255     let frag = RangeFrag {
2256       bix: BlockIx::new(123),
2257       kind: RangeFragKind::Local,
2258       first,
2259       last,
2260       count: 0,
2261     };
2262     fenv.push(frag);
2263     res
2264   }
2265 
2266   fn get_range_frag(
2267     fenv: &TypedIxVec<RangeFragIx, RangeFrag>, fix: RangeFragIx,
2268   ) -> &RangeFrag {
2269     &fenv[fix]
2270   }
2271 
2272   // Structural equality, at least.  Not equality in the sense of
2273   // deferencing the contained RangeFragIxes.
2274   fn sorted_range_eq(
2275     fixs1: &SortedRangeFragIxs, fixs2: &SortedRangeFragIxs,
2276   ) -> bool {
2277     if fixs1.frag_ixs.len() != fixs2.frag_ixs.len() {
2278       return false;
2279     }
2280     for (mf1, mf2) in fixs1.frag_ixs.iter().zip(&fixs2.frag_ixs) {
2281       if mf1 != mf2 {
2282         return false;
2283       }
2284     }
2285     true
2286   }
2287 
2288   let iix3 = InstIx::new(3);
2289   let iix4 = InstIx::new(4);
2290   let iix5 = InstIx::new(5);
2291   let iix6 = InstIx::new(6);
2292   let iix7 = InstIx::new(7);
2293   let iix10 = InstIx::new(10);
2294   let iix12 = InstIx::new(12);
2295 
2296   let fp_3u = InstPoint::new_use(iix3);
2297   let fp_3d = InstPoint::new_def(iix3);
2298 
2299   let fp_4u = InstPoint::new_use(iix4);
2300 
2301   let fp_5u = InstPoint::new_use(iix5);
2302   let fp_5d = InstPoint::new_def(iix5);
2303 
2304   let fp_6u = InstPoint::new_use(iix6);
2305   let fp_6d = InstPoint::new_def(iix6);
2306 
2307   let fp_7u = InstPoint::new_use(iix7);
2308   let fp_7d = InstPoint::new_def(iix7);
2309 
2310   let fp_10u = InstPoint::new_use(iix10);
2311   let fp_12u = InstPoint::new_use(iix12);
2312 
2313   let mut fenv = TypedIxVec::<RangeFragIx, RangeFrag>::new();
2314 
2315   let fix_3u = gen_fix(&mut fenv, fp_3u, fp_3u);
2316   let fix_3d = gen_fix(&mut fenv, fp_3d, fp_3d);
2317   let fix_4u = gen_fix(&mut fenv, fp_4u, fp_4u);
2318   let fix_3u_5u = gen_fix(&mut fenv, fp_3u, fp_5u);
2319   let fix_3d_5d = gen_fix(&mut fenv, fp_3d, fp_5d);
2320   let fix_3d_5u = gen_fix(&mut fenv, fp_3d, fp_5u);
2321   let fix_3u_5d = gen_fix(&mut fenv, fp_3u, fp_5d);
2322   let fix_6u_6d = gen_fix(&mut fenv, fp_6u, fp_6d);
2323   let fix_7u_7d = gen_fix(&mut fenv, fp_7u, fp_7d);
2324   let fix_10u = gen_fix(&mut fenv, fp_10u, fp_10u);
2325   let fix_12u = gen_fix(&mut fenv, fp_12u, fp_12u);
2326 
2327   // Boundary checks for point ranges, 3u vs 3d
2328   assert!(
2329     cmp_range_frags(
2330       get_range_frag(&fenv, fix_3u),
2331       get_range_frag(&fenv, fix_3u)
2332     ) == Some(Ordering::Equal)
2333   );
2334   assert!(
2335     cmp_range_frags(
2336       get_range_frag(&fenv, fix_3u),
2337       get_range_frag(&fenv, fix_3d)
2338     ) == Some(Ordering::Less)
2339   );
2340   assert!(
2341     cmp_range_frags(
2342       get_range_frag(&fenv, fix_3d),
2343       get_range_frag(&fenv, fix_3u)
2344     ) == Some(Ordering::Greater)
2345   );
2346 
2347   // Boundary checks for point ranges, 3d vs 4u
2348   assert!(
2349     cmp_range_frags(
2350       get_range_frag(&fenv, fix_3d),
2351       get_range_frag(&fenv, fix_3d)
2352     ) == Some(Ordering::Equal)
2353   );
2354   assert!(
2355     cmp_range_frags(
2356       get_range_frag(&fenv, fix_3d),
2357       get_range_frag(&fenv, fix_4u)
2358     ) == Some(Ordering::Less)
2359   );
2360   assert!(
2361     cmp_range_frags(
2362       get_range_frag(&fenv, fix_4u),
2363       get_range_frag(&fenv, fix_3d)
2364     ) == Some(Ordering::Greater)
2365   );
2366 
2367   // Partially overlapping
2368   assert!(
2369     cmp_range_frags(
2370       get_range_frag(&fenv, fix_3d_5d),
2371       get_range_frag(&fenv, fix_3u_5u)
2372     ) == None
2373   );
2374   assert!(
2375     cmp_range_frags(
2376       get_range_frag(&fenv, fix_3u_5u),
2377       get_range_frag(&fenv, fix_3d_5d)
2378     ) == None
2379   );
2380 
2381   // Completely overlapping: one contained within the other
2382   assert!(
2383     cmp_range_frags(
2384       get_range_frag(&fenv, fix_3d_5u),
2385       get_range_frag(&fenv, fix_3u_5d)
2386     ) == None
2387   );
2388   assert!(
2389     cmp_range_frags(
2390       get_range_frag(&fenv, fix_3u_5d),
2391       get_range_frag(&fenv, fix_3d_5u)
2392     ) == None
2393   );
2394 
2395   // Create a SortedRangeFragIxs from a bunch of RangeFrag indices
2396   fn new_sorted_frag_ranges(
2397     fenv: &TypedIxVec<RangeFragIx, RangeFrag>, frags: &Vec<RangeFragIx>,
2398   ) -> SortedRangeFragIxs {
2399     SortedRangeFragIxs::new(&frags, fenv)
2400   }
2401 
2402   // Construction tests
2403   // These fail due to overlap
2404   //let _ = new_sorted_frag_ranges(&fenv, &vec![fix_3u_3u, fix_3u_3u]);
2405   //let _ = new_sorted_frag_ranges(&fenv, &vec![fix_3u_5u, fix_3d_5d]);
2406 
2407   // These fail due to not being in order
2408   //let _ = new_sorted_frag_ranges(&fenv, &vec![fix_4u_4u, fix_3u_3u]);
2409 
2410   // Simple non-overlap tests for add()
2411 
2412   let smf_empty = new_sorted_frag_ranges(&fenv, &vec![]);
2413   let smf_6_7_10 =
2414     new_sorted_frag_ranges(&fenv, &vec![fix_6u_6d, fix_7u_7d, fix_10u]);
2415   let smf_3_12 = new_sorted_frag_ranges(&fenv, &vec![fix_3u, fix_12u]);
2416   let smf_3_6_7_10_12 = new_sorted_frag_ranges(
2417     &fenv,
2418     &vec![fix_3u, fix_6u_6d, fix_7u_7d, fix_10u, fix_12u],
2419   );
2420   let mut tmp;
2421 
2422   tmp = smf_empty.clone();
2423   tmp.add(&smf_empty, &fenv);
2424   assert!(sorted_range_eq(&tmp, &smf_empty));
2425 
2426   tmp = smf_3_12.clone();
2427   tmp.add(&smf_empty, &fenv);
2428   assert!(sorted_range_eq(&tmp, &smf_3_12));
2429 
2430   tmp = smf_empty.clone();
2431   tmp.add(&smf_3_12, &fenv);
2432   assert!(sorted_range_eq(&tmp, &smf_3_12));
2433 
2434   tmp = smf_6_7_10.clone();
2435   tmp.add(&smf_3_12, &fenv);
2436   assert!(sorted_range_eq(&tmp, &smf_3_6_7_10_12));
2437 
2438   tmp = smf_3_12.clone();
2439   tmp.add(&smf_6_7_10, &fenv);
2440   assert!(sorted_range_eq(&tmp, &smf_3_6_7_10_12));
2441 
2442   // Tests for can_add()
2443   assert!(true == smf_empty.can_add(&smf_empty, &fenv));
2444   assert!(true == smf_empty.can_add(&smf_3_12, &fenv));
2445   assert!(true == smf_3_12.can_add(&smf_empty, &fenv));
2446   assert!(false == smf_3_12.can_add(&smf_3_12, &fenv));
2447 
2448   assert!(true == smf_6_7_10.can_add(&smf_3_12, &fenv));
2449 
2450   assert!(true == smf_3_12.can_add(&smf_6_7_10, &fenv));
2451 
2452   // Tests for del()
2453   let smf_6_7 = new_sorted_frag_ranges(&fenv, &vec![fix_6u_6d, fix_7u_7d]);
2454   let smf_6_10 = new_sorted_frag_ranges(&fenv, &vec![fix_6u_6d, fix_10u]);
2455   let smf_7 = new_sorted_frag_ranges(&fenv, &vec![fix_7u_7d]);
2456   let smf_10 = new_sorted_frag_ranges(&fenv, &vec![fix_10u]);
2457 
2458   tmp = smf_empty.clone();
2459   tmp.del(&smf_empty, &fenv);
2460   assert!(sorted_range_eq(&tmp, &smf_empty));
2461 
2462   tmp = smf_3_12.clone();
2463   tmp.del(&smf_empty, &fenv);
2464   assert!(sorted_range_eq(&tmp, &smf_3_12));
2465 
2466   tmp = smf_empty.clone();
2467   tmp.del(&smf_3_12, &fenv);
2468   assert!(sorted_range_eq(&tmp, &smf_empty));
2469 
2470   tmp = smf_6_7_10.clone();
2471   tmp.del(&smf_3_12, &fenv);
2472   assert!(sorted_range_eq(&tmp, &smf_6_7_10));
2473 
2474   tmp = smf_3_12.clone();
2475   tmp.del(&smf_6_7_10, &fenv);
2476   assert!(sorted_range_eq(&tmp, &smf_3_12));
2477 
2478   tmp = smf_6_7_10.clone();
2479   tmp.del(&smf_6_7, &fenv);
2480   assert!(sorted_range_eq(&tmp, &smf_10));
2481 
2482   tmp = smf_6_7_10.clone();
2483   tmp.del(&smf_10, &fenv);
2484   assert!(sorted_range_eq(&tmp, &smf_6_7));
2485 
2486   tmp = smf_6_7_10.clone();
2487   tmp.del(&smf_7, &fenv);
2488   assert!(sorted_range_eq(&tmp, &smf_6_10));
2489 
2490   // Tests for can_add_if_we_first_del()
2491   let smf_10_12 = new_sorted_frag_ranges(&fenv, &vec![fix_10u, fix_12u]);
2492 
2493   assert!(
2494     true
2495       == smf_6_7_10
2496         .can_add_if_we_first_del(/*d=*/ &smf_10_12, /*a=*/ &smf_3_12, &fenv)
2497   );
2498 
2499   assert!(
2500     false
2501       == smf_6_7_10
2502         .can_add_if_we_first_del(/*d=*/ &smf_10_12, /*a=*/ &smf_7, &fenv)
2503   );
2504 }
2505 */
2506