@@ -61,12 +61,17 @@ struct Flatten
61
61
std::vector<Expression*> ourPreludes;
62
62
Builder builder (*getModule ());
63
63
64
+ if (curr->is <Const>() || curr->is <Nop>() || curr->is <Unreachable>()) {
65
+ return ;
66
+ }
67
+
64
68
if (Flat::isControlFlowStructure (curr)) {
65
69
// handle control flow explicitly. our children do not have control flow,
66
70
// but they do have preludes which we need to set up in the right place
67
71
68
72
// no one should have given us preludes, they are on the children
69
73
assert (preludes.find (curr) == preludes.end ());
74
+
70
75
if (auto * block = curr->dynCast <Block>()) {
71
76
// make a new list, where each item's preludes are added before it
72
77
ExpressionList newList (getModule ()->allocator );
@@ -106,6 +111,7 @@ struct Flatten
106
111
}
107
112
// the block now has no return value, and may have become unreachable
108
113
block->finalize (none);
114
+
109
115
} else if (auto * iff = curr->dynCast <If>()) {
110
116
// condition preludes go before the entire if
111
117
auto * rep = getPreludesWithExpression (iff->condition , iff);
@@ -138,6 +144,7 @@ struct Flatten
138
144
ourPreludes.push_back (prelude);
139
145
}
140
146
replaceCurrent (rep);
147
+
141
148
} else if (auto * loop = curr->dynCast <Loop>()) {
142
149
// remove a loop value
143
150
Expression* rep = loop;
@@ -155,15 +162,18 @@ struct Flatten
155
162
loop->body = getPreludesWithExpression (originalBody, loop->body );
156
163
loop->finalize ();
157
164
replaceCurrent (rep);
165
+
158
166
} else {
159
167
WASM_UNREACHABLE (" unexpected expr type" );
160
168
}
169
+
161
170
} else {
162
171
// for anything else, there may be existing preludes
163
172
auto iter = preludes.find (curr);
164
173
if (iter != preludes.end ()) {
165
174
ourPreludes.swap (iter->second );
166
175
}
176
+
167
177
// special handling
168
178
if (auto * set = curr->dynCast <LocalSet>()) {
169
179
if (set->isTee ()) {
@@ -178,6 +188,7 @@ struct Flatten
178
188
replaceCurrent (builder.makeLocalGet (set->index , localType));
179
189
}
180
190
}
191
+
181
192
} else if (auto * br = curr->dynCast <Break>()) {
182
193
if (br->value ) {
183
194
auto type = br->value ->type ;
@@ -203,6 +214,7 @@ struct Flatten
203
214
replaceCurrent (br->value );
204
215
}
205
216
}
217
+
206
218
} else if (auto * sw = curr->dynCast <Switch>()) {
207
219
if (sw->value ) {
208
220
auto type = sw->value ->type ;
@@ -227,28 +239,22 @@ struct Flatten
227
239
}
228
240
}
229
241
}
242
+
230
243
// continue for general handling of everything, control flow or otherwise
231
244
curr = getCurrent (); // we may have replaced it
232
245
// we have changed children
233
246
ReFinalizeNode ().visit (curr);
234
- // move everything to the prelude, if we need to: anything but constants
235
- if (!curr->is <Const>()) {
236
- if (curr->type == unreachable) {
237
- ourPreludes.push_back (curr);
238
- replaceCurrent (builder.makeUnreachable ());
239
- } else if (curr->type == none) {
240
- if (!curr->is <Nop>()) {
241
- ourPreludes.push_back (curr);
242
- replaceCurrent (builder.makeNop ());
243
- }
244
- } else {
245
- // use a local
246
- auto type = curr->type ;
247
- Index temp = builder.addVar (getFunction (), type);
248
- ourPreludes.push_back (builder.makeLocalSet (temp, curr));
249
- replaceCurrent (builder.makeLocalGet (temp, type));
250
- }
247
+ if (curr->type == unreachable) {
248
+ ourPreludes.push_back (curr);
249
+ replaceCurrent (builder.makeUnreachable ());
250
+ } else if (curr->type .isConcrete ()) {
251
+ // use a local
252
+ auto type = curr->type ;
253
+ Index temp = builder.addVar (getFunction (), type);
254
+ ourPreludes.push_back (builder.makeLocalSet (temp, curr));
255
+ replaceCurrent (builder.makeLocalGet (temp, type));
251
256
}
257
+
252
258
// next, finish up: migrate our preludes if we can
253
259
if (!ourPreludes.empty ()) {
254
260
auto * parent = getParent ();
0 commit comments