@@ -127,6 +127,7 @@ pub struct EGraph<L, M> {
127127 memo : IndexMap < ENode < L > , Id > ,
128128 classes : UnionFind < Id , EClass < L , M > > ,
129129 unions_since_rebuild : usize ,
130+ pub ( crate ) classes_by_op : IndexMap < ( L , usize ) , Vec < Id > > ,
130131}
131132
132133// manual debug impl to avoid L: Language bound on EGraph defn
@@ -147,6 +148,7 @@ impl<L, M> Default for EGraph<L, M> {
147148 memo : IndexMap :: default ( ) ,
148149 classes : UnionFind :: default ( ) ,
149150 unions_since_rebuild : 0 ,
151+ classes_by_op : IndexMap :: default ( ) ,
150152 }
151153 }
152154}
@@ -327,6 +329,7 @@ impl<L: Language, M: Metadata<L>> EGraph<L, M> {
327329 #[ cfg( feature = "parent-pointers" ) ]
328330 parents : IndexSet :: new ( ) ,
329331 } ;
332+
330333 M :: modify ( & mut class) ;
331334 let next_id = self . classes . make_set ( class) ;
332335 trace ! ( "Added {:4}: {:?}" , next_id, enode) ;
@@ -406,9 +409,11 @@ impl<L: Language, M: Metadata<L>> EGraph<L, M> {
406409 }
407410
408411 fn rebuild_classes ( & mut self ) -> usize {
412+ let ( find, mut_values) = self . classes . split ( ) ;
413+
414+ self . classes_by_op . clear ( ) ;
409415 let mut trimmed = 0 ;
410416
411- let ( find, mut_values) = self . classes . split ( ) ;
412417 for class in mut_values {
413418 let old_len = class. len ( ) ;
414419
@@ -422,6 +427,19 @@ impl<L: Language, M: Metadata<L>> EGraph<L, M> {
422427
423428 class. nodes . clear ( ) ;
424429 class. nodes . extend ( unique) ;
430+
431+ let unique_op: IndexSet < ( & L , usize ) > = class
432+ . nodes
433+ . iter ( )
434+ . map ( |node| ( & node. op , node. children . len ( ) ) )
435+ . collect ( ) ;
436+
437+ for op in unique_op {
438+ self . classes_by_op
439+ . entry ( ( op. 0 . clone ( ) , op. 1 ) )
440+ . and_modify ( |ids| ids. push ( class. id ) )
441+ . or_insert ( vec ! [ class. id] ) ;
442+ }
425443 }
426444
427445 trimmed
@@ -467,11 +485,6 @@ impl<L: Language, M: Metadata<L>> EGraph<L, M> {
467485 /// ```
468486 #[ cfg( not( feature = "parent-pointers" ) ) ]
469487 pub fn rebuild ( & mut self ) -> usize {
470- if self . unions_since_rebuild == 0 {
471- info ! ( "Skipping rebuild!" ) ;
472- return 0 ;
473- }
474-
475488 self . unions_since_rebuild = 0 ;
476489
477490 let old_hc_size = self . memo . len ( ) ;
0 commit comments