Skip to content

Commit bf24bb9

Browse files
authored
feat: Statically eliminate logical expression branches (#1967)
1 parent f95ee44 commit bf24bb9

31 files changed

+772
-3317
lines changed

src/compiler.ts

+39-16
Original file line numberDiff line numberDiff line change
@@ -4577,15 +4577,26 @@ export class Compiler extends DiagnosticEmitter {
45774577

45784578
// simplify if only interested in true or false
45794579
if (contextualType == Type.bool || contextualType == Type.void) {
4580-
rightExpr = this.compileExpression(right, leftType, inheritedConstraints);
4581-
rightType = this.currentType;
4582-
rightFlow.freeScopedLocals();
4580+
leftExpr = this.makeIsTrueish(leftExpr, leftType, left);
4581+
4582+
// shortcut if lhs is always false
4583+
let condKind = this.evaluateCondition(leftExpr);
4584+
if (condKind == ConditionKind.FALSE) {
4585+
expr = leftExpr;
4586+
} else {
4587+
rightExpr = this.compileExpression(right, leftType, inheritedConstraints);
4588+
rightType = this.currentType;
4589+
rightFlow.freeScopedLocals();
4590+
rightExpr = this.makeIsTrueish(rightExpr, rightType, right);
4591+
4592+
// simplify if lhs is always true
4593+
if (condKind == ConditionKind.TRUE) {
4594+
expr = rightExpr;
4595+
} else {
4596+
expr = module.if(leftExpr, rightExpr, module.i32(0));
4597+
}
4598+
}
45834599
this.currentFlow = flow;
4584-
expr = module.if(
4585-
this.makeIsTrueish(leftExpr, leftType, left),
4586-
this.makeIsTrueish(rightExpr, rightType, right),
4587-
module.i32(0)
4588-
);
45894600
this.currentType = Type.bool;
45904601

45914602
} else {
@@ -4630,15 +4641,26 @@ export class Compiler extends DiagnosticEmitter {
46304641

46314642
// simplify if only interested in true or false
46324643
if (contextualType == Type.bool || contextualType == Type.void) {
4633-
rightExpr = this.compileExpression(right, leftType, inheritedConstraints);
4634-
rightType = this.currentType;
4635-
rightFlow.freeScopedLocals();
4644+
leftExpr = this.makeIsTrueish(leftExpr, leftType, left);
4645+
4646+
// shortcut if lhs is always true
4647+
let condKind = this.evaluateCondition(leftExpr);
4648+
if (condKind == ConditionKind.TRUE) {
4649+
expr = leftExpr;
4650+
} else {
4651+
rightExpr = this.compileExpression(right, leftType, inheritedConstraints);
4652+
rightType = this.currentType;
4653+
rightFlow.freeScopedLocals();
4654+
rightExpr = this.makeIsTrueish(rightExpr, rightType, right);
4655+
4656+
// simplify if lhs is always false
4657+
if (condKind == ConditionKind.FALSE) {
4658+
expr = rightExpr;
4659+
} else {
4660+
expr = module.if(leftExpr, module.i32(1), rightExpr);
4661+
}
4662+
}
46364663
this.currentFlow = flow;
4637-
expr = module.if(
4638-
this.makeIsTrueish(leftExpr, leftType, left),
4639-
module.i32(1),
4640-
this.makeIsTrueish(rightExpr, rightType, right)
4641-
);
46424664
this.currentType = Type.bool;
46434665

46444666
} else {
@@ -10037,6 +10059,7 @@ export class Compiler extends DiagnosticEmitter {
1003710059

1003810060
/** Evaluates a boolean condition, determining whether it is TRUE, FALSE or UNKNOWN. */
1003910061
evaluateCondition(expr: ExpressionRef): ConditionKind {
10062+
assert(getExpressionType(expr) == TypeRef.I32);
1004010063
var module = this.module;
1004110064
var evaled = module.runExpression(expr, ExpressionRunnerFlags.Default);
1004210065
if (evaled) {

tests/compiler/do.untouched.wat

-5
Original file line numberDiff line numberDiff line change
@@ -2949,11 +2949,6 @@
29492949
i32.const 0
29502950
drop
29512951
i32.const 0
2952-
if (result i32)
2953-
i32.const 1
2954-
else
2955-
i32.const 0
2956-
end
29572952
drop
29582953
)
29592954
(func $start:do

tests/compiler/empty-exportruntime.untouched.wat

-5
Original file line numberDiff line numberDiff line change
@@ -2466,11 +2466,6 @@
24662466
i32.const 0
24672467
drop
24682468
i32.const 0
2469-
if (result i32)
2470-
i32.const 1
2471-
else
2472-
i32.const 0
2473-
end
24742469
drop
24752470
)
24762471
(func $~lib/rt/__visit_globals (param $0 i32)

tests/compiler/for.untouched.wat

-5
Original file line numberDiff line numberDiff line change
@@ -2974,11 +2974,6 @@
29742974
i32.const 0
29752975
drop
29762976
i32.const 0
2977-
if (result i32)
2978-
i32.const 1
2979-
else
2980-
i32.const 0
2981-
end
29822977
drop
29832978
)
29842979
(func $start:for

tests/compiler/issues/1225.untouched.wat

-5
Original file line numberDiff line numberDiff line change
@@ -2419,11 +2419,6 @@
24192419
i32.const 0
24202420
drop
24212421
i32.const 0
2422-
if (result i32)
2423-
i32.const 1
2424-
else
2425-
i32.const 0
2426-
end
24272422
drop
24282423
)
24292424
(func $start:issues/1225

tests/compiler/logical.untouched.wat

-35
Original file line numberDiff line numberDiff line change
@@ -2434,11 +2434,6 @@
24342434
i32.const 0
24352435
drop
24362436
i32.const 0
2437-
if (result i32)
2438-
i32.const 1
2439-
else
2440-
i32.const 0
2441-
end
24422437
drop
24432438
)
24442439
(func $~lib/rt/__visit_globals (param $0 i32)
@@ -2515,11 +2510,6 @@
25152510
i32.const 0
25162511
i32.store
25172512
i32.const 0
2518-
if (result i32)
2519-
unreachable
2520-
else
2521-
i32.const 0
2522-
end
25232513
drop
25242514
f64.const 0
25252515
i64.reinterpret_f64
@@ -2529,18 +2519,8 @@
25292519
i64.sub
25302520
i64.const -9007199254740994
25312521
i64.le_u
2532-
if (result i32)
2533-
unreachable
2534-
else
2535-
i32.const 0
2536-
end
25372522
drop
25382523
i32.const 1
2539-
if (result i32)
2540-
i32.const 1
2541-
else
2542-
unreachable
2543-
end
25442524
drop
25452525
f64.const 1
25462526
i64.reinterpret_f64
@@ -2550,23 +2530,13 @@
25502530
i64.sub
25512531
i64.const -9007199254740994
25522532
i64.le_u
2553-
if (result i32)
2554-
i32.const 1
2555-
else
2556-
unreachable
2557-
end
25582533
drop
25592534
i32.const 1
25602535
if (result i32)
25612536
i32.const 2
25622537
else
25632538
i32.const 1
25642539
end
2565-
if (result i32)
2566-
i32.const 1
2567-
else
2568-
unreachable
2569-
end
25702540
drop
25712541
f64.const 1
25722542
i64.reinterpret_f64
@@ -2588,11 +2558,6 @@
25882558
i64.sub
25892559
i64.const -9007199254740994
25902560
i64.le_u
2591-
if (result i32)
2592-
i32.const 1
2593-
else
2594-
unreachable
2595-
end
25962561
drop
25972562
i32.const 1
25982563
if (result i32)

tests/compiler/managed-cast.untouched.wat

-5
Original file line numberDiff line numberDiff line change
@@ -2541,11 +2541,6 @@
25412541
i32.const 0
25422542
drop
25432543
i32.const 0
2544-
if (result i32)
2545-
i32.const 1
2546-
else
2547-
i32.const 0
2548-
end
25492544
drop
25502545
)
25512546
(func $~lib/rt/__visit_globals (param $0 i32)

tests/compiler/object-literal.untouched.wat

-5
Original file line numberDiff line numberDiff line change
@@ -4278,11 +4278,6 @@
42784278
i32.const 0
42794279
drop
42804280
i32.const 0
4281-
if (result i32)
4282-
i32.const 1
4283-
else
4284-
i32.const 0
4285-
end
42864281
drop
42874282
)
42884283
(func $~lib/rt/__visit_globals (param $0 i32)

tests/compiler/rt/finalize.untouched.wat

-5
Original file line numberDiff line numberDiff line change
@@ -2416,11 +2416,6 @@
24162416
i32.const 0
24172417
drop
24182418
i32.const 0
2419-
if (result i32)
2420-
i32.const 1
2421-
else
2422-
i32.const 0
2423-
end
24242419
drop
24252420
)
24262421
(func $start:rt/finalize

tests/compiler/rt/runtime-incremental-export.untouched.wat

-5
Original file line numberDiff line numberDiff line change
@@ -2466,11 +2466,6 @@
24662466
i32.const 0
24672467
drop
24682468
i32.const 0
2469-
if (result i32)
2470-
i32.const 1
2471-
else
2472-
i32.const 0
2473-
end
24742469
drop
24752470
)
24762471
(func $~lib/rt/__visit_globals (param $0 i32)

tests/compiler/std-wasi/console.untouched.wat

-5
Original file line numberDiff line numberDiff line change
@@ -5317,11 +5317,6 @@
53175317
i32.load offset=8
53185318
local.set $2
53195319
i32.const 1
5320-
if (result i32)
5321-
i32.const 1
5322-
else
5323-
i32.const 0
5324-
end
53255320
drop
53265321
local.get $2
53275322
local.set $3

tests/compiler/std-wasi/process.untouched.wat

-5
Original file line numberDiff line numberDiff line change
@@ -6985,11 +6985,6 @@
69856985
i32.load offset=8
69866986
local.set $2
69876987
i32.const 1
6988-
if (result i32)
6989-
i32.const 1
6990-
else
6991-
i32.const 1
6992-
end
69936988
drop
69946989
local.get $2
69956990
local.set $3

tests/compiler/std/array-literal.untouched.wat

-5
Original file line numberDiff line numberDiff line change
@@ -3872,11 +3872,6 @@
38723872
i32.const 0
38733873
drop
38743874
i32.const 0
3875-
if (result i32)
3876-
i32.const 1
3877-
else
3878-
i32.const 0
3879-
end
38803875
drop
38813876
)
38823877
(func $~lib/rt/__visit_globals (param $0 i32)

0 commit comments

Comments
 (0)