28
28
#include " analysis/lattices/inverted.h"
29
29
#include " analysis/lattices/lift.h"
30
30
#include " analysis/lattices/stack.h"
31
+ #include " analysis/lattices/tuple.h"
31
32
#include " analysis/lattices/vector.h"
32
33
#include " analysis/liveness-transfer-function.h"
33
34
#include " analysis/reaching-definitions-transfer-function.h"
@@ -152,38 +153,47 @@ static_assert(Lattice<RandomLattice>);
152
153
using ArrayFullLattice = analysis::Array<RandomFullLattice, 2 >;
153
154
using ArrayLattice = analysis::Array<RandomLattice, 2 >;
154
155
156
+ using TupleFullLattice = analysis::Tuple<RandomFullLattice, RandomFullLattice>;
157
+ using TupleLattice = analysis::Tuple<RandomLattice, RandomLattice>;
158
+
155
159
struct RandomFullLattice ::L : std::variant<Bool,
156
160
UInt32,
157
161
Inverted<RandomFullLattice>,
158
162
ArrayFullLattice,
159
- Vector<RandomFullLattice>> {};
163
+ Vector<RandomFullLattice>,
164
+ TupleFullLattice> {};
160
165
161
166
struct RandomFullLattice ::ElementImpl
162
167
: std::variant<typename Bool::Element,
163
168
typename UInt32::Element,
164
169
typename Inverted<RandomFullLattice>::Element,
165
170
typename ArrayFullLattice::Element,
166
- typename Vector<RandomFullLattice>::Element> {};
171
+ typename Vector<RandomFullLattice>::Element,
172
+ typename TupleFullLattice::Element> {};
167
173
168
174
struct RandomLattice ::L : std::variant<RandomFullLattice,
169
175
Flat<uint32_t >,
170
176
Lift<RandomLattice>,
171
177
ArrayLattice,
172
- Vector<RandomLattice>> {};
178
+ Vector<RandomLattice>,
179
+ TupleLattice> {};
173
180
174
181
struct RandomLattice ::ElementImpl
175
182
: std::variant<typename RandomFullLattice::Element,
176
183
typename Flat<uint32_t >::Element,
177
184
typename Lift<RandomLattice>::Element,
178
185
typename ArrayLattice::Element,
179
- typename Vector<RandomLattice>::Element> {};
186
+ typename Vector<RandomLattice>::Element,
187
+ typename TupleLattice::Element> {};
188
+
189
+ constexpr int FullLatticePicks = 6 ;
180
190
181
191
RandomFullLattice::RandomFullLattice (Random& rand,
182
192
size_t depth,
183
193
std::optional<uint32_t > maybePick)
184
194
: rand(rand) {
185
195
// TODO: Limit the depth once we get lattices with more fan-out.
186
- uint32_t pick = maybePick ? *maybePick : rand.upTo (5 );
196
+ uint32_t pick = maybePick ? *maybePick : rand.upTo (FullLatticePicks );
187
197
switch (pick) {
188
198
case 0 :
189
199
lattice = std::make_unique<L>(L{Bool{}});
@@ -203,35 +213,43 @@ RandomFullLattice::RandomFullLattice(Random& rand,
203
213
lattice = std::make_unique<L>(
204
214
L{Vector{RandomFullLattice{rand, depth + 1 }, rand.upTo (4 )}});
205
215
return ;
216
+ case 5 :
217
+ lattice = std::make_unique<L>(
218
+ L{TupleFullLattice{RandomFullLattice{rand, depth + 1 },
219
+ RandomFullLattice{rand, depth + 1 }}});
220
+ return ;
206
221
}
207
222
WASM_UNREACHABLE (" unexpected pick" );
208
223
}
209
224
210
225
RandomLattice::RandomLattice (Random& rand, size_t depth) : rand(rand) {
211
226
// TODO: Limit the depth once we get lattices with more fan-out.
212
- uint32_t pick = rand.upTo (9 );
227
+ uint32_t pick = rand.upTo (FullLatticePicks + 5 );
228
+
229
+ if (pick < FullLatticePicks) {
230
+ lattice = std::make_unique<L>(L{RandomFullLattice{rand, depth, pick}});
231
+ return ;
232
+ }
233
+
213
234
switch (pick) {
214
- case 0 :
215
- case 1 :
216
- case 2 :
217
- case 3 :
218
- case 4 :
219
- lattice = std::make_unique<L>(L{RandomFullLattice{rand, depth, pick}});
220
- return ;
221
- case 5 :
235
+ case FullLatticePicks + 0 :
222
236
lattice = std::make_unique<L>(L{Flat<uint32_t >{}});
223
237
return ;
224
- case 6 :
238
+ case FullLatticePicks + 1 :
225
239
lattice = std::make_unique<L>(L{Lift{RandomLattice{rand, depth + 1 }}});
226
240
return ;
227
- case 7 :
241
+ case FullLatticePicks + 2 :
228
242
lattice =
229
243
std::make_unique<L>(L{ArrayLattice{RandomLattice{rand, depth + 1 }}});
230
244
return ;
231
- case 8 :
245
+ case FullLatticePicks + 3 :
232
246
lattice = std::make_unique<L>(
233
247
L{Vector{RandomLattice{rand, depth + 1 }, rand.upTo (4 )}});
234
248
return ;
249
+ case FullLatticePicks + 4 :
250
+ lattice = std::make_unique<L>(L{TupleLattice{
251
+ RandomLattice{rand, depth + 1 }, RandomLattice{rand, depth + 1 }}});
252
+ return ;
235
253
}
236
254
WASM_UNREACHABLE (" unexpected pick" );
237
255
}
@@ -258,6 +276,11 @@ RandomFullLattice::Element RandomFullLattice::makeElement() const noexcept {
258
276
}
259
277
return ElementImpl{std::move (elem)};
260
278
}
279
+ if (const auto * l = std::get_if<TupleFullLattice>(lattice.get ())) {
280
+ return ElementImpl{typename TupleFullLattice::Element{
281
+ std::get<0 >(l->lattices ).makeElement (),
282
+ std::get<1 >(l->lattices ).makeElement ()}};
283
+ }
261
284
WASM_UNREACHABLE (" unexpected lattice" );
262
285
}
263
286
@@ -292,6 +315,11 @@ RandomLattice::Element RandomLattice::makeElement() const noexcept {
292
315
}
293
316
return ElementImpl{std::move (elem)};
294
317
}
318
+ if (const auto * l = std::get_if<TupleLattice>(lattice.get ())) {
319
+ return ElementImpl{
320
+ typename TupleLattice::Element{std::get<0 >(l->lattices ).makeElement (),
321
+ std::get<1 >(l->lattices ).makeElement ()}};
322
+ }
295
323
WASM_UNREACHABLE (" unexpected lattice" );
296
324
}
297
325
@@ -333,6 +361,14 @@ void printFullElement(std::ostream& os,
333
361
}
334
362
indent (os, depth);
335
363
os << " ]\n " ;
364
+ } else if (const auto * e =
365
+ std::get_if<typename TupleFullLattice::Element>(&*elem)) {
366
+ os << " Tuple(\n " ;
367
+ const auto & [first, second] = *e;
368
+ printFullElement (os, first, depth + 1 );
369
+ printFullElement (os, second, depth + 1 );
370
+ indent (os, depth);
371
+ os << " )\n " ;
336
372
} else {
337
373
WASM_UNREACHABLE (" unexpected element" );
338
374
}
@@ -382,6 +418,14 @@ void printElement(std::ostream& os,
382
418
}
383
419
indent (os, depth);
384
420
os << " ]\n " ;
421
+ } else if (const auto * e =
422
+ std::get_if<typename TupleLattice::Element>(&*elem)) {
423
+ os << " Tuple(\n " ;
424
+ const auto & [first, second] = *e;
425
+ printElement (os, first, depth + 1 );
426
+ printElement (os, second, depth + 1 );
427
+ indent (os, depth);
428
+ os << " )\n " ;
385
429
} else {
386
430
WASM_UNREACHABLE (" unexpected element" );
387
431
}
0 commit comments