Переглянути джерело

do not swap `@:commutative` ops if the arguments have no side-effects so we can optimize (closes #3869)

Simon Krajewski 10 роки тому
батько
коміт
f1bf5164c1
2 змінених файлів з 20 додано та 0 видалено
  1. 18 0
      tests/optimization/src/TestAnalyzer.hx
  2. 2 0
      typer.ml

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

@@ -3,6 +3,12 @@ private enum E {
 	B(?i:Int);
 }
 
+@:forward
+private abstract Vec2({x:Float, y:Float}) from {x:Float, y:Float} {
+	@:commutative @:op(A * B) static inline function mul(a:Vec2, b:Float):Vec2
+		return {x: a.x * b, y: a.y * b};
+}
+
 class TestAnalyzer extends TestBase {
 
 	static function main() {
@@ -676,6 +682,18 @@ class TestAnalyzer extends TestBase {
 		}
 	}
 
+	function testIssue3869() {
+        var v1:Vec2 = {x: 1., y: 2.};
+        var r = v1 * 2;
+		assertEqualsConst(2., r.x);
+		assertEqualsConst(4., r.y);
+
+        var v2:Vec2 = {x: 1., y: 2.};
+        var r2 = 2 * v2;
+		assertEqualsConst(2., r2.x);
+		assertEqualsConst(4., r2.y);
+	}
+
 	function cond1() {
 		append("cond1");
 		return true;

+ 2 - 0
typer.ml

@@ -2243,6 +2243,8 @@ and type_binop2 ctx op (e1 : texpr) (e2 : Ast.expr) is_assign_op wt p =
 							check_constraints ctx "" cf.cf_params monos (apply_params a.a_params tl) false cf.cf_pos;
 							let e = if not swapped then
 								make e1 e2
+							else if not (Optimizer.has_side_effect e1) && not (Optimizer.has_side_effect e2) then
+								make e1 e2
 							else
 								let v1,v2 = gen_local ctx t1, gen_local ctx t2 in
 								let ev1,ev2 = mk (TVar(v1,Some e1)) ctx.t.tvoid p,mk (TVar(v2,Some e2)) ctx.t.tvoid p in