@@ -66,24 +66,56 @@ module Expr = struct
6666 , _ ) ->
6767 false
6868
69+ (* Optimized mixer (DJB2 variant). Inlines to simple arithmetic. *)
70+ let [@ inline] combine h v = (h * 33 ) + v
71+
6972 let hash (e : expr ) : int =
70- let h x = Hashtbl. hash x in
7173 match e with
72- | Val v -> h v
73- | Ptr { base; offset } -> h (base, offset.tag)
74- | Loc l -> h l
75- | Symbol s -> h s
76- | List v -> h v
77- | App (x , es ) -> h (x, es)
78- | Unop (ty , op , e ) -> h (ty, op, e.tag)
79- | Cvtop (ty , op , e ) -> h (ty, op, e.tag)
80- | Binop (ty , op , e1 , e2 ) -> h (ty, op, e1.tag, e2.tag)
81- | Relop (ty , op , e1 , e2 ) -> h (ty, op, e1.tag, e2.tag)
82- | Triop (ty , op , e1 , e2 , e3 ) -> h (ty, op, e1.tag, e2.tag, e3.tag)
83- | Naryop (ty , op , es ) -> h (ty, op, es)
84- | Extract (e , hi , lo ) -> h (e.tag, hi, lo)
85- | Concat (e1 , e2 ) -> h (e1.tag, e2.tag)
86- | Binder (b , vars , e ) -> h (b, vars, e.tag)
74+ | Val v -> Value. hash v
75+ | Ptr { base; offset } -> combine (Bitvector. hash base) offset.tag
76+ | Loc l -> Loc. hash l
77+ | Symbol s -> Symbol. hash s
78+ | List l -> List. fold_left (fun acc x -> combine acc x.Hc. tag) 0 l
79+ | App (s , es ) ->
80+ let h_s = Symbol. hash s in
81+ List. fold_left (fun acc x -> combine acc x.Hc. tag) h_s es
82+ | Unop (ty , op , e ) ->
83+ let h1 = Ty. hash ty in
84+ let h2 = combine h1 (Ty.Unop. hash op) in
85+ combine h2 e.tag
86+ | Binop (ty , op , e1 , e2 ) ->
87+ let h = Ty. hash ty in
88+ let h = combine h (Ty.Binop. hash op) in
89+ let h = combine h e1.tag in
90+ combine h e2.tag
91+ | Triop (ty , op , e1 , e2 , e3 ) ->
92+ let h = Ty. hash ty in
93+ let h = combine h (Ty.Triop. hash op) in
94+ let h = combine h e1.tag in
95+ let h = combine h e2.tag in
96+ combine h e3.tag
97+ | Relop (ty , op , e1 , e2 ) ->
98+ let h = Ty. hash ty in
99+ let h = combine h (Ty.Relop. hash op) in
100+ let h = combine h e1.tag in
101+ combine h e2.tag
102+ | Cvtop (ty , op , e ) ->
103+ let h = Ty. hash ty in
104+ let h = combine h (Ty.Cvtop. hash op) in
105+ combine h e.tag
106+ | Naryop (ty , op , es ) ->
107+ let h = Ty. hash ty in
108+ let h = combine h (Ty.Naryop. hash op) in
109+ List. fold_left (fun acc x -> combine acc x.Hc. tag) h es
110+ | Extract (e , hi , lo ) ->
111+ let h = e.tag in
112+ let h = combine h hi in
113+ combine h lo
114+ | Concat (e1 , e2 ) -> combine e1.tag e2.tag
115+ | Binder (b , vars , e ) ->
116+ let h = Hashtbl. hash b in
117+ let h_vars = List. fold_left (fun acc x -> combine acc x.Hc. tag) h vars in
118+ combine h_vars e.tag
87119end
88120
89121module Hc = Hc. Make [@ inlined hint] (Expr )
0 commit comments