Skip to content

Commit a2e1702

Browse files
committed
fix blockifyMerge logic - it needs to not skip code in the block we merge to. since that's a fairly specific functionality needed in removeUnusedBrs, move it to there
1 parent 7bc2ed7 commit a2e1702

6 files changed

Lines changed: 116 additions & 32 deletions

src/passes/RemoveUnusedBrs.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,39 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
232232
// this is already an if-else. if one side is a dead end, we can append to the other, if
233233
// there is no returned value to concern us
234234
assert(!isConcreteWasmType(iff->type)); // can't be, since in the middle of a block
235+
236+
// ensures the first node is a block, if it isn't already, and merges in the second,
237+
// either as a single element or, if a block, by appending to the first block. this
238+
// keeps the order of operations in place, that is, the appended element will be
239+
// executed after the first node's elements
240+
auto blockifyMerge = [&](Expression* any, Expression* append) -> Block* {
241+
Block* block = nullptr;
242+
if (any) block = any->dynCast<Block>();
243+
// if the first isn't a block, or it's a block with a name (so we might
244+
// branch to the end, and so can't append to it, we might skip that code!)
245+
// then make a new block
246+
if (!block || block->name.is()) {
247+
block = builder.makeBlock(any);
248+
} else {
249+
assert(!isConcreteWasmType(block->type));
250+
}
251+
auto* other = append->dynCast<Block>();
252+
if (!other) {
253+
block->list.push_back(append);
254+
} else {
255+
for (auto* item : other->list) {
256+
block->list.push_back(item);
257+
}
258+
}
259+
block->finalize();
260+
return block;
261+
};
262+
235263
if (ExpressionAnalyzer::obviouslyDoesNotFlowOut(iff->ifTrue)) {
236-
iff->ifFalse = builder.blockifyMerge(iff->ifFalse, builder.stealSlice(block, i + 1, list.size()));
264+
iff->ifFalse = blockifyMerge(iff->ifFalse, builder.stealSlice(block, i + 1, list.size()));
237265
return true;
238266
} else if (ExpressionAnalyzer::obviouslyDoesNotFlowOut(iff->ifFalse)) {
239-
iff->ifTrue = builder.blockifyMerge(iff->ifTrue, builder.stealSlice(block, i + 1, list.size()));
267+
iff->ifTrue = blockifyMerge(iff->ifTrue, builder.stealSlice(block, i + 1, list.size()));
240268
return true;
241269
}
242270
}

src/wasm-builder.h

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -315,28 +315,6 @@ class Builder {
315315
return block;
316316
}
317317

318-
// ensures the first node is a block, if it isn't already, and merges in the second,
319-
// either as a single element or, if a block, by appending to the first block
320-
Block* blockifyMerge(Expression* any, Expression* append) {
321-
Block* block = nullptr;
322-
if (any) block = any->dynCast<Block>();
323-
if (!block) {
324-
block = makeBlock(any);
325-
} else {
326-
assert(!isConcreteWasmType(block->type));
327-
}
328-
auto* other = append->dynCast<Block>();
329-
if (!other) {
330-
block->list.push_back(append);
331-
} else {
332-
for (auto* item : other->list) {
333-
block->list.push_back(item);
334-
}
335-
}
336-
block->finalize();
337-
return block;
338-
}
339-
340318
// a helper for the common pattern of a sequence of two expressions. Similar to
341319
// blockify, but does *not* reuse a block if the first is one.
342320
Block* makeSequence(Expression* left, Expression* right) {

test/passes/remove-unused-brs.txt

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
(type $3 (func (param i32 i32) (result i32)))
66
(type $4 (func (param i32 i32)))
77
(type $5 (func (param f32 i32 f32 i32 i32 f64 f32) (result i32)))
8+
(type $6 (func (param i32) (result i64)))
89
(memory $0 256 256)
910
(func $b0-yes (type $0) (param $i1 i32)
1011
(block $topmost
@@ -539,11 +540,13 @@
539540
(block $out59
540541
(if
541542
(i32.const 0)
542-
(block $block61
543-
(drop
544-
(i32.const 1)
543+
(block
544+
(block $block61
545+
(drop
546+
(i32.const 1)
547+
)
548+
(call $loops)
545549
)
546-
(call $loops)
547550
(br $in58)
548551
)
549552
(nop)
@@ -584,11 +587,13 @@
584587
(block $out69
585588
(if
586589
(i32.const 0)
587-
(block $block71
588-
(drop
589-
(i32.const 1)
590+
(block
591+
(block $block71
592+
(drop
593+
(i32.const 1)
594+
)
595+
(call $loops)
590596
)
591-
(call $loops)
592597
(drop
593598
(i32.const 102)
594599
)
@@ -1011,4 +1016,23 @@
10111016
(i32.const 1935947830)
10121017
)
10131018
)
1019+
(func $unexitable-loops-result (type $6) (param $0 i32) (result i64)
1020+
(loop $label$0
1021+
(loop $label$1
1022+
(br_if $label$0
1023+
(i32.load8_s
1024+
(i32.const 201460482)
1025+
)
1026+
)
1027+
(block
1028+
(block $label$3
1029+
(br_if $label$1
1030+
(get_local $0)
1031+
)
1032+
)
1033+
(br $label$1)
1034+
)
1035+
)
1036+
)
1037+
)
10141038
)

test/passes/remove-unused-brs.wast

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,5 +901,23 @@
901901
(i32.const 1935947830)
902902
)
903903
)
904+
(func $unexitable-loops-result (param $0 i32) (result i64)
905+
(loop $label$0
906+
(loop $label$1
907+
(if
908+
(i32.load8_s
909+
(i32.const 201460482)
910+
)
911+
(br $label$0)
912+
(block $label$3
913+
(br_if $label$3
914+
(get_local $0)
915+
)
916+
)
917+
)
918+
(br $label$1)
919+
)
920+
)
921+
)
904922
)
905923

test/passes/remove-unused-names_remove-unused-brs_vacuum.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
(type $FUNCSIG$vii (func (param i32 i32)))
2323
(type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
2424
(type $FUNCSIG$id (func (param f64) (result i32)))
25+
(type $23 (func (param i32) (result i64)))
2526
(import "env" "DYNAMICTOP_PTR" (global $import$0 i32))
2627
(import "env" "tempDoublePtr" (global $import$1 i32))
2728
(import "env" "ABORT" (global $import$2 i32))
@@ -113,4 +114,21 @@
113114
(func $23 (type $0) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
114115
(unreachable)
115116
)
117+
(func $unexitable-loops-result (type $23) (param $0 i32) (result i64)
118+
(loop $label$0
119+
(loop $label$1
120+
(br_if $label$0
121+
(i32.load8_s
122+
(i32.const 201460482)
123+
)
124+
)
125+
(block
126+
(br_if $label$1
127+
(get_local $0)
128+
)
129+
(br $label$1)
130+
)
131+
)
132+
)
133+
)
116134
)

test/passes/remove-unused-names_remove-unused-brs_vacuum.wast

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,5 +127,23 @@
127127
(func $23 (param i32) (param i32) (param i32) (result i32)
128128
(unreachable)
129129
)
130+
(func $unexitable-loops-result (param $0 i32) (result i64)
131+
(loop $label$0
132+
(loop $label$1
133+
(if
134+
(i32.load8_s
135+
(i32.const 201460482)
136+
)
137+
(br $label$0)
138+
(block $label$3
139+
(br_if $label$3
140+
(get_local $0)
141+
)
142+
)
143+
)
144+
(br $label$1)
145+
)
146+
)
147+
)
130148
)
131149

0 commit comments

Comments
 (0)