Skip to content

Commit a72c996

Browse files
committed
Handle return calls in CodeFolding
Treat them the same as returns and test that they can be folded out of try-catch blocks because they do not have throws effects.
1 parent b4affd2 commit a72c996

File tree

2 files changed

+207
-6
lines changed

2 files changed

+207
-6
lines changed

src/passes/CodeFolding.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
172172
}
173173
}
174174

175-
void visitReturn(Return* curr) {
175+
void handleReturn(Expression* curr) {
176176
if (!controlFlowStack.empty()) {
177177
// we can easily optimize if we are at the end of the parent block
178178
Block* parent = controlFlowStack.back()->dynCast<Block>();
@@ -186,6 +186,26 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
186186
returnTails.push_back(Tail(curr, getCurrentPointer()));
187187
}
188188

189+
void visitReturn(Return* curr) { handleReturn(curr); }
190+
191+
void visitCall(Call* curr) {
192+
if (curr->isReturn) {
193+
handleReturn(curr);
194+
}
195+
}
196+
197+
void visitCallIndirect(CallIndirect* curr) {
198+
if (curr->isReturn) {
199+
handleReturn(curr);
200+
}
201+
}
202+
203+
void visitCallRef(CallRef* curr) {
204+
if (curr->isReturn) {
205+
handleReturn(curr);
206+
}
207+
}
208+
189209
void visitBlock(Block* curr) {
190210
if (curr->list.empty()) {
191211
return;

test/lit/passes/code-folding-eh-old.wast

Lines changed: 186 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
;; CHECK: (tag $e-i32 (param i32))
77
(tag $e-i32 (param i32))
88

9-
;; CHECK: (func $pop-test (type $0)
9+
;; CHECK: (func $pop-test (type $1)
1010
;; CHECK-NEXT: (block $folding-inner0
1111
;; CHECK-NEXT: (try
1212
;; CHECK-NEXT: (do
@@ -67,12 +67,55 @@
6767
)
6868
)
6969

70-
;; CHECK: (func $foo (type $0)
70+
;; CHECK: (func $try-call-optimize-terminating-tails-success (type $0) (result i32)
71+
;; CHECK-NEXT: (block $folding-inner0
72+
;; CHECK-NEXT: (return
73+
;; CHECK-NEXT: (block (result i32)
74+
;; CHECK-NEXT: (try
75+
;; CHECK-NEXT: (do
76+
;; CHECK-NEXT: (br $folding-inner0)
77+
;; CHECK-NEXT: )
78+
;; CHECK-NEXT: (catch_all
79+
;; CHECK-NEXT: (br $folding-inner0)
80+
;; CHECK-NEXT: )
81+
;; CHECK-NEXT: )
82+
;; CHECK-NEXT: (i32.const 0)
83+
;; CHECK-NEXT: )
84+
;; CHECK-NEXT: )
85+
;; CHECK-NEXT: )
86+
;; CHECK-NEXT: (drop
87+
;; CHECK-NEXT: (i32.const 1)
88+
;; CHECK-NEXT: )
89+
;; CHECK-NEXT: (drop
90+
;; CHECK-NEXT: (i32.const 1)
91+
;; CHECK-NEXT: )
92+
;; CHECK-NEXT: (return
93+
;; CHECK-NEXT: (i32.const 0)
94+
;; CHECK-NEXT: )
95+
;; CHECK-NEXT: )
96+
(func $try-call-optimize-terminating-tails-success (result i32)
97+
(try
98+
(do
99+
(drop (i32.const 1))
100+
(drop (i32.const 1))
101+
(return (i32.const 0))
102+
)
103+
(catch_all
104+
(drop (i32.const 1))
105+
(drop (i32.const 1))
106+
(return (i32.const 0))
107+
)
108+
)
109+
(i32.const 0)
110+
)
111+
112+
113+
;; CHECK: (func $foo (type $1)
71114
;; CHECK-NEXT: (nop)
72115
;; CHECK-NEXT: )
73116
(func $foo)
74117

75-
;; CHECK: (func $try-call-optimize-terminating-tails (type $1) (result i32)
118+
;; CHECK: (func $try-call-optimize-terminating-tails (type $0) (result i32)
76119
;; CHECK-NEXT: (try
77120
;; CHECK-NEXT: (do
78121
;; CHECK-NEXT: (call $foo)
@@ -116,7 +159,145 @@
116159
(i32.const 0)
117160
)
118161

119-
;; CHECK: (func $try-call-optimize-expression-tails (type $0)
162+
;; CHECK: (func $foo-i32 (type $0) (result i32)
163+
;; CHECK-NEXT: (i32.const 0)
164+
;; CHECK-NEXT: )
165+
(func $foo-i32 (result i32)
166+
(i32.const 0)
167+
)
168+
169+
;; CHECK: (func $try-call-optimize-terminating-tails-call-return (type $0) (result i32)
170+
;; CHECK-NEXT: (try
171+
;; CHECK-NEXT: (do
172+
;; CHECK-NEXT: (drop
173+
;; CHECK-NEXT: (i32.const 1)
174+
;; CHECK-NEXT: )
175+
;; CHECK-NEXT: (drop
176+
;; CHECK-NEXT: (i32.const 1)
177+
;; CHECK-NEXT: )
178+
;; CHECK-NEXT: (return
179+
;; CHECK-NEXT: (call $foo-i32)
180+
;; CHECK-NEXT: )
181+
;; CHECK-NEXT: )
182+
;; CHECK-NEXT: (catch_all
183+
;; CHECK-NEXT: (drop
184+
;; CHECK-NEXT: (i32.const 1)
185+
;; CHECK-NEXT: )
186+
;; CHECK-NEXT: (drop
187+
;; CHECK-NEXT: (i32.const 1)
188+
;; CHECK-NEXT: )
189+
;; CHECK-NEXT: (return
190+
;; CHECK-NEXT: (call $foo-i32)
191+
;; CHECK-NEXT: )
192+
;; CHECK-NEXT: )
193+
;; CHECK-NEXT: )
194+
;; CHECK-NEXT: (i32.const 0)
195+
;; CHECK-NEXT: )
196+
(func $try-call-optimize-terminating-tails-call-return (result i32)
197+
(try
198+
(do
199+
(drop (i32.const 1))
200+
(drop (i32.const 1))
201+
;; Cannot be folded out of the try because it might throw.
202+
(return (call $foo-i32))
203+
)
204+
(catch_all
205+
(drop (i32.const 1))
206+
(drop (i32.const 1))
207+
(return (call $foo-i32))
208+
)
209+
)
210+
(i32.const 0)
211+
)
212+
213+
;; CHECK: (func $try-call-optimize-terminating-tails-return-call (type $0) (result i32)
214+
;; CHECK-NEXT: (block $folding-inner0
215+
;; CHECK-NEXT: (return
216+
;; CHECK-NEXT: (block (result i32)
217+
;; CHECK-NEXT: (try
218+
;; CHECK-NEXT: (do
219+
;; CHECK-NEXT: (br $folding-inner0)
220+
;; CHECK-NEXT: )
221+
;; CHECK-NEXT: (catch_all
222+
;; CHECK-NEXT: (br $folding-inner0)
223+
;; CHECK-NEXT: )
224+
;; CHECK-NEXT: )
225+
;; CHECK-NEXT: (i32.const 0)
226+
;; CHECK-NEXT: )
227+
;; CHECK-NEXT: )
228+
;; CHECK-NEXT: )
229+
;; CHECK-NEXT: (drop
230+
;; CHECK-NEXT: (i32.const 1)
231+
;; CHECK-NEXT: )
232+
;; CHECK-NEXT: (drop
233+
;; CHECK-NEXT: (i32.const 1)
234+
;; CHECK-NEXT: )
235+
;; CHECK-NEXT: (drop
236+
;; CHECK-NEXT: (i32.const 1)
237+
;; CHECK-NEXT: )
238+
;; CHECK-NEXT: (return_call $foo-i32)
239+
;; CHECK-NEXT: )
240+
(func $try-call-optimize-terminating-tails-return-call (result i32)
241+
(try
242+
(do
243+
(drop (i32.const 1))
244+
(drop (i32.const 1))
245+
(drop (i32.const 1))
246+
(return_call $foo-i32)
247+
)
248+
(catch_all
249+
(drop (i32.const 1))
250+
(drop (i32.const 1))
251+
(drop (i32.const 1))
252+
(return_call $foo-i32)
253+
)
254+
)
255+
(i32.const 0)
256+
)
257+
258+
;; CHECK: (func $try-call-optimize-expression-tails-success (type $1)
259+
;; CHECK-NEXT: (block $x
260+
;; CHECK-NEXT: (try
261+
;; CHECK-NEXT: (do
262+
;; CHECK-NEXT: (br $x)
263+
;; CHECK-NEXT: )
264+
;; CHECK-NEXT: (catch_all
265+
;; CHECK-NEXT: (br $x)
266+
;; CHECK-NEXT: )
267+
;; CHECK-NEXT: )
268+
;; CHECK-NEXT: (unreachable)
269+
;; CHECK-NEXT: )
270+
;; CHECK-NEXT: (drop
271+
;; CHECK-NEXT: (i32.const 1)
272+
;; CHECK-NEXT: )
273+
;; CHECK-NEXT: (drop
274+
;; CHECK-NEXT: (i32.const 1)
275+
;; CHECK-NEXT: )
276+
;; CHECK-NEXT: (drop
277+
;; CHECK-NEXT: (i32.const 1)
278+
;; CHECK-NEXT: )
279+
;; CHECK-NEXT: )
280+
(func $try-call-optimize-expression-tails-success
281+
(block $x
282+
(try
283+
(do
284+
(drop (i32.const 1))
285+
(drop (i32.const 1))
286+
(drop (i32.const 1))
287+
(br $x)
288+
)
289+
(catch_all
290+
(drop (i32.const 1))
291+
(drop (i32.const 1))
292+
(drop (i32.const 1))
293+
(br $x)
294+
)
295+
)
296+
(unreachable)
297+
)
298+
)
299+
300+
;; CHECK: (func $try-call-optimize-expression-tails (type $1)
120301
;; CHECK-NEXT: (block $x
121302
;; CHECK-NEXT: (try
122303
;; CHECK-NEXT: (do
@@ -156,7 +337,7 @@
156337
)
157338
)
158339

159-
;; CHECK: (func $if-arms-in-catch (type $1) (result i32)
340+
;; CHECK: (func $if-arms-in-catch (type $0) (result i32)
160341
;; CHECK-NEXT: (local $0 i32)
161342
;; CHECK-NEXT: (try
162343
;; CHECK-NEXT: (do

0 commit comments

Comments
 (0)