Browse Source

Reconstruct binops in return (#12243)

RblSb 3 months ago
parent
commit
dadcd316aa
2 changed files with 40 additions and 4 deletions
  1. 13 4
      src/optimization/analyzerTexpr.ml
  2. 27 0
      tests/optimization/src/issues/Issue9249.hx

+ 13 - 4
src/optimization/analyzerTexpr.ml

@@ -1006,10 +1006,19 @@ end
 
 module Cleanup = struct
 	let apply com e =
-		let if_or_op e e1 e2 e3 = match (Texpr.skip e1).eexpr,(Texpr.skip e3).eexpr with
-			| TUnop(Not,Prefix,e1),TConst (TBool true) -> optimize_binop {e with eexpr = TBinop(OpBoolOr,e1,e2)} OpBoolOr e1 e2
-			| _,TConst (TBool false) -> optimize_binop {e with eexpr = TBinop(OpBoolAnd,e1,e2)} OpBoolAnd e1 e2
-			| _,TBlock [] -> {e with eexpr = TIf(e1,e2,None)}
+		let if_or_op e e1 e2 e3 = match (Texpr.skip e1).eexpr,(Texpr.skip e2).eexpr,(Texpr.skip e3).eexpr with
+			| _,TReturn(Some b),TReturn(Some {eexpr = TConst (TBool false)}) ->
+				let binop = optimize_binop {e with eexpr = TBinop(OpBoolAnd,e1,b)} OpBoolAnd e1 b in
+				{e with eexpr = TReturn(Some binop)}
+			| TUnop(Not,Prefix,e1),TReturn(Some b),TReturn(Some {eexpr = TConst (TBool true)}) ->
+				let binop = optimize_binop {e with eexpr = TBinop(OpBoolOr,e1,b)} OpBoolOr e1 b in
+				{e with eexpr = TReturn(Some binop)}
+			| TUnop(Not,Prefix,e1),_,TConst (TBool true) ->
+				optimize_binop {e with eexpr = TBinop(OpBoolOr,e1,e2)} OpBoolOr e1 e2
+			| _,_,TConst (TBool false) ->
+				optimize_binop {e with eexpr = TBinop(OpBoolAnd,e1,e2)} OpBoolAnd e1 e2
+			| _,_,TBlock [] ->
+				{e with eexpr = TIf(e1,e2,None)}
 			| _ -> match (Texpr.skip e2).eexpr with
 				| TBlock [] ->
 					let e1' = mk (TUnop(Not,Prefix,e1)) e1.etype e1.epos in

+ 27 - 0
tests/optimization/src/issues/Issue9249.hx

@@ -0,0 +1,27 @@
+package issues;
+
+class Issue9249 {
+	@:js('
+		return _pulsingEffect != null && (_image != null || !issues_Issue9249._hasImage()) && (!_doAnimate || _animation != null && _animation.animationPlaying);
+	')
+	static function test(_pulsingEffect:Any, _image:Any, _doAnimate:Bool, _animation:Dynamic) {
+		return _pulsingEffect != null
+			&& (_image != null || !_hasImage())
+			&& (!_doAnimate || (_animation != null && _animation.animationPlaying));
+	}
+	static function _hasImage() return true;
+
+	@:js('
+		return Std.random(0) == 0 && a && b;
+	')
+	static function and(a:Bool, b:Bool):Bool {
+		var a = Std.random(0) == 0 && a && b;
+		return a;
+	}
+	@:js('
+		return a && b && time == 0;
+	')
+	static function and2(a:Bool, b:Bool, time:Int):Bool {
+		return a && b && time == 0;
+	}
+}