Преглед на файлове

speed up CopyPropagation

The transfer function is called frequently, so let's move the lookups to commit instead.
Simon Krajewski преди 9 години
родител
ревизия
dd16b7645c
променени са 2 файла, в които са добавени 24 реда и са изтрити 32 реда
  1. 21 31
      analyzer.ml
  2. 3 1
      optimizer.ml

+ 21 - 31
analyzer.ml

@@ -1903,12 +1903,12 @@ module CopyPropagation = DataFlow(struct
 	type t =
 		| Top
 		| Bottom
-		| Local of (BasicBlock.t * tvar)
+		| Local of tvar
 
 	let to_string = function
 		| Top -> "Top"
 		| Bottom -> "Bottom"
-		| Local(bb,v) -> Printf.sprintf "%s<%i>" v.v_name v.v_id
+		| Local v -> Printf.sprintf "%s<%i>" v.v_name v.v_id
 
 	let conditional = false
 	let flag = FlagCopyPropagation
@@ -1923,29 +1923,13 @@ module CopyPropagation = DataFlow(struct
 	let equals t1 t2 = match t1,t2 with
 		| Top,Top -> true
 		| Bottom,Bottom -> true
-		| Local(_,v1),Local(_,v2) -> v1.v_id = v2.v_id
+		| Local v1,Local v2 -> v1.v_id = v2.v_id
 		| _ -> false
 
 	let transfer ctx bb e =
-		let local bb v = try
-			begin match get_cell v.v_id with
-				| Bottom -> raise Not_found
-				| t -> t
-			end
-		with Not_found ->
-			Local(bb,v)
-		in
 		let rec loop e = match e.eexpr with
 			| TLocal v when not v.v_capture ->
-				let v' = get_var_origin ctx.graph v in
-				(* This restriction is in place due to how we currently reconstruct the AST. Multiple SSA-vars may be turned back to
-				   the same origin var, which creates interference that is not tracked in the analysis. We address this by only
-				   considering variables whose origin-variables are assigned to at most once. *)
-				let writes = try snd (IntMap.find v'.v_id ctx.graph.g_var_writes) with Not_found -> [] in
-				begin match writes with
-					| [bb] -> local bb v
-					| _ -> Bottom
-				end
+				Local v
 			| TParenthesis e1 | TMeta(_,e1) | TCast(e1,None) ->
 				loop e1
 			| _ ->
@@ -1957,20 +1941,26 @@ module CopyPropagation = DataFlow(struct
 		lattice := IntMap.empty
 
 	let commit ctx =
-		(* We don't care about the scope on JS and AS3 because they hoist var declarations. *)
-		let in_scope bb bb' = match ctx.com.platform with
-			| Js _ -> true
-			| Flash when Common.defined ctx.com Define.As3 -> true
-			| _ -> List.mem (List.hd bb'.bb_scopes) bb.bb_scopes
-		in
 		let rec commit bb e = match e.eexpr with
 			| TLocal v when not v.v_capture ->
 				begin try
-					let ct = IntMap.find v.v_id !lattice in
-					begin match ct with
-						| Local(bb',v') when in_scope bb bb' && (type_iseq_strict v.v_type v'.v_type) -> {e with eexpr = TLocal v'}
-						| _ -> raise Not_found
-					end
+					let lat = get_cell v.v_id in
+					let leave () =
+						lattice := IntMap.remove v.v_id !lattice;
+						raise Not_found
+					in
+					let v' = match lat with Local v -> v | _ -> leave() in
+					if not (type_iseq_strict v'.v_type v.v_type) then leave();
+					let v'' = get_var_origin ctx.graph v' in
+					(* This restriction is in place due to how we currently reconstruct the AST. Multiple SSA-vars may be turned back to
+					   the same origin var, which creates interference that is not tracked in the analysis. We address this by only
+					   considering variables whose origin-variables are assigned to at most once. *)
+					let writes = try snd (IntMap.find v''.v_id ctx.graph.g_var_writes) with Not_found -> [] in
+					begin match writes with
+						| [_] -> ()
+						| _ -> leave()
+					end;
+					{e with eexpr = TLocal v'}
 				with Not_found ->
 					e
 				end

+ 3 - 1
optimizer.ml

@@ -220,8 +220,10 @@ let api_inline ctx c field params p = match c.cl_path, field, params with
 	| _ ->
 		api_inline2 ctx.com c field params p
 
-let is_affected_type t = match follow t with
+let rec is_affected_type t = match follow t with
 	| TAbstract({a_path = [],("Int" | "Float" | "Bool")},_) -> true
+	| TAbstract({a_path = ["haxe"],("Int64" | "Int32")},_) -> true
+	| TAbstract(a,tl) -> is_affected_type (Abstract.get_underlying_type a tl)
 	| TDynamic _ -> true (* sadly *)
 	| _ -> false