Skip to content

Commit 09ac6aa

Browse files
authored
make sure we do not fold out code from blocks with a fallthrough value, and then since the parent blocks do not have such values, we can finalize them with their type as a concrete type should not vanish (#1302)
1 parent 81afbbf commit 09ac6aa

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

src/passes/CodeFolding.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,12 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
127127
if (curr->condition || curr->value) {
128128
unoptimizables.insert(curr->name);
129129
} else {
130-
// we can only optimize if we are at the end of the parent block
130+
// we can only optimize if we are at the end of the parent block,
131+
// and if the parent block does not return a value (we can't move
132+
// elements out of it if there is a value being returned)
131133
Block* parent = controlFlowStack.back()->dynCast<Block>();
132-
if (parent && curr == parent->list.back()) {
134+
if (parent && curr == parent->list.back() &&
135+
!isConcreteWasmType(parent->list.back()->type)) {
133136
breakTails[curr->name].push_back(Tail(curr, parent));
134137
} else {
135138
unoptimizables.insert(curr->name);
@@ -168,8 +171,13 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
168171
}
169172

170173
void visitBlock(Block* curr) {
174+
if (curr->list.empty()) return;
171175
if (!curr->name.is()) return;
172176
if (unoptimizables.count(curr->name) > 0) return;
177+
// we can't optimize a fallthrough value
178+
if (isConcreteWasmType(curr->list.back()->type)) {
179+
return;
180+
}
173181
auto iter = breakTails.find(curr->name);
174182
if (iter == breakTails.end()) return;
175183
// looks promising
@@ -376,8 +384,14 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
376384
if (!tail.isFallthrough()) {
377385
tail.block->list.push_back(last);
378386
}
379-
// the block type may change if we removed final values
380-
tail.block->finalize();
387+
// the block type may change if we removed unreachable stuff,
388+
// but in general it should remain the same, as if it had a
389+
// forced type it should remain, *and*, we don't have a
390+
// fallthrough value (we would never get here), so a concrete
391+
// type was not from that. I.e., any type on the block is
392+
// either forced and/or from breaks with a value, so the
393+
// type cannot be changed by moving code out.
394+
tail.block->finalize(tail.block->type);
381395
}
382396
// since we managed a merge, then it might open up more opportunities later
383397
anotherPass = true;

test/passes/code-folding.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,20 @@
106106
)
107107
(return)
108108
)
109+
(func $leave-inner-block-type (; 6 ;) (type $1)
110+
(block $label$1
111+
(drop
112+
(block $label$2 (result i32)
113+
(br_if $label$2
114+
(unreachable)
115+
(unreachable)
116+
)
117+
(br $label$1)
118+
)
119+
)
120+
)
121+
(drop
122+
(i32.const 1)
123+
)
124+
)
109125
)

test/passes/code-folding.wast

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,24 @@
114114
)
115115
)
116116
)
117+
(func $leave-inner-block-type
118+
(block $label$1
119+
(drop
120+
(block $label$2 (result i32) ;; leave this alone (otherwise, if we make it unreachable, we need to do more updating)
121+
(br_if $label$2
122+
(unreachable)
123+
(unreachable)
124+
)
125+
(drop
126+
(i32.const 1)
127+
)
128+
(br $label$1)
129+
)
130+
)
131+
(drop
132+
(i32.const 1)
133+
)
134+
)
135+
)
117136
)
118137

0 commit comments

Comments
 (0)