浏览代码

Merge pull request #3667 from Simn/analyzer_value_cache

Analyzer value cache
Simon Krajewski 10 年之前
父节点
当前提交
4bd7da6aa2
共有 1 个文件被更改,包括 54 次插入19 次删除
  1. 54 19
      analyzer.ml

+ 54 - 19
analyzer.ml

@@ -439,7 +439,6 @@ module Ssa = struct
 		com : Common.context;
 		mutable cleanup : (unit -> unit) list;
 		mutable cur_data : node_data;
-		mutable var_values : texpr IntMap.t;
 		mutable var_conds : (condition list) IntMap.t;
 		mutable loop_stack : (join_node * join_node) list;
 		mutable exception_stack : join_node list;
@@ -511,13 +510,50 @@ module Ssa = struct
 			ctx.exception_stack <- List.tl ctx.exception_stack;
 		)
 
+	let get_origin_var v = match v.v_extra with
+		| Some (_,Some {eexpr = TArrayDecl ({eexpr = TLocal v'} :: _)}) -> v'
+		| _ -> raise Not_found
+
+	let set_origin_var v v_origin p =
+		let ev = mk_loc v_origin p in
+		let create tl =
+			let e_extra = mk (TArrayDecl [
+				ev
+			]) t_dynamic p in
+			v.v_extra <- Some (tl,Some e_extra)
+		in
+		match v.v_extra with
+		| Some (tl,Some ({eexpr = TArrayDecl (_ :: el)} as ee)) ->
+			v.v_extra <- Some(tl, Some {ee with eexpr = TArrayDecl (ev :: el)})
+		| Some (tl,None) ->
+			create tl
+		| None ->
+			create []
+		| _ ->
+			assert false
+
+	let get_var_value v = match v.v_extra with
+		| Some (_,Some {eexpr = TArrayDecl (_ :: e :: _)}) -> e
+		| _ -> raise Not_found
+
+	let set_var_value v e =
+		match v.v_extra with
+		| Some (tl,Some ({eexpr = TArrayDecl (e1 :: el)} as ee)) ->
+			let el = match el with
+				| [] -> [e]
+				| _ :: el -> e :: el
+			in
+			v.v_extra <- Some (tl,Some {ee with eexpr = TArrayDecl (e1 :: el)})
+		| _ ->
+			assert false
+
 	let declare_var ctx v p =
 		let old = v.v_extra in
 		ctx.cleanup <- (fun () ->
 			v.v_extra <- old
 		) :: ctx.cleanup;
 		ctx.cur_data.nd_var_map <- IntMap.add v.v_id v ctx.cur_data.nd_var_map;
-		v.v_extra <- Some ([],(Some (mk_loc v p)))
+		set_origin_var v v p
 
 	let assign_var ctx v e p =
 		if v.v_capture then
@@ -532,9 +568,9 @@ module Ssa = struct
 			in
 			let v' = alloc_var (Printf.sprintf "%s<%i>" v.v_name i) v.v_type in
 			v'.v_meta <- [(Meta.Custom ":ssa"),[],p];
-			v'.v_extra <- Some ([],(Some (mk_loc v p)));
+			set_origin_var v' v p;
 			ctx.cur_data.nd_var_map <- IntMap.add v.v_id v' ctx.cur_data.nd_var_map;
-			ctx.var_values <- IntMap.add v'.v_id e ctx.var_values;
+			set_var_value v' e;
 			v'
 		end
 
@@ -575,7 +611,8 @@ module Ssa = struct
 				IntMap.iter (fun i vl -> match vl with
 					| [v,p] ->
 						ctx.cur_data.nd_var_map <- IntMap.add i v ctx.cur_data.nd_var_map;
-					| ({v_extra = Some (_,Some {eexpr = TLocal v})},p) :: _ ->
+					| (v',_) :: _ ->
+						let v = get_origin_var v' in
 						ignore(assign_var ctx v (mk_phi vl p) p)
 					| _ ->
 						assert false
@@ -596,7 +633,7 @@ module Ssa = struct
 		| TUnop(Not,_,e1) ->
 			invert_conds (eval_cond ctx e1)
 		| TLocal v ->
-			begin try eval_cond ctx (IntMap.find v.v_id ctx.var_values)
+			begin try eval_cond ctx (get_var_value v)
 			with Not_found -> [] end
 		| _ ->
 			[]
@@ -669,7 +706,7 @@ module Ssa = struct
 					| None -> None
 					| Some e ->
 						let e = loop ctx e in
-						ctx.var_values <- IntMap.add v.v_id e ctx.var_values;
+						set_var_value v e;
 						Some e
 				in
 				{e with eexpr = TVar(v,eo)}
@@ -819,7 +856,6 @@ module Ssa = struct
 		let ctx = {
 			com = com;
 			cur_data = mk_node_data e.epos;
-			var_values = IntMap.empty;
 			var_conds = IntMap.empty;
 			loop_stack = [];
 			exception_stack = [];
@@ -830,11 +866,11 @@ module Ssa = struct
 
 	let unapply com e =
 		let rec loop e = match e.eexpr with
-			| TFor(({v_extra = Some([],Some {eexpr = TLocal v'})} as v),e1,e2) when Meta.has (Meta.Custom ":ssa") v.v_meta ->
+			| TFor(({v_extra = Some([],Some {eexpr = TArrayDecl ({eexpr = TLocal v'} :: _)})} as v),e1,e2) when Meta.has (Meta.Custom ":ssa") v.v_meta ->
 				let e1 = loop e1 in
 				let e2 = loop e2 in
 				{e with eexpr = TFor(v',e1,e2)}
-			| TLocal ({v_extra = Some([],Some {eexpr = TLocal v'})} as v) when Meta.has (Meta.Custom ":ssa") v.v_meta ->
+			| TLocal ({v_extra = Some([],Some {eexpr = TArrayDecl ({eexpr = TLocal v'} :: _)})} as v) when Meta.has (Meta.Custom ":ssa") v.v_meta ->
 				{e with eexpr = TLocal v'}
 			| TBlock el ->
 				let rec filter e = match e.eexpr with
@@ -885,13 +921,12 @@ module ConstPropagation = struct
 				| TDynamic _ -> raise Not_found
 				| _ -> ()
 			end;
-			let e = IntMap.find v.v_id ssa.var_values in
-			let reset() =
-				ssa.var_values <- IntMap.add v.v_id e ssa.var_values;
-			in
-			ssa.var_values <- IntMap.remove v.v_id ssa.var_values;
+			let e = Ssa.get_var_value v in
+			let old = v.v_extra in
+			v.v_extra <- None;
 			let e = value ssa e in
-			reset();
+			v.v_extra <- old;
+			Ssa.set_var_value v e;
 			e
 		with Not_found ->
 			e
@@ -919,7 +954,7 @@ module ConstPropagation = struct
 				e
 			else
 				value ssa e'
-		| TCall ({eexpr = TLocal {v_name = "__ssa_phi__"}},el) ->
+		| TCall (({eexpr = TLocal {v_name = "__ssa_phi__"}} as e1),el) ->
 			let el = List.map (value ssa) el in
 			begin match el with
 				| [] -> assert false
@@ -927,7 +962,7 @@ module ConstPropagation = struct
 					if List.for_all (fun e2 -> expr_eq e1 e2) el then
 						value ssa e1
 					else
-						e
+						{e with eexpr = TCall(e1,el)}
 			end
 		| TParenthesis e1 | TMeta(_,e1) ->
 			value ssa e1
@@ -1074,7 +1109,7 @@ module Checker = struct
 			given_warnings := PMap.add p true !given_warnings
 		in
 		let resolve_value v =
-			let e' = IntMap.find v.v_id ssa.var_values in
+			let e' = Ssa.get_var_value v in
 			begin match e'.eexpr with
 				| TLocal v' when v == v' -> e'
 				| _ -> e'