29
29
#include " analysis/lattices/lift.h"
30
30
#include " analysis/lattices/powerset2.h"
31
31
#include " analysis/lattices/stack.h"
32
+ #include " analysis/lattices/tuple.h"
32
33
#include " analysis/lattices/vector.h"
33
34
#include " analysis/liveness-transfer-function.h"
34
35
#include " analysis/reaching-definitions-transfer-function.h"
@@ -154,37 +155,44 @@ static_assert(Lattice<RandomLattice>);
154
155
using ArrayFullLattice = analysis::Array<RandomFullLattice, 2 >;
155
156
using ArrayLattice = analysis::Array<RandomLattice, 2 >;
156
157
158
+ using TupleFullLattice = analysis::Tuple<RandomFullLattice, RandomFullLattice>;
159
+ using TupleLattice = analysis::Tuple<RandomLattice, RandomLattice>;
160
+
157
161
struct RandomFullLattice ::L : std::variant<Bool,
158
162
UInt32,
159
163
FinitePowerset2<BitSet>,
160
164
Inverted<RandomFullLattice>,
161
165
ArrayFullLattice,
162
- Vector<RandomFullLattice>> {};
166
+ Vector<RandomFullLattice>,
167
+ TupleFullLattice> {};
163
168
164
169
struct RandomFullLattice ::ElementImpl
165
170
: std::variant<typename Bool::Element,
166
171
typename UInt32::Element,
167
172
typename FinitePowerset2<BitSet>::Element,
168
173
typename Inverted<RandomFullLattice>::Element,
169
174
typename ArrayFullLattice::Element,
170
- typename Vector<RandomFullLattice>::Element> {};
175
+ typename Vector<RandomFullLattice>::Element,
176
+ typename TupleFullLattice::Element> {};
171
177
172
178
struct RandomLattice ::L : std::variant<RandomFullLattice,
173
179
Flat<uint32_t >,
174
180
Powerset2<BitSet>,
175
181
Lift<RandomLattice>,
176
182
ArrayLattice,
177
- Vector<RandomLattice>> {};
183
+ Vector<RandomLattice>,
184
+ TupleLattice> {};
178
185
179
186
struct RandomLattice ::ElementImpl
180
187
: std::variant<typename RandomFullLattice::Element,
181
188
typename Flat<uint32_t >::Element,
182
189
typename Powerset2<BitSet>::Element,
183
190
typename Lift<RandomLattice>::Element,
184
191
typename ArrayLattice::Element,
185
- typename Vector<RandomLattice>::Element> {};
192
+ typename Vector<RandomLattice>::Element,
193
+ typename TupleLattice::Element> {};
186
194
187
- constexpr int FullLatticePicks = 6 ;
195
+ constexpr int FullLatticePicks = 7 ;
188
196
189
197
RandomFullLattice::RandomFullLattice (Random& rand,
190
198
size_t depth,
@@ -214,13 +222,18 @@ RandomFullLattice::RandomFullLattice(Random& rand,
214
222
lattice = std::make_unique<L>(
215
223
L{Vector{RandomFullLattice{rand, depth + 1 }, rand.upTo (4 )}});
216
224
return ;
225
+ case 6 :
226
+ lattice = std::make_unique<L>(
227
+ L{TupleFullLattice{RandomFullLattice{rand, depth + 1 },
228
+ RandomFullLattice{rand, depth + 1 }}});
229
+ return ;
217
230
}
218
231
WASM_UNREACHABLE (" unexpected pick" );
219
232
}
220
233
221
234
RandomLattice::RandomLattice (Random& rand, size_t depth) : rand(rand) {
222
235
// TODO: Limit the depth once we get lattices with more fan-out.
223
- uint32_t pick = rand.upTo (FullLatticePicks + 5 );
236
+ uint32_t pick = rand.upTo (FullLatticePicks + 6 );
224
237
225
238
if (pick < FullLatticePicks) {
226
239
lattice = std::make_unique<L>(L{RandomFullLattice{rand, depth, pick}});
@@ -245,6 +258,10 @@ RandomLattice::RandomLattice(Random& rand, size_t depth) : rand(rand) {
245
258
lattice = std::make_unique<L>(
246
259
L{Vector{RandomLattice{rand, depth + 1 }, rand.upTo (4 )}});
247
260
return ;
261
+ case FullLatticePicks + 5 :
262
+ lattice = std::make_unique<L>(L{TupleLattice{
263
+ RandomLattice{rand, depth + 1 }, RandomLattice{rand, depth + 1 }}});
264
+ return ;
248
265
}
249
266
WASM_UNREACHABLE (" unexpected pick" );
250
267
}
@@ -280,6 +297,11 @@ RandomFullLattice::Element RandomFullLattice::makeElement() const noexcept {
280
297
}
281
298
return ElementImpl{std::move (elem)};
282
299
}
300
+ if (const auto * l = std::get_if<TupleFullLattice>(lattice.get ())) {
301
+ return ElementImpl{typename TupleFullLattice::Element{
302
+ std::get<0 >(l->lattices ).makeElement (),
303
+ std::get<1 >(l->lattices ).makeElement ()}};
304
+ }
283
305
WASM_UNREACHABLE (" unexpected lattice" );
284
306
}
285
307
@@ -323,6 +345,11 @@ RandomLattice::Element RandomLattice::makeElement() const noexcept {
323
345
}
324
346
return ElementImpl{std::move (elem)};
325
347
}
348
+ if (const auto * l = std::get_if<TupleLattice>(lattice.get ())) {
349
+ return ElementImpl{
350
+ typename TupleLattice::Element{std::get<0 >(l->lattices ).makeElement (),
351
+ std::get<1 >(l->lattices ).makeElement ()}};
352
+ }
326
353
WASM_UNREACHABLE (" unexpected lattice" );
327
354
}
328
355
@@ -376,6 +403,14 @@ void printFullElement(std::ostream& os,
376
403
}
377
404
indent (os, depth);
378
405
os << " ]\n " ;
406
+ } else if (const auto * e =
407
+ std::get_if<typename TupleFullLattice::Element>(&*elem)) {
408
+ os << " Tuple(\n " ;
409
+ const auto & [first, second] = *e;
410
+ printFullElement (os, first, depth + 1 );
411
+ printFullElement (os, second, depth + 1 );
412
+ indent (os, depth);
413
+ os << " )\n " ;
379
414
} else {
380
415
WASM_UNREACHABLE (" unexpected element" );
381
416
}
@@ -437,6 +472,14 @@ void printElement(std::ostream& os,
437
472
}
438
473
indent (os, depth);
439
474
os << " ]\n " ;
475
+ } else if (const auto * e =
476
+ std::get_if<typename TupleLattice::Element>(&*elem)) {
477
+ os << " Tuple(\n " ;
478
+ const auto & [first, second] = *e;
479
+ printElement (os, first, depth + 1 );
480
+ printElement (os, second, depth + 1 );
481
+ indent (os, depth);
482
+ os << " )\n " ;
440
483
} else {
441
484
WASM_UNREACHABLE (" unexpected element" );
442
485
}
0 commit comments