浏览代码

[analyzer] initial optimization of `switch (constant)` (not perfect yet)

Simon Krajewski 11 年之前
父节点
当前提交
71ee8ebadc
共有 2 个文件被更改,包括 57 次插入0 次删除
  1. 25 0
      analyzer.ml
  2. 32 0
      tests/optimization/src/Test.hx

+ 25 - 0
analyzer.ml

@@ -920,6 +920,31 @@ module ConstPropagation = struct
 						let eo = match eo with None -> None | Some e -> Some (loop e) in
 						{e with eexpr = TIf(e1,e2,eo)}
 				end;
+			| TSwitch(e1,cases,edef) ->
+				let e1 = loop e1 in
+				let rec check_constant e = match e.eexpr with
+					| TConst ct -> ct
+					| TParenthesis e1 | TCast(e1,None) | TMeta(_,e1) -> check_constant e1
+					| _ -> raise Not_found
+				in
+				begin try
+					let ct = check_constant e1 in
+					begin try
+						let _,e = List.find (fun (el,_) ->
+							List.exists (fun e -> match e.eexpr with
+								| TConst ct2 -> ct = ct2
+								| _ -> false
+							) el
+						) cases in
+						loop e
+					with Not_found ->
+						begin match edef with None -> raise Not_found | Some e -> loop e end
+					end
+				with Not_found ->
+					let cases = List.map (fun (el,e) -> el,loop e) cases in
+					let edef = match edef with None -> None | Some e -> Some (loop e) in
+					{e with eexpr = TSwitch(e1,cases,edef)}
+				end
 			| _ ->
 				Type.map_expr loop e
 		in

+ 32 - 0
tests/optimization/src/Test.hx

@@ -141,4 +141,36 @@ class Test {
 	static function testAbstractOverStringBinop() {
 		var s = "" + A;
 	}
+
+	@:js('
+		var a = true;
+		var b = 0;
+		b = 1;
+		b;
+	')
+	static function testSwitch1() {
+		var a = true;
+		var b = 0;
+		switch (a) {
+			case true: b = 1;
+			case false: b = 2;
+		}
+		b; // TODO: this should become 1
+	}
+
+	@:js('
+		var a = true;
+		var b = 0;
+		a = true;
+		a;
+	')
+	static function testSwitch2() {
+		var a = true;
+		var b = 0;
+		switch (b) {
+			case -1: a = false;
+			default: a = true;
+		}
+		a;
+	}
 }