Forráskód Böngészése

[analyzer] propagate constant enum values because enums are immutable

Simon Krajewski 10 éve
szülő
commit
ccd13c368b
2 módosított fájl, 32 hozzáadás és 0 törlés
  1. 8 0
      analyzer.ml
  2. 24 0
      tests/optimization/src/TestAnalyzer.hx

+ 8 - 0
analyzer.ml

@@ -960,6 +960,10 @@ module ConstPropagation = struct
 		| _ ->
 			false
 
+	let semi_awkward_enum_value ssa e i = match e.eexpr with
+		| TCall({eexpr = TField(_,FEnum _)},el) -> (try List.nth el i with Failure _ -> raise Not_found)
+		| _ -> raise Not_found
+
 	let rec local ssa v e =
 		begin try
 			if v.v_capture then raise Not_found;
@@ -1015,6 +1019,10 @@ module ConstPropagation = struct
 			value ssa e1
 		| TLocal v ->
 			local ssa v e
+ 		| TEnumParameter(e1,ef,i) ->
+			let ev = value ssa e1 in
+			begin try semi_awkward_enum_value ssa ev i
+			with Not_found -> e end
 		| _ ->
 			e
 

+ 24 - 0
tests/optimization/src/TestAnalyzer.hx

@@ -1,3 +1,8 @@
+private enum E {
+	A(s:String, i:Int, a:Array<Int>);
+	B(?i:Int);
+}
+
 class TestAnalyzer extends TestBase {
 
 	static function main() {
@@ -652,6 +657,25 @@ class TestAnalyzer extends TestBase {
 		//assertEquals(50, call(a, a = a + 1, a));
 	//}
 
+	function testEnumValues() {
+		var array = [1];
+		var a = A("foo", 12, array);
+		switch (a) {
+			case A(s, i, a):
+				assertEqualsConst("foo", s);
+				assertEqualsConst(12, i);
+				assertEquals(array, a);
+			case B(_):
+		}
+
+		var b = B(0);
+		switch (b) {
+			case B(i):
+				assertEqualsConst(0, i);
+			case A(_):
+		}
+	}
+
 	function cond1() {
 		append("cond1");
 		return true;