Selaa lähdekoodia

use local CSE in code motion to prevent code duplication

Simon Krajewski 9 vuotta sitten
vanhempi
commit
0f9e14a92e
2 muutettua tiedostoa jossa 45 lisäystä ja 14 poistoa
  1. 23 14
      analyzer.ml
  2. 22 0
      tests/optimization/src/TestJs.hx

+ 23 - 14
analyzer.ml

@@ -1972,6 +1972,7 @@ module CodeMotion = DataFlow(struct
 			in
 			{ eexpr = def; etype = t; epos = p }
 		in
+		let cache = ref IntMap.empty in
 		let replace decl bb v =
 			let lat,t,p = get_cell v.v_id in
 			match lat with
@@ -1981,24 +1982,32 @@ module CodeMotion = DataFlow(struct
 				if loops = [] || not (has_local1 || has_local2) then raise Exit;
 				let lat = ((Binop(op,lat1,lat2)),t,p) in
 				let bb_loop_pre = IntMap.find (List.hd loops) ctx.graph.g_loops in
-				let v' = if decl then begin
-					set_cell v.v_id (Local(v,bb_loop_pre),t,p);
-					v
-				end else begin
-					let v' = alloc_var "tmp" v.v_type in
-					v'.v_meta <- [Meta.CompilerGenerated,[],p];
-					v'
-				end in
-				let e = to_texpr lat in
-				let ev' = mk (TLocal v') v'.v_type p in
-				let e = mk (TVar(v',Some e)) ctx.com.basic.tvoid p in
-				add_texpr ctx.graph bb_loop_pre e;
-				let ev = mk (TLocal v) v.v_type p in
+				let ev' = try
+					let l = IntMap.find bb_loop_pre.bb_id !cache in
+					snd (List.find (fun (lat',e) -> equals lat lat') l)
+				with Not_found ->
+					let v' = if decl then begin
+						set_cell v.v_id (Local(v,bb_loop_pre),t,p);
+						v
+					end else begin
+						let v' = alloc_var "tmp" v.v_type in
+						v'.v_meta <- [Meta.CompilerGenerated,[],p];
+						v'
+					end in
+					let e = to_texpr lat in
+					let ev' = mk (TLocal v') v'.v_type p in
+					let e = mk (TVar(v',Some e)) ctx.com.basic.tvoid p in
+					add_texpr ctx.graph bb_loop_pre e;
+					cache := IntMap.add bb_loop_pre.bb_id ((lat,ev') :: try IntMap.find bb_loop_pre.bb_id !cache with Not_found -> []) !cache;
+					ev'
+				in
 				if decl then begin
 					set_var_value ctx.graph v bb_loop_pre false (DynArray.length bb_loop_pre.bb_el - 1);
 					mk (TConst TNull) t p
-				end else
+				end else begin
+					let ev = mk (TLocal v) v.v_type p in
 					mk (TBinop(OpAssign,ev,ev')) t p
+				end
 			| _ ->
 				raise Exit
 		in

+ 22 - 0
tests/optimization/src/TestJs.hx

@@ -392,6 +392,28 @@ class TestJs {
 		}
 	}
 
+	@:js('
+		var a = TestJs.getInt();
+		var b = TestJs.getInt();
+		var x;
+		var tmp = a + b;
+		while(a != b) {
+			x = tmp;
+			TestJs["use"](x);
+			TestJs["use"](x);
+		}
+	')
+	static function testCodeMotion5() {
+		var a = getInt();
+		var b = getInt();
+		var x;
+		while (a != b) {
+			x = a + b;
+			use(x);
+			use(x);
+		}
+	}
+
 	@:js('
 		var a = TestJs.getInt();
 		TestJs["use"](a);