Browse Source

keep track of modified locals when inlining

Simon Krajewski 9 years ago
parent
commit
23847d7c75
1 changed files with 13 additions and 1 deletions
  1. 13 1
      optimizer.ml

+ 13 - 1
optimizer.ml

@@ -345,10 +345,12 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f
 		| TAbstract({a_path = [],("Int" | "Float" | "Bool")},_) -> true
 		| _ -> false
 	in
+	let modified_locals = Hashtbl.create 0 in
 	let rec might_be_affected e =
 		let rec loop e = match e.eexpr with
 			| TConst _ | TFunction _ | TTypeExpr _ -> ()
-			| TLocal _ | TField _ when is_affected_type e.etype -> raise Exit
+			| TLocal v when Hashtbl.mem modified_locals v.v_id -> raise Exit
+			| TField _ when is_affected_type e.etype -> raise Exit
 			| _ -> Type.iter loop e
 		in
 		try
@@ -357,10 +359,20 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f
 		with Exit ->
 			true
 	in
+	let rec collect_modified_locals e = match e.eexpr with
+		| TUnop((Increment | Decrement),_,{eexpr = TLocal v}) when is_affected_type v.v_type ->
+			Hashtbl.add modified_locals v.v_id true
+		| TBinop((OpAssign | OpAssignOp _),{eexpr = TLocal v},e2) when is_affected_type v.v_type ->
+			collect_modified_locals e2;
+			Hashtbl.add modified_locals v.v_id true
+		| _ ->
+			Type.iter collect_modified_locals e
+	in
 	let had_side_effect = ref false in
 	let inlined_vars = List.map2 (fun e (v,_) ->
 		let l = local v in
 		if has_side_effect e then begin
+			collect_modified_locals e;
 			had_side_effect := true;
 			l.i_force_temp <- true;
 		end;