Selaa lähdekoodia

basic dt hashing

Simon Krajewski 12 vuotta sitten
vanhempi
commit
3bcfd035e0
1 muutettua tiedostoa jossa 53 lisäystä ja 26 poistoa
  1. 53 26
      matcher.ml

+ 53 - 26
matcher.ml

@@ -25,6 +25,10 @@ open Common
 open Type
 open Type
 open Typecore
 open Typecore
 
 
+(* Dt *)
+
+type pvar = tvar * pos
+
 type con_def =
 type con_def =
 	| CEnum of tenum * tenum_field
 	| CEnum of tenum * tenum_field
 	| CConst of tconstant
 	| CConst of tconstant
@@ -40,7 +44,26 @@ and con = {
 	c_pos : pos;
 	c_pos : pos;
 }
 }
 
 
-type pvar = tvar * pos
+type st_def =
+	| SVar of tvar
+	| SField of st * string
+	| SEnum of st * string * int
+	| SArray of st * int
+	| STuple of st * int * int
+
+and st = {
+	st_def : st_def;
+	st_type : t;
+	st_pos : pos;
+}
+
+type dt =
+	| Out of texpr * texpr option * dt option
+	| Switch of st * (con * dt) list
+	| Bind of (pvar * st) list * dt
+	| Goto of int
+
+(* Pattern *)
 
 
 type pat_def =
 type pat_def =
 	| PAny
 	| PAny
@@ -56,19 +79,6 @@ and pat = {
 	p_pos : pos;
 	p_pos : pos;
 }
 }
 
 
-type st_def =
-	| SVar of tvar
-	| SField of st * string
-	| SEnum of st * string * int
-	| SArray of st * int
-	| STuple of st * int * int
-
-and st = {
-	st_def : st_def;
-	st_type : t;
-	st_pos : pos;
-}
-
 type out = {
 type out = {
 	o_expr : texpr;
 	o_expr : texpr;
 	o_guard : texpr option;
 	o_guard : texpr option;
@@ -79,21 +89,19 @@ type out = {
 type pat_vec = pat array * out
 type pat_vec = pat array * out
 type pat_matrix = pat_vec list
 type pat_matrix = pat_vec list
 
 
+(* Context *)
+
 type pattern_ctx = {
 type pattern_ctx = {
 	mutable pc_locals : (string, pvar) PMap.t;
 	mutable pc_locals : (string, pvar) PMap.t;
 	mutable pc_sub_vars : (string, pvar) PMap.t option;
 	mutable pc_sub_vars : (string, pvar) PMap.t option;
 	mutable pc_reify : bool;
 	mutable pc_reify : bool;
 }
 }
 
 
-type dt =
-	| Out of texpr * texpr option * dt option
-	| Switch of st * (con * dt) list
-	| Bind of (pvar * st) list * dt
-	| Goto of int
-
 type matcher = {
 type matcher = {
 	ctx : typer;
 	ctx : typer;
 	need_val : bool;
 	need_val : bool;
+	dt_cache : (dt,int) Hashtbl.t;
+	mutable dt_count : int;
 	mutable outcomes : (pat list,out) PMap.t;
 	mutable outcomes : (pat list,out) PMap.t;
 	mutable toplevel_or : bool;
 	mutable toplevel_or : bool;
 	mutable used_paths : (int,bool) Hashtbl.t;
 	mutable used_paths : (int,bool) Hashtbl.t;
@@ -797,7 +805,21 @@ let bind_remaining out pv stl =
 	in
 	in
 	loop stl pv
 	loop stl pv
 
 
-let rec compile mctx stl pmat = match pmat with
+let get_cache mctx dt =
+	match dt with Goto _ -> dt | _ ->
+	try
+		let i = Hashtbl.find mctx.dt_cache dt in
+		Goto i
+	with Not_found ->
+		Hashtbl.replace mctx.dt_cache dt mctx.dt_count;
+		print_endline ("REGISTERED " ^ (string_of_int mctx.dt_count));
+		print_endline (s_dt "" dt);
+		print_endline "==========";
+		mctx.dt_count <- mctx.dt_count + 1;
+		dt
+
+let rec compile mctx stl pmat =
+	let dt = match pmat with
 	| [] ->
 	| [] ->
 		(match stl with
 		(match stl with
 		| st :: stl ->
 		| st :: stl ->
@@ -839,7 +861,7 @@ let rec compile mctx stl pmat = match pmat with
 				let hsubs = mk_subs st_head c in
 				let hsubs = mk_subs st_head c in
 				let subs = hsubs @ st_tail in
 				let subs = hsubs @ st_tail in
 				let dt = compile mctx subs spec in
 				let dt = compile mctx subs spec in
-				c,dt
+				c,get_cache mctx dt
 			) sigma in
 			) sigma in
 			let def = default mctx pmat in
 			let def = default mctx pmat in
 			let dt = match def,cases with
 			let dt = match def,cases with
@@ -858,13 +880,13 @@ let rec compile mctx stl pmat = match pmat with
 				compile mctx st_tail def
 				compile mctx st_tail def
 			| def,_ ->
 			| def,_ ->
 				let cdef = mk_con CAny t_dynamic st_head.st_pos in
 				let cdef = mk_con CAny t_dynamic st_head.st_pos in
-				let cases = cases @ [cdef,compile mctx st_tail def] in
+				let cases = cases @ [cdef,get_cache mctx (compile mctx st_tail def)] in
 				Switch(st_head,cases)
 				Switch(st_head,cases)
 			in
 			in
-			if bl = [] then dt else Bind(bl,dt)
+			if bl = [] then dt else Bind(bl,get_cache mctx dt)
 		end
 		end
-
-(* Main *)
+	in
+	get_cache mctx dt
 
 
 let rec collapse_case el = match el with
 let rec collapse_case el = match el with
 	| e :: [] ->
 	| e :: [] ->
@@ -875,6 +897,8 @@ let rec collapse_case el = match el with
 	| [] ->
 	| [] ->
 		assert false
 		assert false
 
 
+(* Decision tree compilation *)
+
 let make_dt ctx e cases def with_type p =
 let make_dt ctx e cases def with_type p =
 	let need_val,with_type,tmono = match with_type with
 	let need_val,with_type,tmono = match with_type with
 		| NoValue -> false,NoValue,None
 		| NoValue -> false,NoValue,None
@@ -937,6 +961,8 @@ let make_dt ctx e cases def with_type p =
 		outcomes = PMap.empty;
 		outcomes = PMap.empty;
 		toplevel_or = false;
 		toplevel_or = false;
 		used_paths = Hashtbl.create 0;
 		used_paths = Hashtbl.create 0;
+		dt_cache = Hashtbl.create 0;
+		dt_count = 0;
 	} in
 	} in
 	(* flatten cases *)
 	(* flatten cases *)
 	let cases = List.map (fun (el,eg,e) ->
 	let cases = List.map (fun (el,eg,e) ->
@@ -1345,6 +1371,7 @@ and to_array_switch cctx t st cases =
 
 
 let match_expr ctx e cases def with_type p =
 let match_expr ctx e cases def with_type p =
 	let dt,var_inits,t = make_dt ctx e cases def with_type p in
 	let dt,var_inits,t = make_dt ctx e cases def with_type p in
+	if p.pfile = "src/Main.hx" then print_endline (s_dt "" dt);
 	let cctx = {
 	let cctx = {
 		ctx = ctx;
 		ctx = ctx;
 		out_type = mk_mono();
 		out_type = mk_mono();