Browse Source

exit loop unrolling if we find a break or continue

Simon Krajewski 10 years ago
parent
commit
5030cdd716
2 changed files with 47 additions and 0 deletions
  1. 5 0
      optimizer.ml
  2. 42 0
      tests/optimization/src/TestLocalDce.hx

+ 5 - 0
optimizer.ml

@@ -669,6 +669,11 @@ let rec optimize_for_loop ctx (i,pi) e1 e2 p =
 		begin try
 			let v = add_local ctx i pt in
 			let e2 = type_expr ctx e2 NoValue in
+			let rec loop e = match e.eexpr with
+				| TBreak | TContinue -> raise Exit
+				| _ -> Type.iter loop e
+			in
+			loop e2;
 			let eloc = mk (TLocal v) v.v_type p in
 			let el = List.map (fun e ->
 				let e_assign = mk (TBinop(OpAssign,eloc,e)) e.etype e.epos in

+ 42 - 0
tests/optimization/src/TestLocalDce.hx

@@ -153,5 +153,47 @@ class TestLocalDce {
 		trace(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;
+		}
+		console.log(s);
+	')
+	static function testLoopUnrollContinue() {
+		var s = keep(1);
+		for (i in [0, 3, 4]) {
+			s += i * 2;
+			continue;
+		}
+		trace(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;
+		}
+		console.log(s);
+	')
+	static function testLoopUnrollBreak() {
+		var s = keep(1);
+		for (i in [0, 3, 4]) {
+			s += i * 2;
+			break;
+		}
+		trace(s);
+	}
+
 	static function keep(v:Dynamic) { return v; }
 }