@@ -116,7 +116,7 @@ impl std::fmt::Display for BranchEdge {
116116}
117117
118118/// Invalidation reasons
119- #[ derive( Debug , Clone , Copy ) ]
119+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
120120pub enum Invariant {
121121 /// Basic operation is redefined
122122 BOPRedefined {
@@ -309,6 +309,34 @@ pub enum Const {
309309 CDouble ( f64 ) ,
310310}
311311
312+ impl std:: hash:: Hash for Const {
313+ fn hash < H : std:: hash:: Hasher > ( & self , state : & mut H ) {
314+ match self {
315+ Const :: Value ( v) => v. hash ( state) ,
316+ Const :: CBool ( b) => b. hash ( state) ,
317+ Const :: CInt8 ( i) => i. hash ( state) ,
318+ Const :: CInt16 ( i) => i. hash ( state) ,
319+ Const :: CInt32 ( i) => i. hash ( state) ,
320+ Const :: CInt64 ( i) => i. hash ( state) ,
321+ Const :: CUInt8 ( u) => u. hash ( state) ,
322+ Const :: CUInt16 ( u) => u. hash ( state) ,
323+ Const :: CUInt32 ( u) => u. hash ( state) ,
324+ Const :: CUInt64 ( u) => u. hash ( state) ,
325+ Const :: CShape ( sid) => sid. hash ( state) ,
326+ Const :: CPtr ( p) => {
327+ let addr = * p as usize ;
328+ addr. hash ( state) ;
329+ }
330+ Const :: CDouble ( d) => {
331+ let bits = d. to_bits ( ) ;
332+ bits. hash ( state) ;
333+ }
334+ }
335+ }
336+ }
337+
338+ impl std:: cmp:: Eq for Const { }
339+
312340impl std:: fmt:: Display for Const {
313341 fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
314342 self . print ( & PtrPrintMap :: identity ( ) ) . fmt ( f)
@@ -1026,6 +1054,8 @@ impl Insn {
10261054 Insn :: Snapshot { .. } => false ,
10271055 Insn :: LoadField { .. } => false ,
10281056 Insn :: WriteBarrier { .. } => false ,
1057+ Insn :: IncrCounter ( _) => false ,
1058+ Insn :: GuardBitEquals { .. } => false ,
10291059 _ => true ,
10301060 }
10311061 }
@@ -4422,6 +4452,8 @@ impl Function {
44224452 let mut type_guards: Vec < ( InsnId , Type , InsnId ) > = vec ! [ ] ;
44234453 let mut shape_guards: Vec < ( InsnId , ShapeId , InsnId ) > = vec ! [ ] ;
44244454 let mut memory: HashMap < ( InsnId , i32 ) , InsnId > = HashMap :: new ( ) ;
4455+ let mut patchpoints: HashMap < Invariant , InsnId > = HashMap :: new ( ) ;
4456+ let mut eq_guards: HashMap < ( InsnId , Const ) , InsnId > = HashMap :: new ( ) ;
44254457 for insn_id in old_insns {
44264458 match self . find ( insn_id) {
44274459 Insn :: GuardType { val, guard_type, .. } => {
@@ -4445,6 +4477,14 @@ impl Function {
44454477 }
44464478 shape_guards. push ( ( val, shape, insn_id) ) ;
44474479 }
4480+ Insn :: GuardBitEquals { val, expected, .. } => {
4481+ let key = ( self . chase_insn ( val) , expected) ;
4482+ if let Some ( & prev) = eq_guards. get ( & key) {
4483+ self . make_equal_to ( insn_id, prev) ;
4484+ continue ;
4485+ }
4486+ eq_guards. insert ( key, insn_id) ;
4487+ }
44484488 Insn :: LoadField { recv, offset, .. } => {
44494489 let key = ( self . chase_insn ( recv) , offset) ;
44504490 eprintln ! ( "trying to read ({}, {})" , key. 0 , key. 1 ) ;
@@ -4462,10 +4502,18 @@ impl Function {
44624502 eprintln ! ( "writing ({}, {}) = {}" , key. 0 , key. 1 , val) ;
44634503 memory. insert ( key, val) ;
44644504 }
4505+ Insn :: PatchPoint { invariant, .. } => {
4506+ if let Some ( & prev) = patchpoints. get ( & invariant) {
4507+ // self.make_equal_to(insn_id, prev);
4508+ continue ;
4509+ }
4510+ patchpoints. insert ( invariant, insn_id) ;
4511+ }
44654512 insn if insn. has_effects ( ) => {
44664513 eprintln ! ( "clearing memory due to {}" , format!( "{}" , insn) ) ;
44674514 shape_guards. clear ( ) ;
44684515 memory. clear ( ) ;
4516+ patchpoints. clear ( ) ;
44694517 }
44704518 _ => { }
44714519 }
0 commit comments