Skip to content

Commit a2a8d2a

Browse files
authored
Handle unoptimized branches in CodeFolding (#7111)
CodeFolding previously did not consider br_on_* instructions at all, so it would happily merge tails even if there were br_on_* branches to the same label with non-matching tails. Fix the bug by making any label targeted by any instruction not explicitly handled by CodeFolding unoptimizable. This will gracefully handle other branching instructions like `resume` and `resume_throw` as well. Folding these branches properly is left as future work. Also rename the test file from code-folding_enable-threads.wast to just code-folding.wast and enable all features instead of just threads. The old name was left over from when the test was originally ported to lit, and the new feature is necessary because the new test uses GC instructions.
1 parent 3d39401 commit a2a8d2a

File tree

2 files changed

+65
-20
lines changed

2 files changed

+65
-20
lines changed

src/passes/CodeFolding.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@ struct ExpressionMarker
8484
void visitExpression(Expression* expr) { marked.insert(expr); }
8585
};
8686

87-
struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
87+
struct CodeFolding
88+
: public WalkerPass<
89+
ControlFlowWalker<CodeFolding, UnifiedExpressionVisitor<CodeFolding>>> {
8890
bool isFunctionParallel() override { return true; }
8991

9092
std::unique_ptr<Pass> create() override {
@@ -138,6 +140,17 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
138140

139141
// walking
140142

143+
void visitExpression(Expression* curr) {
144+
// For any branching instruction not explicitly handled by this pass, mark
145+
// the labels it branches to unoptimizable.
146+
// TODO: Handle folding br_on* instructions. br_on_null could be folded with
147+
// other kinds of branches and br_on_non_null, br_on_cast, and
148+
// br_on_cast_fail instructions could be folded with other copies of
149+
// themselves.
150+
BranchUtils::operateOnScopeNameUses(
151+
curr, [&](Name label) { unoptimizables.insert(label); });
152+
}
153+
141154
void visitBreak(Break* curr) {
142155
if (curr->condition || curr->value) {
143156
unoptimizables.insert(curr->name);
@@ -155,13 +168,6 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
155168
}
156169
}
157170

158-
void visitSwitch(Switch* curr) {
159-
for (auto target : curr->targets) {
160-
unoptimizables.insert(target);
161-
}
162-
unoptimizables.insert(curr->default_);
163-
}
164-
165171
void visitUnreachable(Unreachable* curr) {
166172
// we can only optimize if we are at the end of the parent block
167173
if (!controlFlowStack.empty()) {

test/lit/passes/code-folding_enable-threads.wast renamed to test/lit/passes/code-folding.wast

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
22
;; NOTE: This test was ported using port_passes_tests_to_lit.py and could be cleaned up.
33

4-
;; RUN: foreach %s %t wasm-opt --code-folding --enable-threads -S -o - | filecheck %s
4+
;; RUN: foreach %s %t wasm-opt -all --code-folding -S -o - | filecheck %s
55

66
(module
77
;; CHECK: (type $0 (func))
@@ -15,13 +15,13 @@
1515
(memory $0 1 1)
1616
;; CHECK: (table $0 282 282 funcref)
1717

18-
;; CHECK: (func $0
18+
;; CHECK: (func $0 (type $0)
1919
;; CHECK-NEXT: (block $label$1
2020
;; CHECK-NEXT: (if
2121
;; CHECK-NEXT: (i32.const 1)
2222
;; CHECK-NEXT: (then
2323
;; CHECK-NEXT: (block $label$3
24-
;; CHECK-NEXT: (call_indirect (type $13)
24+
;; CHECK-NEXT: (call_indirect $0 (type $13)
2525
;; CHECK-NEXT: (block $label$4
2626
;; CHECK-NEXT: (br $label$3)
2727
;; CHECK-NEXT: )
@@ -52,7 +52,7 @@
5252
)
5353
)
5454
)
55-
;; CHECK: (func $negative-zero (result f32)
55+
;; CHECK: (func $negative-zero (type $1) (result f32)
5656
;; CHECK-NEXT: (if (result f32)
5757
;; CHECK-NEXT: (i32.const 0)
5858
;; CHECK-NEXT: (then
@@ -82,7 +82,7 @@
8282
)
8383
)
8484
)
85-
;; CHECK: (func $negative-zero-b (result f32)
85+
;; CHECK: (func $negative-zero-b (type $1) (result f32)
8686
;; CHECK-NEXT: (drop
8787
;; CHECK-NEXT: (i32.const 0)
8888
;; CHECK-NEXT: )
@@ -105,7 +105,7 @@
105105
)
106106
)
107107
)
108-
;; CHECK: (func $negative-zero-c (result f32)
108+
;; CHECK: (func $negative-zero-c (type $1) (result f32)
109109
;; CHECK-NEXT: (drop
110110
;; CHECK-NEXT: (i32.const 0)
111111
;; CHECK-NEXT: )
@@ -128,7 +128,7 @@
128128
)
129129
)
130130
)
131-
;; CHECK: (func $break-target-outside-of-return-merged-code
131+
;; CHECK: (func $break-target-outside-of-return-merged-code (type $0)
132132
;; CHECK-NEXT: (block $label$A
133133
;; CHECK-NEXT: (if
134134
;; CHECK-NEXT: (unreachable)
@@ -202,7 +202,7 @@
202202
)
203203
)
204204
)
205-
;; CHECK: (func $break-target-inside-all-good
205+
;; CHECK: (func $break-target-inside-all-good (type $0)
206206
;; CHECK-NEXT: (block $folding-inner0
207207
;; CHECK-NEXT: (block $label$A
208208
;; CHECK-NEXT: (if
@@ -269,7 +269,7 @@
269269
)
270270
)
271271
)
272-
;; CHECK: (func $leave-inner-block-type
272+
;; CHECK: (func $leave-inner-block-type (type $0)
273273
;; CHECK-NEXT: (block $label$1
274274
;; CHECK-NEXT: (drop
275275
;; CHECK-NEXT: (block $label$2
@@ -312,7 +312,7 @@
312312
(memory $0 1 1 shared)
313313
;; CHECK: (export "func_2224" (func $0))
314314
(export "func_2224" (func $0))
315-
;; CHECK: (func $0 (result i32)
315+
;; CHECK: (func $0 (type $0) (result i32)
316316
;; CHECK-NEXT: (local $var$0 i32)
317317
;; CHECK-NEXT: (if (result i32)
318318
;; CHECK-NEXT: (i32.const 0)
@@ -352,7 +352,7 @@
352352

353353
;; CHECK: (global $global$0 (mut i32) (i32.const 10))
354354
(global $global$0 (mut i32) (i32.const 10))
355-
;; CHECK: (func $determinism
355+
;; CHECK: (func $determinism (type $0)
356356
;; CHECK-NEXT: (block $folding-inner0
357357
;; CHECK-NEXT: (block
358358
;; CHECK-NEXT: (block $label$1
@@ -439,7 +439,7 @@
439439
)
440440
(unreachable)
441441
)
442-
;; CHECK: (func $careful-of-the-switch (param $0 i32)
442+
;; CHECK: (func $careful-of-the-switch (type $1) (param $0 i32)
443443
;; CHECK-NEXT: (block $label$1
444444
;; CHECK-NEXT: (block $label$3
445445
;; CHECK-NEXT: (block $label$5
@@ -482,3 +482,42 @@
482482
)
483483
)
484484
)
485+
486+
(module
487+
;; CHECK: (type $0 (func))
488+
489+
;; CHECK: (func $br-on-null (type $0)
490+
;; CHECK-NEXT: (block $block
491+
;; CHECK-NEXT: (drop
492+
;; CHECK-NEXT: (br_on_null $block
493+
;; CHECK-NEXT: (ref.null none)
494+
;; CHECK-NEXT: )
495+
;; CHECK-NEXT: )
496+
;; CHECK-NEXT: (drop
497+
;; CHECK-NEXT: (block (result i32)
498+
;; CHECK-NEXT: (call $br-on-null)
499+
;; CHECK-NEXT: (br $block)
500+
;; CHECK-NEXT: )
501+
;; CHECK-NEXT: )
502+
;; CHECK-NEXT: (call $br-on-null)
503+
;; CHECK-NEXT: )
504+
;; CHECK-NEXT: )
505+
(func $br-on-null
506+
(block $block
507+
(drop
508+
;; The other two tails are the same, but this br_on_null should inhibit code
509+
;; folding.
510+
(br_on_null $block
511+
(ref.null none)
512+
)
513+
)
514+
(drop
515+
(block (result i32)
516+
(call $br-on-null)
517+
(br $block)
518+
)
519+
)
520+
(call $br-on-null)
521+
)
522+
)
523+
)

0 commit comments

Comments
 (0)