瀏覽代碼

Fixed loop unrolling (closes #3784, fixes #3792) (#6876)

* fixed loop unrolling (closes #3784, fixes #3792)

* enabled tests for loop unrolling (#3784)
Alexander Kuzmenko 7 年之前
父節點
當前提交
eaf32fecd6
共有 4 個文件被更改,包括 51 次插入39 次删除
  1. 1 0
      extra/CHANGES.txt
  2. 7 7
      src/optimization/optimizer.ml
  3. 30 32
      tests/optimization/src/TestLocalDce.hx
  4. 13 0
      tests/unit/src/unit/issues/Issue3792.hx

+ 1 - 0
extra/CHANGES.txt

@@ -2,6 +2,7 @@ XXXX-XX-XX: 4.0.0-preview.4
 
 	General improvements and optimizations:
 
+	all : implemented `for` loop unrolling (#3784)
 	js : added externs for js.Date (#6855)
 
 	Bugfixes:

+ 7 - 7
src/optimization/optimizer.ml

@@ -789,7 +789,7 @@ let rec optimize_for_loop ctx (i,pi) e1 e2 p =
 					NormalWhile
 				)) t_void p;
 			])
-	| TArrayDecl el, TInst({ cl_path = [],"Array" },[pt]) when false ->
+	| TArrayDecl el, TInst({ cl_path = [],"Array" },[pt]) ->
 		begin try
 			let num_expr = ref 0 in
 			let rec loop e = match fst e with
@@ -800,8 +800,6 @@ let rec optimize_for_loop ctx (i,pi) e1 e2 p =
 					Ast.map_expr loop e
 			in
 			ignore(loop e2);
-			let v = add_local ctx i pt p in
-			let e2 = type_expr ctx e2 NoValue in
 			let cost = (List.length el) * !num_expr in
 			let max_cost = try
 				int_of_string (Common.defined_value ctx.com Define.LoopUnrollMaxCost)
@@ -809,13 +807,15 @@ let rec optimize_for_loop ctx (i,pi) e1 e2 p =
 				250
 			in
 			if cost > max_cost then raise Exit;
-			let eloc = mk (TLocal v) v.v_type p in
 			let el = List.map (fun e ->
+				let v = add_local ctx i pt p in
+				let ev = mk (TVar(v, None)) ctx.t.tvoid p in
+				let typed_e2 = type_expr ctx e2 NoValue in
+				let eloc = mk (TLocal v) v.v_type p in
 				let e_assign = mk (TBinop(OpAssign,eloc,e)) e.etype e.epos in
-				concat e_assign e2
+				concat ev (concat e_assign typed_e2)
 			) el in
-			let ev = mk (TVar(v, None)) ctx.t.tvoid p in
-			Some (mk (TBlock (ev :: el)) ctx.t.tvoid p)
+			Some (mk (TBlock el) ctx.t.tvoid p)
 		with Exit ->
 			gen_int_iter pt get_next_array_element get_array_length
 		end

+ 30 - 32
tests/optimization/src/TestLocalDce.hx

@@ -129,13 +129,13 @@ class TestLocalDce {
 		use(s);
 	}
 
-	//@:js('
-		//var s = TestLocalDce.keep(1);
-		//s += 0;
-		//s += 6;
-		//s += 8;
-		//TestJs.use(s);
-	//')
+	@:js('
+		var s = TestLocalDce.keep(1);
+		s += 0;
+		s += 6;
+		s += 8;
+		TestJs.use(s);
+	')
 	static function testLoopUnroll() {
 		var s = keep(1);
 		for (i in [0, 3, 4]) {
@@ -144,7 +144,7 @@ class TestLocalDce {
 		use(s);
 	}
 
-	//@:js('TestJs.use(5.);')
+	@:js('TestJs.use(5.);')
 	static function testLoopUnrollDavid() {
 		var s = 0.0;
 		inline function foo(r)
@@ -154,18 +154,18 @@ class TestLocalDce {
 		use(s);
 	}
 
-	//@:js('
-		//var s = TestLocalDce.keep(1);
-		//var _g = 0;
-		//var _g1 = [0,3,4];
-		//while(_g < _g1.length) {
-			//var i = _g1[_g];
-			//++_g;
-			//s += i * 2;
-			//continue;
-		//}
-		//TestJs.use(s);
-	//')
+	@:js('
+		var s = TestLocalDce.keep(1);
+		var _g = 0;
+		var _g1 = [0,3,4];
+		while(_g < _g1.length) {
+			var i = _g1[_g];
+			++_g;
+			s += i * 2;
+			continue;
+		}
+		TestJs.use(s);
+	')
 	static function testLoopUnrollContinue() {
 		var s = keep(1);
 		for (i in [0, 3, 4]) {
@@ -175,18 +175,16 @@ class TestLocalDce {
 		use(s);
 	}
 
-	//@:js('
-		//var s = TestLocalDce.keep(1);
-		//var _g = 0;
-		//var _g1 = [0,3,4];
-		//while(0 < _g1.length) {
-			//var i = _g1[0];
-			//++_g;
-			//s += i * 2;
-			//break;
-		//}
-		//TestJs.use(s);
-	//')
+	@:js('
+		var s = TestLocalDce.keep(1);
+		var _g1 = [0,3,4];
+		while(0 < _g1.length) {
+			var i = _g1[0];
+			s += i * 2;
+			break;
+		}
+		TestJs.use(s);
+	')
 	static function testLoopUnrollBreak() {
 		var s = keep(1);
 		for (i in [0, 3, 4]) {

+ 13 - 0
tests/unit/src/unit/issues/Issue3792.hx

@@ -0,0 +1,13 @@
+package unit.issues;
+
+class Issue3792 extends unit.Test {
+	function test() {
+		var arr = [];
+		for(x in [1, 2, 3]) {
+			arr.push(function() return x);
+		}
+
+		var result = [for(fn in arr) fn()];
+		aeq([1, 2, 3], result);
+	}
+}