Forráskód Böngészése

improve pattern match conversion using IntMap instead of List and avoid some work in macro-mode (see #3937)

Simon Krajewski 10 éve
szülő
commit
18de81238b
3 módosított fájl, 13 hozzáadás és 6 törlés
  1. 0 2
      analyzer.ml
  2. 2 0
      ast.ml
  3. 11 4
      codegen.ml

+ 0 - 2
analyzer.ml

@@ -3,8 +3,6 @@ open Type
 open Common
 open Typecore
 
-module IntMap = Map.Make(struct type t = int let compare a b = a - b end)
-
 let s_expr = s_expr (s_type (print_context()))
 let s_expr_pretty = s_expr_pretty "" (s_type (print_context()))
 let debug e = print_endline (s_expr e)

+ 2 - 0
ast.ml

@@ -26,6 +26,8 @@ type pos = {
 	pmax : int;
 }
 
+module IntMap = Map.Make(struct type t = int let compare a b = a - b end)
+
 module Meta = struct
 	type strict_meta =
 		| Abstract

+ 11 - 4
codegen.ml

@@ -971,10 +971,10 @@ module PatternMatchConversion = struct
 			| tmp -> ((tmp,ldt) :: cases)
 
 	let replace_locals e =
-		let v_known = ref [] in
+		let v_known = ref IntMap.empty in
 		let copy v =
 			let v' = alloc_var v.v_name v.v_type in
-			v_known := (v,v') :: !v_known;
+			v_known := IntMap.add v.v_id v' !v_known;
 			v'
 		in
 		let rec loop e = match e.eexpr with
@@ -996,7 +996,7 @@ module PatternMatchConversion = struct
 				) catches in
 				{e with eexpr = TTry(e1,catches)}
 			| TLocal v ->
-				let v' = try List.assq v !v_known with Not_found -> v in
+				let v' = try IntMap.find v.v_id !v_known with Not_found -> v in
 				{e with eexpr = TLocal v'}
 			| _ ->
 				Type.map_expr loop e
@@ -1029,7 +1029,14 @@ module PatternMatchConversion = struct
 		| DTSwitch(e_st,cl,dto) ->
 			let def = match dto with None -> None | Some dt -> Some (convert_dt cctx dt) in
 			let cases = group_cases cl in
-			let cases = List.map (fun (cl,dt) -> cl,replace_locals (convert_dt cctx dt)) cases in
+			let cases = List.map (fun (cl,dt) ->
+				let e = convert_dt cctx dt in
+				(* The macro interpreter does not care about unique locals and
+				   we don't run the analyzer on the output, so let's save some
+				   time here (issue #3937) *)
+				let e = if cctx.ctx.in_macro then e else replace_locals e in
+				cl,e
+			) cases in
 			mk (TSwitch(e_st,cases,def)) (mk_mono()) e_st.epos
 
 	let to_typed_ast ctx dt p =