From dbf7dec1423f02e1ad81d5760c833c4a549ea163 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Fri, 20 Feb 2026 03:05:25 +0100 Subject: [PATCH 1/2] Simplify boolean expressions in Java AST --- .../src/com/google/gwt/dev/jjs/impl/Simplifier.java | 11 ++++++----- .../gwt/dev/jjs/impl/DeadCodeEliminationTest.java | 8 ++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java b/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java index d7dd069accc..489604bce65 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java +++ b/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java @@ -429,9 +429,10 @@ public static JExpression simplifyAnd(JBinaryOperation expression) { if (rhs instanceof JBooleanLiteral) { if (((JBooleanLiteral) rhs).getValue()) { return lhs; - } else if (!lhs.hasSideEffects()) { - // Do not remove lhs if it had side effects - return rhs; + } else { + // if side effect, allow rewriting a() && false && b() -> (a(), false) && b() + // -> (a(), false && b()) -> (a(), false) + return lhs.hasSideEffects() ? new JMultiExpression(info, lhs, rhs) : rhs; } } @@ -482,8 +483,8 @@ public static JExpression simplifyOr(JBinaryOperation expression) { if (rhs instanceof JBooleanLiteral) { if (!((JBooleanLiteral) rhs).getValue()) { return lhs; - } else if (!lhs.hasSideEffects()) { - return rhs; + } else { + return lhs.hasSideEffects() ? new JMultiExpression(info, lhs, rhs) : rhs; } } return expression; diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/DeadCodeEliminationTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/DeadCodeEliminationTest.java index 5bc051d8033..93510b822f0 100644 --- a/dev/core/test/com/google/gwt/dev/jjs/impl/DeadCodeEliminationTest.java +++ b/dev/core/test/com/google/gwt/dev/jjs/impl/DeadCodeEliminationTest.java @@ -298,8 +298,10 @@ public void testCommuteMultiExpression() throws Exception { + "static int f1;" + "static A createA() { A.f1 = 1; return new A(); } " + "static boolean booleanWithSideEffects() { createA(); return true;}" + + "static boolean randomBooleanWithSideEffects() { createA(); return random() > .5;}" + "static boolean booleanWithoutSideEffects() { return true;}" + "static int arithmeticWithSideEffects() { createA(); return 4;}" + + "static native double random() /*-{ }-*/;" + "}"); optimizeExpressions(false, "boolean", "true && A.booleanWithoutSideEffects()") @@ -311,6 +313,12 @@ public void testCommuteMultiExpression() throws Exception { optimizeExpressions(false, "boolean", "false && A.booleanWithSideEffects()") .intoString("return false;"); + optimizeExpressions(false, "int", "A.randomBooleanWithSideEffects() && false && A.randomBooleanWithSideEffects() ? 1 : 2") + .intoString("return (EntryPoint$A.f1 = 1, new EntryPoint$A(), (EntryPoint$A.random() > 0.5, 2));"); + + optimizeExpressions(false, "int", "A.randomBooleanWithSideEffects() || true || A.randomBooleanWithSideEffects() ? 1 : 2") + .intoString("return (EntryPoint$A.f1 = 1, new EntryPoint$A(), (EntryPoint$A.random() > 0.5, 1));"); + optimizeExpressions(false, "int", "3 + A.arithmeticWithSideEffects()") .intoString("return (EntryPoint$A.f1 = 1, new EntryPoint$A(), 7);"); } From 54102dd710a6210510ad810d813ae1da338de62b Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Tue, 24 Feb 2026 08:20:48 +0100 Subject: [PATCH 2/2] Add test cases, code style --- .../google/gwt/dev/jjs/impl/Simplifier.java | 14 ++++++--- .../dev/jjs/impl/DeadCodeEliminationTest.java | 30 +++++++++++++++---- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java b/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java index 489604bce65..e054081b931 100644 --- a/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java +++ b/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java @@ -429,10 +429,14 @@ public static JExpression simplifyAnd(JBinaryOperation expression) { if (rhs instanceof JBooleanLiteral) { if (((JBooleanLiteral) rhs).getValue()) { return lhs; - } else { - // if side effect, allow rewriting a() && false && b() -> (a(), false) && b() + } else if (lhs.hasSideEffects()) { + // if side effect, rewrite a() && false to (a(), false) + // so that parent node can be simplified further + // e.g. (a() && false) && b() -> (a(), false) && b() // -> (a(), false && b()) -> (a(), false) - return lhs.hasSideEffects() ? new JMultiExpression(info, lhs, rhs) : rhs; + return new JMultiExpression(info, lhs, rhs); + } else { + return rhs; } } @@ -483,8 +487,10 @@ public static JExpression simplifyOr(JBinaryOperation expression) { if (rhs instanceof JBooleanLiteral) { if (!((JBooleanLiteral) rhs).getValue()) { return lhs; + } else if (lhs.hasSideEffects()) { + return new JMultiExpression(info, lhs, rhs); } else { - return lhs.hasSideEffects() ? new JMultiExpression(info, lhs, rhs) : rhs; + return rhs; } } return expression; diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/DeadCodeEliminationTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/DeadCodeEliminationTest.java index 93510b822f0..d641d08ef0d 100644 --- a/dev/core/test/com/google/gwt/dev/jjs/impl/DeadCodeEliminationTest.java +++ b/dev/core/test/com/google/gwt/dev/jjs/impl/DeadCodeEliminationTest.java @@ -298,10 +298,12 @@ public void testCommuteMultiExpression() throws Exception { + "static int f1;" + "static A createA() { A.f1 = 1; return new A(); } " + "static boolean booleanWithSideEffects() { createA(); return true;}" - + "static boolean randomBooleanWithSideEffects() { createA(); return random() > .5;}" + + "@javaemul.internal.annotations.DoNotInline " + + "static boolean notInlinedBool1() { return true;}" + + "@javaemul.internal.annotations.DoNotInline " + + "static boolean notInlinedBool2() { return true;}" + "static boolean booleanWithoutSideEffects() { return true;}" + "static int arithmeticWithSideEffects() { createA(); return 4;}" - + "static native double random() /*-{ }-*/;" + "}"); optimizeExpressions(false, "boolean", "true && A.booleanWithoutSideEffects()") @@ -313,11 +315,27 @@ public void testCommuteMultiExpression() throws Exception { optimizeExpressions(false, "boolean", "false && A.booleanWithSideEffects()") .intoString("return false;"); - optimizeExpressions(false, "int", "A.randomBooleanWithSideEffects() && false && A.randomBooleanWithSideEffects() ? 1 : 2") - .intoString("return (EntryPoint$A.f1 = 1, new EntryPoint$A(), (EntryPoint$A.random() > 0.5, 2));"); + optimizeExpressions(false, "boolean", "A.notInlinedBool1() && false") + .intoString("return (EntryPoint$A.notInlinedBool1(), false);"); - optimizeExpressions(false, "int", "A.randomBooleanWithSideEffects() || true || A.randomBooleanWithSideEffects() ? 1 : 2") - .intoString("return (EntryPoint$A.f1 = 1, new EntryPoint$A(), (EntryPoint$A.random() > 0.5, 1));"); + optimizeExpressions(false, "int", + "A.notInlinedBool1() && (false && A.notInlinedBool2()) ? 1 : 2") + .intoString("return (EntryPoint$A.notInlinedBool1(), 2);"); + + optimizeExpressions(false, "int", + "(A.notInlinedBool1() && false) && A.notInlinedBool2() ? 1 : 2") + .intoString("return (EntryPoint$A.notInlinedBool1(), 2);"); + + optimizeExpressions(false, "boolean", "A.notInlinedBool1() || true") + .intoString("return (EntryPoint$A.notInlinedBool1(), true);"); + + optimizeExpressions(false, "int", + "A.notInlinedBool1() || (true || A.notInlinedBool2()) ? 1 : 2") + .intoString("return (EntryPoint$A.notInlinedBool1(), 1);"); + + optimizeExpressions(false, "int", + "(A.notInlinedBool1() || true) || A.notInlinedBool2() ? 1 : 2") + .intoString("return (EntryPoint$A.notInlinedBool1(), 1);"); optimizeExpressions(false, "int", "3 + A.arithmeticWithSideEffects()") .intoString("return (EntryPoint$A.f1 = 1, new EntryPoint$A(), 7);");