diff --git a/lib/bforest/src/lib.rs b/lib/bforest/src/lib.rs index 1bddcd8a73..2a1c5f8436 100644 --- a/lib/bforest/src/lib.rs +++ b/lib/bforest/src/lib.rs @@ -114,9 +114,6 @@ trait Forest { /// An array of values for the leaf nodes. type LeafValues: Copy + BorrowMut<[Self::Value]>; - /// Type used for key comparisons. - type Comparator: Comparator; - /// Splat a single key into a whole array. fn splat_key(key: Self::Key) -> Self::LeafKeys; diff --git a/lib/bforest/src/map.rs b/lib/bforest/src/map.rs index 270d186230..497ca2c112 100644 --- a/lib/bforest/src/map.rs +++ b/lib/bforest/src/map.rs @@ -9,19 +9,17 @@ use std::marker::PhantomData; use std::string::String; /// Tag type defining forest types for a map. -struct MapTypes(PhantomData<(K, V, C)>); +struct MapTypes(PhantomData<(K, V)>); -impl Forest for MapTypes +impl Forest for MapTypes where K: Copy, V: Copy, - C: Comparator, { type Key = K; type Value = V; type LeafKeys = [K; INNER_SIZE - 1]; type LeafValues = [V; INNER_SIZE - 1]; - type Comparator = C; fn splat_key(key: Self::Key) -> Self::LeafKeys { [key; INNER_SIZE - 1] @@ -33,20 +31,18 @@ where } /// Memory pool for a forest of `Map` instances. -pub struct MapForest +pub struct MapForest where K: Copy, V: Copy, - C: Comparator, { - nodes: NodePool>, + nodes: NodePool>, } -impl MapForest +impl MapForest where K: Copy, V: Copy, - C: Comparator, { /// Create a new empty forest. pub fn new() -> Self { @@ -63,7 +59,7 @@ where } } -/// B-tree mapping from `K` to `V` using `C` for comparing keys. +/// B-tree mapping from `K` to `V`. /// /// This is not a general-purpose replacement for `BTreeMap`. See the [module /// documentation](index.html) for more information about design tradeoffs. @@ -72,21 +68,19 @@ where /// they belong to. *Cloning a map does not allocate new memory for the clone*. It creates an alias /// of the same memory. #[derive(Clone)] -pub struct Map +pub struct Map where K: Copy, V: Copy, - C: Comparator, { root: PackedOption, - unused: PhantomData<(K, V, C)>, + unused: PhantomData<(K, V)>, } -impl Map +impl Map where K: Copy, V: Copy, - C: Comparator, { /// Make an empty map. pub fn new() -> Self { @@ -102,7 +96,7 @@ where } /// Get the value stored for `key`. - pub fn get(&self, key: K, forest: &MapForest, comp: &C) -> Option { + pub fn get>(&self, key: K, forest: &MapForest, comp: &C) -> Option { self.root .expand() .and_then(|root| Path::default().find(key, root, &forest.nodes, comp)) @@ -115,7 +109,12 @@ where /// Otherwise, return the last key-value pair with a key that is less than or equal to `key`. /// /// If no stored keys are less than or equal to `key`, return `None`. - pub fn get_or_less(&self, key: K, forest: &MapForest, comp: &C) -> Option<(K, V)> { + pub fn get_or_less>( + &self, + key: K, + forest: &MapForest, + comp: &C, + ) -> Option<(K, V)> { self.root.expand().and_then(|root| { let mut path = Path::default(); match path.find(key, root, &forest.nodes, comp) { @@ -126,18 +125,23 @@ where } /// Insert `key, value` into the map and return the old value stored for `key`, if any. - pub fn insert( + pub fn insert>( &mut self, key: K, value: V, - forest: &mut MapForest, + forest: &mut MapForest, comp: &C, ) -> Option { self.cursor(forest, comp).insert(key, value) } /// Remove `key` from the map and return the removed value for `key`, if any. - pub fn remove(&mut self, key: K, forest: &mut MapForest, comp: &C) -> Option { + pub fn remove>( + &mut self, + key: K, + forest: &mut MapForest, + comp: &C, + ) -> Option { let mut c = self.cursor(forest, comp); if c.goto(key).is_some() { c.remove() @@ -147,7 +151,7 @@ where } /// Remove all entries. - pub fn clear(&mut self, forest: &mut MapForest) { + pub fn clear(&mut self, forest: &mut MapForest) { if let Some(root) = self.root.take() { forest.nodes.free_tree(root); } @@ -158,7 +162,7 @@ where /// Remove all key-value pairs where the predicate returns false. /// /// The predicate is allowed to update the values stored in the map. - pub fn retain(&mut self, forest: &mut MapForest, mut predicate: F) + pub fn retain(&mut self, forest: &mut MapForest, mut predicate: F) where F: FnMut(K, &mut V) -> bool, { @@ -181,16 +185,16 @@ where /// Create a cursor for navigating this map. The cursor is initially positioned off the end of /// the map. - pub fn cursor<'a>( + pub fn cursor<'a, C: Comparator>( &'a mut self, - forest: &'a mut MapForest, + forest: &'a mut MapForest, comp: &'a C, ) -> MapCursor<'a, K, V, C> { MapCursor::new(self, forest, comp) } /// Create an iterator traversing this map. The iterator type is `(K, V)`. - pub fn iter<'a>(&'a self, forest: &'a MapForest) -> MapIter<'a, K, V, C> { + pub fn iter<'a>(&'a self, forest: &'a MapForest) -> MapIter<'a, K, V> { MapIter { root: self.root, pool: &forest.nodes, @@ -199,11 +203,10 @@ where } } -impl Default for Map +impl Default for Map where K: Copy, V: Copy, - C: Comparator, { fn default() -> Self { Self::new() @@ -211,16 +214,15 @@ where } #[cfg(test)] -impl Map +impl Map where K: Copy + fmt::Display, V: Copy, - C: Comparator, { /// Verify consistency. - fn verify(&self, forest: &MapForest, comp: &C) + fn verify>(&self, forest: &MapForest, comp: &C) where - NodeData>: fmt::Display, + NodeData>: fmt::Display, { if let Some(root) = self.root.expand() { forest.nodes.verify_tree(root, comp); @@ -228,7 +230,7 @@ where } /// Get a text version of the path to `key`. - fn tpath(&self, key: K, forest: &MapForest, comp: &C) -> String { + fn tpath>(&self, key: K, forest: &MapForest, comp: &C) -> String { use std::string::ToString; match self.root.expand() { None => "map(empty)".to_string(), @@ -252,9 +254,9 @@ where C: 'a + Comparator, { root: &'a mut PackedOption, - pool: &'a mut NodePool>, + pool: &'a mut NodePool>, comp: &'a C, - path: Path>, + path: Path>, } impl<'a, K, V, C> MapCursor<'a, K, V, C> @@ -265,8 +267,8 @@ where { /// Create a cursor with a default (off-the-end) location. fn new( - container: &'a mut Map, - forest: &'a mut MapForest, + container: &'a mut Map, + forest: &'a mut MapForest, comp: &'a C, ) -> MapCursor<'a, K, V, C> { MapCursor { @@ -379,22 +381,20 @@ where } /// An iterator visiting the key-value pairs of a `Map`. -pub struct MapIter<'a, K, V, C> +pub struct MapIter<'a, K, V> where K: 'a + Copy, V: 'a + Copy, - C: 'a + Comparator, { root: PackedOption, - pool: &'a NodePool>, - path: Path>, + pool: &'a NodePool>, + path: Path>, } -impl<'a, K, V, C> Iterator for MapIter<'a, K, V, C> +impl<'a, K, V> Iterator for MapIter<'a, K, V> where K: 'a + Copy, V: 'a + Copy, - C: 'a + Comparator, { type Item = (K, V); @@ -438,16 +438,16 @@ mod test { #[test] fn node_size() { // check that nodes are cache line sized when keys and values are 32 bits. - type F = MapTypes; + type F = MapTypes; assert_eq!(mem::size_of::>(), 64); } #[test] fn empty() { - let mut f = MapForest::::new(); + let mut f = MapForest::::new(); f.clear(); - let mut m = Map::::new(); + let mut m = Map::::new(); assert!(m.is_empty()); m.clear(&mut f); @@ -470,8 +470,8 @@ mod test { #[test] fn inserting() { - let f = &mut MapForest::::new(); - let mut m = Map::::new(); + let f = &mut MapForest::::new(); + let mut m = Map::::new(); // The first seven values stay in a single leaf node. assert_eq!(m.insert(50, 5.0, f, &()), None); @@ -577,9 +577,9 @@ mod test { #[test] fn split_level0_leaf() { // Various ways of splitting a full leaf node at level 0. - let f = &mut MapForest::::new(); + let f = &mut MapForest::::new(); - fn full_leaf(f: &mut MapForest) -> Map { + fn full_leaf(f: &mut MapForest) -> Map { let mut m = Map::new(); for n in 1..8 { m.insert(n * 10, n as f32 * 1.1, f, &()); @@ -628,7 +628,7 @@ mod test { #[test] fn split_level1_leaf() { // Various ways of splitting a full leaf node at level 1. - let f = &mut MapForest::::new(); + let f = &mut MapForest::::new(); // Return a map whose root node is a full inner node, and the leaf nodes are all full // containing: @@ -637,7 +637,7 @@ mod test { // 210, 220, ..., 270 // ... // 810, 820, ..., 870 - fn full(f: &mut MapForest) -> Map { + fn full(f: &mut MapForest) -> Map { let mut m = Map::new(); // Start by inserting elements in order. @@ -756,7 +756,7 @@ mod test { // Make a tree with two barely healthy leaf nodes: // [ 10 20 30 40 ] [ 50 60 70 80 ] - fn two_leaf(f: &mut MapForest) -> Map { + fn two_leaf(f: &mut MapForest) -> Map { f.clear(); let mut m = Map::new(); for n in 1..9 { @@ -767,7 +767,7 @@ mod test { #[test] fn remove_level1() { - let f = &mut MapForest::::new(); + let f = &mut MapForest::::new(); let mut m = two_leaf(f); // Verify geometry. @@ -830,7 +830,7 @@ mod test { #[test] fn remove_level1_rightmost() { - let f = &mut MapForest::::new(); + let f = &mut MapForest::::new(); let mut m = two_leaf(f); // [ 10 20 30 40 ] [ 50 60 70 80 ] @@ -852,7 +852,7 @@ mod test { // Make a 3-level tree with barely healthy nodes. // 1 root, 8 inner nodes, 7*4+5=33 leaf nodes, 4 entries each. - fn level3_sparse(f: &mut MapForest) -> Map { + fn level3_sparse(f: &mut MapForest) -> Map { f.clear(); let mut m = Map::new(); for n in 1..133 { @@ -863,7 +863,7 @@ mod test { #[test] fn level3_removes() { - let f = &mut MapForest::::new(); + let f = &mut MapForest::::new(); let mut m = level3_sparse(f); m.verify(f, &()); @@ -894,8 +894,8 @@ mod test { #[test] fn insert_many() { - let f = &mut MapForest::::new(); - let mut m = Map::::new(); + let f = &mut MapForest::::new(); + let mut m = Map::::new(); let mm = 4096; let mut x = 0; diff --git a/lib/bforest/src/node.rs b/lib/bforest/src/node.rs index b529816afb..de5337053d 100644 --- a/lib/bforest/src/node.rs +++ b/lib/bforest/src/node.rs @@ -595,7 +595,6 @@ mod test { type Value = SetValue; type LeafKeys = [char; 15]; type LeafValues = [SetValue; 15]; - type Comparator = (); fn splat_key(key: Self::Key) -> Self::LeafKeys { [key; 15] diff --git a/lib/bforest/src/path.rs b/lib/bforest/src/path.rs index c0e4a089af..153c487547 100644 --- a/lib/bforest/src/path.rs +++ b/lib/bforest/src/path.rs @@ -49,7 +49,7 @@ impl Path { key: F::Key, root: Node, pool: &NodePool, - comp: &F::Comparator, + comp: &Comparator, ) -> Option { let mut node = root; for level in 0.. { @@ -723,7 +723,6 @@ mod test { type Value = char; type LeafKeys = [i32; 7]; type LeafValues = [char; 7]; - type Comparator = TC; fn splat_key(key: Self::Key) -> Self::LeafKeys { [key; 7] diff --git a/lib/bforest/src/pool.rs b/lib/bforest/src/pool.rs index e6b08e4f1c..ceab96d38c 100644 --- a/lib/bforest/src/pool.rs +++ b/lib/bforest/src/pool.rs @@ -1,5 +1,7 @@ //! B+-tree node pool. +#[cfg(test)] +use super::Comparator; use super::{Forest, Node, NodeData}; use entity::PrimaryMap; #[cfg(test)] @@ -76,12 +78,11 @@ impl NodePool { #[cfg(test)] impl NodePool { /// Verify the consistency of the tree rooted at `node`. - pub fn verify_tree(&self, node: Node, comp: &F::Comparator) + pub fn verify_tree>(&self, node: Node, comp: &C) where NodeData: fmt::Display, F::Key: fmt::Display, { - use super::Comparator; use entity::SparseSet; use std::borrow::Borrow; use std::cmp::Ordering; diff --git a/lib/bforest/src/set.rs b/lib/bforest/src/set.rs index 8371fd3bc6..911907ee61 100644 --- a/lib/bforest/src/set.rs +++ b/lib/bforest/src/set.rs @@ -9,18 +9,16 @@ use std::marker::PhantomData; use std::string::String; /// Tag type defining forest types for a set. -struct SetTypes(PhantomData<(K, C)>); +struct SetTypes(PhantomData); -impl Forest for SetTypes +impl Forest for SetTypes where K: Copy, - C: Comparator, { type Key = K; type Value = SetValue; type LeafKeys = [K; 2 * INNER_SIZE - 1]; type LeafValues = [SetValue; 2 * INNER_SIZE - 1]; - type Comparator = C; fn splat_key(key: Self::Key) -> Self::LeafKeys { [key; 2 * INNER_SIZE - 1] @@ -32,18 +30,16 @@ where } /// Memory pool for a forest of `Set` instances. -pub struct SetForest +pub struct SetForest where K: Copy, - C: Comparator, { - nodes: NodePool>, + nodes: NodePool>, } -impl SetForest +impl SetForest where K: Copy, - C: Comparator, { /// Create a new empty forest. pub fn new() -> Self { @@ -69,19 +65,17 @@ where /// they belong to. *Cloning a set does not allocate new memory for the clone*. It creates an alias /// of the same memory. #[derive(Clone)] -pub struct Set +pub struct Set where K: Copy, - C: Comparator, { root: PackedOption, - unused: PhantomData<(K, C)>, + unused: PhantomData, } -impl Set +impl Set where K: Copy, - C: Comparator, { /// Make an empty set. pub fn new() -> Self { @@ -97,7 +91,7 @@ where } /// Does the set contain `key`?. - pub fn contains(&self, key: K, forest: &SetForest, comp: &C) -> bool { + pub fn contains>(&self, key: K, forest: &SetForest, comp: &C) -> bool { self.root .expand() .and_then(|root| Path::default().find(key, root, &forest.nodes, comp)) @@ -109,14 +103,24 @@ where /// If the set did not contain `key`, insert it and return true. /// /// If `key` is already present, don't change the set and return false. - pub fn insert(&mut self, key: K, forest: &mut SetForest, comp: &C) -> bool { + pub fn insert>( + &mut self, + key: K, + forest: &mut SetForest, + comp: &C, + ) -> bool { self.cursor(forest, comp).insert(key) } /// Remove `key` from the set and return true. /// /// If `key` was not present in the set, return false. - pub fn remove(&mut self, key: K, forest: &mut SetForest, comp: &C) -> bool { + pub fn remove>( + &mut self, + key: K, + forest: &mut SetForest, + comp: &C, + ) -> bool { let mut c = self.cursor(forest, comp); if c.goto(key) { c.remove(); @@ -127,7 +131,7 @@ where } /// Remove all entries. - pub fn clear(&mut self, forest: &mut SetForest) { + pub fn clear(&mut self, forest: &mut SetForest) { if let Some(root) = self.root.take() { forest.nodes.free_tree(root); } @@ -136,7 +140,7 @@ where /// Retains only the elements specified by the predicate. /// /// Remove all elements where the predicate returns false. - pub fn retain(&mut self, forest: &mut SetForest, mut predicate: F) + pub fn retain(&mut self, forest: &mut SetForest, mut predicate: F) where F: FnMut(K) -> bool, { @@ -155,16 +159,16 @@ where /// Create a cursor for navigating this set. The cursor is initially positioned off the end of /// the set. - pub fn cursor<'a>( + pub fn cursor<'a, C: Comparator>( &'a mut self, - forest: &'a mut SetForest, + forest: &'a mut SetForest, comp: &'a C, ) -> SetCursor<'a, K, C> { SetCursor::new(self, forest, comp) } /// Create an iterator traversing this set. The iterator type is `K`. - pub fn iter<'a>(&'a self, forest: &'a SetForest) -> SetIter<'a, K, C> { + pub fn iter<'a>(&'a self, forest: &'a SetForest) -> SetIter<'a, K> { SetIter { root: self.root, pool: &forest.nodes, @@ -173,10 +177,9 @@ where } } -impl Default for Set +impl Default for Set where K: Copy, - C: Comparator, { fn default() -> Self { Self::new() @@ -193,9 +196,9 @@ where C: 'a + Comparator, { root: &'a mut PackedOption, - pool: &'a mut NodePool>, + pool: &'a mut NodePool>, comp: &'a C, - path: Path>, + path: Path>, } impl<'a, K, C> SetCursor<'a, K, C> @@ -205,8 +208,8 @@ where { /// Create a cursor with a default (invalid) location. fn new( - container: &'a mut Set, - forest: &'a mut SetForest, + container: &'a mut Set, + forest: &'a mut SetForest, comp: &'a C, ) -> SetCursor<'a, K, C> { SetCursor { @@ -327,20 +330,18 @@ where } /// An iterator visiting the elements of a `Set`. -pub struct SetIter<'a, K, C> +pub struct SetIter<'a, K> where K: 'a + Copy, - C: 'a + Comparator, { root: PackedOption, - pool: &'a NodePool>, - path: Path>, + pool: &'a NodePool>, + path: Path>, } -impl<'a, K, C> Iterator for SetIter<'a, K, C> +impl<'a, K> Iterator for SetIter<'a, K> where K: 'a + Copy, - C: 'a + Comparator, { type Item = K; @@ -365,16 +366,16 @@ mod test { #[test] fn node_size() { // check that nodes are cache line sized when keys are 32 bits. - type F = SetTypes; + type F = SetTypes; assert_eq!(mem::size_of::>(), 64); } #[test] fn empty() { - let mut f = SetForest::::new(); + let mut f = SetForest::::new(); f.clear(); - let mut s = Set::::new(); + let mut s = Set::::new(); assert!(s.is_empty()); s.clear(&mut f); assert!(!s.contains(7, &f, &())); @@ -394,8 +395,8 @@ mod test { #[test] fn simple_cursor() { - let mut f = SetForest::::new(); - let mut s = Set::::new(); + let mut f = SetForest::::new(); + let mut s = Set::::new(); let mut c = SetCursor::new(&mut s, &mut f, &()); assert!(c.insert(50)); @@ -436,8 +437,8 @@ mod test { #[test] fn two_level_sparse_tree() { - let mut f = SetForest::::new(); - let mut s = Set::::new(); + let mut f = SetForest::::new(); + let mut s = Set::::new(); let mut c = SetCursor::new(&mut s, &mut f, &()); // Insert enough elements that we get a two-level tree. @@ -482,8 +483,8 @@ mod test { #[test] fn three_level_sparse_tree() { - let mut f = SetForest::::new(); - let mut s = Set::::new(); + let mut f = SetForest::::new(); + let mut s = Set::::new(); let mut c = SetCursor::new(&mut s, &mut f, &()); // Insert enough elements that we get a 3-level tree. @@ -535,7 +536,7 @@ mod test { // Level 4: 512 leafs, up to 7680 elements // // A 3-level tree can hold at most 960 elements. - fn dense4l(f: &mut SetForest) -> Set { + fn dense4l(f: &mut SetForest) -> Set { f.clear(); let mut s = Set::new(); @@ -549,7 +550,7 @@ mod test { #[test] fn four_level() { - let mut f = SetForest::::new(); + let mut f = SetForest::::new(); let mut s = dense4l(&mut f); assert_eq!( @@ -593,7 +594,7 @@ mod test { #[test] fn four_level_clear() { - let mut f = SetForest::::new(); + let mut f = SetForest::::new(); let mut s = dense4l(&mut f); s.clear(&mut f); } diff --git a/lib/codegen/src/flowgraph.rs b/lib/codegen/src/flowgraph.rs index 9eda2741af..b84da7cd0b 100644 --- a/lib/codegen/src/flowgraph.rs +++ b/lib/codegen/src/flowgraph.rs @@ -61,11 +61,11 @@ struct CFGNode { /// /// The redundant EBB stored here is always consistent with the CFG successor lists, even after /// the IR has been edited. - pub predecessors: bforest::Map, + pub predecessors: bforest::Map, /// Set of EBBs that are the targets of branches and jumps in this EBB. /// The set is ordered by EBB number, indicated by the `()` comparator type. - pub successors: bforest::Set, + pub successors: bforest::Set, } /// The Control Flow Graph maintains a mapping of ebbs to their predecessors @@ -73,8 +73,8 @@ struct CFGNode { /// extended basic blocks. pub struct ControlFlowGraph { data: EntityMap, - pred_forest: bforest::MapForest, - succ_forest: bforest::SetForest, + pred_forest: bforest::MapForest, + succ_forest: bforest::SetForest, valid: bool, } @@ -193,7 +193,7 @@ impl ControlFlowGraph { /// An iterator over EBB predecessors. The iterator type is `BasicBlock`. /// /// Each predecessor is an instruction that branches to the EBB. -pub struct PredIter<'a>(bforest::MapIter<'a, Inst, Ebb, ()>); +pub struct PredIter<'a>(bforest::MapIter<'a, Inst, Ebb>); impl<'a> Iterator for PredIter<'a> { type Item = BasicBlock; @@ -204,7 +204,7 @@ impl<'a> Iterator for PredIter<'a> { } /// An iterator over EBB successors. The iterator type is `Ebb`. -pub type SuccIter<'a> = bforest::SetIter<'a, Ebb, ()>; +pub type SuccIter<'a> = bforest::SetIter<'a, Ebb>; #[cfg(test)] mod tests { diff --git a/lib/codegen/src/regalloc/liverange.rs b/lib/codegen/src/regalloc/liverange.rs index f330fb12b5..cc6a985641 100644 --- a/lib/codegen/src/regalloc/liverange.rs +++ b/lib/codegen/src/regalloc/liverange.rs @@ -112,6 +112,7 @@ use entity::SparseMapValue; use ir::{Ebb, ExpandedProgramPoint, Inst, Layout, ProgramOrder, ProgramPoint, Value}; use regalloc::affinity::Affinity; use std::cmp::Ordering; +use std::marker::PhantomData; /// Global live range of a single SSA value. /// @@ -172,7 +173,9 @@ pub struct GenLiveRange { /// /// The entries are non-overlapping, and none of them overlap the EBB where the value is /// defined. - liveins: bforest::Map, + liveins: bforest::Map, + + po: PhantomData<*const PO>, } /// Context information needed to query a `LiveRange`. @@ -180,14 +183,14 @@ pub struct LiveRangeContext<'a, PO: 'a + ProgramOrder> { /// Ordering of EBBs. pub order: &'a PO, /// Memory pool. - pub forest: &'a bforest::MapForest, + pub forest: &'a bforest::MapForest, } impl<'a, PO: ProgramOrder> LiveRangeContext<'a, PO> { /// Make a new context. pub fn new( order: &'a PO, - forest: &'a bforest::MapForest, + forest: &'a bforest::MapForest, ) -> LiveRangeContext<'a, PO> { LiveRangeContext { order, forest } } @@ -205,11 +208,13 @@ impl<'a, PO: ProgramOrder> Clone for LiveRangeContext<'a, PO> { impl<'a, PO: ProgramOrder> Copy for LiveRangeContext<'a, PO> {} /// Forest of B-trees used for storing live ranges. -pub type LiveRangeForest = bforest::MapForest; +pub type LiveRangeForest = bforest::MapForest; -impl bforest::Comparator for PO { +struct Cmp<'a, PO: ProgramOrder + 'a>(&'a PO); + +impl<'a, PO: ProgramOrder> bforest::Comparator for Cmp<'a, PO> { fn cmp(&self, a: Ebb, b: Ebb) -> Ordering { - self.cmp(a, b) + self.0.cmp(a, b) } } @@ -224,6 +229,7 @@ impl GenLiveRange { def_begin: def, def_end: def, liveins: bforest::Map::new(), + po: PhantomData, } } @@ -243,7 +249,7 @@ impl GenLiveRange { ebb: Ebb, to: Inst, order: &PO, - forest: &mut bforest::MapForest, + forest: &mut bforest::MapForest, ) -> bool { // First check if we're extending the def interval. // @@ -264,7 +270,8 @@ impl GenLiveRange { } // Now check if we're extending any of the existing live-in intervals. - let mut c = self.liveins.cursor(forest, order); + let cmp = Cmp(order); + let mut c = self.liveins.cursor(forest, &cmp); let first_time_livein; if let Some(end) = c.goto(ebb) { @@ -367,8 +374,9 @@ impl GenLiveRange { /// answer, but it is also possible that an even later program point is returned. So don't /// depend on the returned `Inst` to belong to `ebb`. pub fn livein_local_end(&self, ebb: Ebb, ctx: LiveRangeContext) -> Option { + let cmp = Cmp(ctx.order); self.liveins - .get_or_less(ebb, ctx.forest, ctx.order) + .get_or_less(ebb, ctx.forest, &cmp) .and_then(|(_, inst)| { // We have an entry that ends at `inst`. if ctx.order.cmp(inst, ebb) == Ordering::Greater { @@ -390,10 +398,7 @@ impl GenLiveRange { /// /// Note that the intervals are stored in a compressed form so each entry may span multiple /// EBBs where the value is live in. - pub fn liveins<'a>( - &'a self, - ctx: LiveRangeContext<'a, PO>, - ) -> bforest::MapIter<'a, Ebb, Inst, PO> { + pub fn liveins<'a>(&'a self, ctx: LiveRangeContext<'a, PO>) -> bforest::MapIter<'a, Ebb, Inst> { self.liveins.iter(ctx.forest) } @@ -507,11 +512,7 @@ mod tests { } // Validate the live range invariants. - fn validate( - &self, - lr: &GenLiveRange, - forest: &bforest::MapForest, - ) { + fn validate(&self, lr: &GenLiveRange, forest: &bforest::MapForest) { // The def interval must cover a single EBB. let def_ebb = self.pp_ebb(lr.def_begin); assert_eq!(def_ebb, self.pp_ebb(lr.def_end));