Skip to content

Commit 1bd4267

Browse files
authored
[NFC] Properties::hasUnwritableTypeImmediate (#7576)
Many WasmGC instructions have type index immediates that determine the static types of certain operands. When we emit the IR, we need to look at these operands to determine the type index immediate to emit. In cases where the operand is unreachable or has bottom type, there is no possible type index to emit, so we have to emit a replacement. Previously Print.cpp had a visitor for each instruction that has such a type immediate to individually check whether the replacement was necessary. Refactor this to use a new `Properties::hasUnwritableTypeImmediate` function implemented on top of a new DELEGATE_FIELD_REF_CHILD macro in wasm-delegations-fields.def. This function will be used elsewhere in a following PR.
1 parent 4227e60 commit 1bd4267

File tree

3 files changed

+82
-97
lines changed

3 files changed

+82
-97
lines changed

src/ir/properties.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,41 @@ inline MemoryOrder getMemoryOrder(Expression* curr) {
514514
return MemoryOrder::Unordered;
515515
}
516516

517+
// Whether this instruction will be unwritable in the text and binary formats
518+
// because it requires a type index immediate giving the type of a child that
519+
// has unreachable or null type, and therefore does not have a type index.
520+
inline bool hasUnwritableTypeImmediate(Expression* curr) {
521+
#define DELEGATE_ID curr->_id
522+
523+
#define DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(id, field) \
524+
{ \
525+
auto type = curr->cast<id>()->field->type; \
526+
if (type == Type::unreachable || type.isNull()) { \
527+
return true; \
528+
} \
529+
}
530+
531+
#define DELEGATE_FIELD_CHILD(id, field)
532+
#define DELEGATE_FIELD_CHILD_VECTOR(id, field)
533+
#define DELEGATE_FIELD_INT(id, field)
534+
#define DELEGATE_FIELD_INT_ARRAY(id, field)
535+
#define DELEGATE_FIELD_INT_VECTOR(id, field)
536+
#define DELEGATE_FIELD_LITERAL(id, field)
537+
#define DELEGATE_FIELD_NAME(id, field)
538+
#define DELEGATE_FIELD_NAME_VECTOR(id, field)
539+
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field)
540+
#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field)
541+
#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field)
542+
#define DELEGATE_FIELD_TYPE(id, field)
543+
#define DELEGATE_FIELD_TYPE_VECTOR(id, field)
544+
#define DELEGATE_FIELD_HEAPTYPE(id, field)
545+
#define DELEGATE_FIELD_ADDRESS(id, field)
546+
547+
#include "wasm-delegations-fields.def"
548+
549+
return false;
550+
}
551+
517552
// A "generative" expression is one that can generate different results for the
518553
// same inputs, and that difference is *not* explained by other expressions that
519554
// interact with this one. This is an intrinsic/internal property of the

src/passes/Print.cpp

Lines changed: 21 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -313,13 +313,8 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> {
313313
void visitTry(Try* curr);
314314
void visitTryTable(TryTable* curr);
315315

316+
void printUnreachableReplacement(Expression* curr);
316317
bool maybePrintUnreachableReplacement(Expression* curr, Type type);
317-
bool maybePrintUnreachableOrNullReplacement(Expression* curr, Type type);
318-
void visitCallRef(CallRef* curr) {
319-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->target->type)) {
320-
visitExpression(curr);
321-
}
322-
}
323318
void visitRefCast(RefCast* curr) {
324319
if (!maybePrintUnreachableReplacement(curr, curr->type)) {
325320
visitExpression(curr);
@@ -330,26 +325,6 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> {
330325
visitExpression(curr);
331326
}
332327
}
333-
void visitStructGet(StructGet* curr) {
334-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->ref->type)) {
335-
visitExpression(curr);
336-
}
337-
}
338-
void visitStructSet(StructSet* curr) {
339-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->ref->type)) {
340-
visitExpression(curr);
341-
}
342-
}
343-
void visitStructRMW(StructRMW* curr) {
344-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->ref->type)) {
345-
visitExpression(curr);
346-
}
347-
}
348-
void visitStructCmpxchg(StructCmpxchg* curr) {
349-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->ref->type)) {
350-
visitExpression(curr);
351-
}
352-
}
353328
void visitArrayNew(ArrayNew* curr) {
354329
if (!maybePrintUnreachableReplacement(curr, curr->type)) {
355330
visitExpression(curr);
@@ -370,63 +345,28 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> {
370345
visitExpression(curr);
371346
}
372347
}
373-
void visitArraySet(ArraySet* curr) {
374-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->ref->type)) {
375-
visitExpression(curr);
376-
}
377-
}
378-
void visitArrayGet(ArrayGet* curr) {
379-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->ref->type)) {
380-
visitExpression(curr);
381-
}
382-
}
383-
void visitArrayCopy(ArrayCopy* curr) {
384-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->srcRef->type) &&
385-
!maybePrintUnreachableOrNullReplacement(curr, curr->destRef->type)) {
386-
visitExpression(curr);
387-
}
388-
}
389-
void visitArrayFill(ArrayFill* curr) {
390-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->ref->type)) {
391-
visitExpression(curr);
392-
}
393-
}
394-
void visitArrayInitData(ArrayInitData* curr) {
395-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->ref->type)) {
396-
visitExpression(curr);
397-
}
398-
}
399-
void visitArrayInitElem(ArrayInitElem* curr) {
400-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->ref->type)) {
401-
visitExpression(curr);
402-
}
403-
}
404348
void visitContNew(ContNew* curr) {
405349
if (!maybePrintUnreachableReplacement(curr, curr->type)) {
406350
visitExpression(curr);
407351
}
408352
}
409353
void visitContBind(ContBind* curr) {
410-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->cont->type) &&
411-
!maybePrintUnreachableOrNullReplacement(curr, curr->type)) {
354+
if (!maybePrintUnreachableReplacement(curr, curr->type)) {
412355
visitExpression(curr);
413356
}
414357
}
415358
void visitResume(Resume* curr) {
416-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->cont->type) &&
417-
!maybePrintUnreachableOrNullReplacement(curr, curr->type)) {
359+
if (!maybePrintUnreachableReplacement(curr, curr->type)) {
418360
visitExpression(curr);
419361
}
420362
}
421363
void visitResumeThrow(ResumeThrow* curr) {
422-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->cont->type) &&
423-
!maybePrintUnreachableOrNullReplacement(curr, curr->type)) {
364+
if (!maybePrintUnreachableReplacement(curr, curr->type)) {
424365
visitExpression(curr);
425366
}
426367
}
427368
void visitStackSwitch(StackSwitch* curr) {
428-
if (!maybePrintUnreachableOrNullReplacement(curr, curr->cont->type) &&
429-
!maybePrintUnreachableOrNullReplacement(curr, curr->type)) {
369+
if (!maybePrintUnreachableReplacement(curr, curr->type)) {
430370
visitExpression(curr);
431371
}
432372
}
@@ -2776,6 +2716,11 @@ void PrintSExpression::maybePrintImplicitBlock(Expression* curr) {
27762716
}
27772717

27782718
void PrintSExpression::visitExpression(Expression* curr) {
2719+
if (Properties::hasUnwritableTypeImmediate(curr)) {
2720+
printUnreachableReplacement(curr);
2721+
return;
2722+
}
2723+
27792724
o << '(';
27802725
printExpressionContents(curr);
27812726
auto it = ChildIterator(curr);
@@ -2987,16 +2932,7 @@ void PrintSExpression::visitTryTable(TryTable* curr) {
29872932
controlFlowDepth--;
29882933
}
29892934

2990-
bool PrintSExpression::maybePrintUnreachableReplacement(Expression* curr,
2991-
Type type) {
2992-
// When we cannot print an instruction because the child from which it's
2993-
// supposed to get a type immediate is unreachable, then we print a
2994-
// semantically-equivalent block that drops each of the children and ends in
2995-
// an unreachable.
2996-
if (type != Type::unreachable) {
2997-
return false;
2998-
}
2999-
2935+
void PrintSExpression::printUnreachableReplacement(Expression* curr) {
30002936
// Emit a block with drops of the children.
30012937
o << "(block";
30022938
if (!minify) {
@@ -3012,15 +2948,19 @@ bool PrintSExpression::maybePrintUnreachableReplacement(Expression* curr,
30122948
Unreachable unreachable;
30132949
printFullLine(&unreachable);
30142950
decIndent();
3015-
return true;
30162951
}
30172952

3018-
bool PrintSExpression::maybePrintUnreachableOrNullReplacement(Expression* curr,
3019-
Type type) {
3020-
if (type.isNull()) {
3021-
type = Type::unreachable;
2953+
bool PrintSExpression::maybePrintUnreachableReplacement(Expression* curr,
2954+
Type type) {
2955+
// When we cannot print an instruction because the child from which it's
2956+
// supposed to get a type immediate is unreachable, then we print a
2957+
// semantically-equivalent block that drops each of the children and ends in
2958+
// an unreachable.
2959+
if (type == Type::unreachable) {
2960+
printUnreachableReplacement(curr);
2961+
return true;
30222962
}
3023-
return maybePrintUnreachableReplacement(curr, type);
2963+
return false;
30242964
}
30252965

30262966
static bool requiresExplicitFuncType(HeapType type) {

src/wasm-delegations-fields.def

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
// are visited in reverse order, which is convenient for walking by pushing
3939
// them to a stack first).
4040
//
41+
// DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(id, field) - called for each child field
42+
// whose type is given by an immediate in the binary format. If you do not
43+
// define this, then DELEGATE_FIELD_CHILD is called.
44+
//
4145
// DELEGATE_FIELD_OPTIONAL_CHILD(id, field) - called for a child that may not be
4246
// present (like a Return's value). If you do not define this then
4347
// DELEGATE_FIELD_CHILD is called.
@@ -109,6 +113,10 @@
109113
#error please define DELEGATE_FIELD_CHILD(id, field)
110114
#endif
111115

116+
#ifndef DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD
117+
#define DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(id, field) DELEGATE_FIELD_CHILD(id, field)
118+
#endif
119+
112120
#ifndef DELEGATE_FIELD_OPTIONAL_CHILD
113121
#define DELEGATE_FIELD_OPTIONAL_CHILD(id, field) DELEGATE_FIELD_CHILD(id, field)
114122
#endif
@@ -230,6 +238,7 @@
230238
// By default we emit a switch and cases, but that can be customized using the
231239
// following:
232240

241+
233242
#ifndef DELEGATE_FIELD_MAIN_START
234243
#define DELEGATE_FIELD_MAIN_START \
235244
switch (DELEGATE_ID) { \
@@ -610,7 +619,7 @@ DELEGATE_FIELD_INT(I31Get, signed_)
610619
DELEGATE_FIELD_CASE_END(I31Get)
611620

612621
DELEGATE_FIELD_CASE_START(CallRef)
613-
DELEGATE_FIELD_CHILD(CallRef, target)
622+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(CallRef, target)
614623
DELEGATE_FIELD_CHILD_VECTOR(CallRef, operands)
615624
DELEGATE_FIELD_INT(CallRef, isReturn)
616625
DELEGATE_FIELD_CASE_END(CallRef)
@@ -637,31 +646,31 @@ DELEGATE_FIELD_CASE_END(StructNew)
637646

638647
DELEGATE_FIELD_CASE_START(StructGet)
639648
DELEGATE_FIELD_INT(StructGet, index)
640-
DELEGATE_FIELD_CHILD(StructGet, ref)
649+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(StructGet, ref)
641650
DELEGATE_FIELD_INT(StructGet, signed_)
642651
DELEGATE_FIELD_INT(StructGet, order)
643652
DELEGATE_FIELD_CASE_END(StructGet)
644653

645654
DELEGATE_FIELD_CASE_START(StructSet)
646655
DELEGATE_FIELD_INT(StructSet, index)
647656
DELEGATE_FIELD_CHILD(StructSet, value)
648-
DELEGATE_FIELD_CHILD(StructSet, ref)
657+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(StructSet, ref)
649658
DELEGATE_FIELD_INT(StructSet, order)
650659
DELEGATE_FIELD_CASE_END(StructSet)
651660

652661
DELEGATE_FIELD_CASE_START(StructRMW)
653662
DELEGATE_FIELD_INT(StructRMW, op)
654663
DELEGATE_FIELD_INT(StructRMW, index)
655664
DELEGATE_FIELD_CHILD(StructRMW, value)
656-
DELEGATE_FIELD_CHILD(StructRMW, ref)
665+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(StructRMW, ref)
657666
DELEGATE_FIELD_INT(StructRMW, order)
658667
DELEGATE_FIELD_CASE_END(StructRMW)
659668

660669
DELEGATE_FIELD_CASE_START(StructCmpxchg)
661670
DELEGATE_FIELD_INT(StructCmpxchg, index)
662671
DELEGATE_FIELD_CHILD(StructCmpxchg, replacement)
663672
DELEGATE_FIELD_CHILD(StructCmpxchg, expected)
664-
DELEGATE_FIELD_CHILD(StructCmpxchg, ref)
673+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(StructCmpxchg, ref)
665674
DELEGATE_FIELD_INT(StructCmpxchg, order)
666675
DELEGATE_FIELD_CASE_END(StructCmpxchg)
667676

@@ -688,14 +697,14 @@ DELEGATE_FIELD_CASE_END(ArrayNewFixed)
688697

689698
DELEGATE_FIELD_CASE_START(ArrayGet)
690699
DELEGATE_FIELD_CHILD(ArrayGet, index)
691-
DELEGATE_FIELD_CHILD(ArrayGet, ref)
700+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ArrayGet, ref)
692701
DELEGATE_FIELD_INT(ArrayGet, signed_)
693702
DELEGATE_FIELD_CASE_END(ArrayGet)
694703

695704
DELEGATE_FIELD_CASE_START(ArraySet)
696705
DELEGATE_FIELD_CHILD(ArraySet, value)
697706
DELEGATE_FIELD_CHILD(ArraySet, index)
698-
DELEGATE_FIELD_CHILD(ArraySet, ref)
707+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ArraySet, ref)
699708
DELEGATE_FIELD_CASE_END(ArraySet)
700709

701710
DELEGATE_FIELD_CASE_START(ArrayLen)
@@ -705,32 +714,32 @@ DELEGATE_FIELD_CASE_END(ArrayLen)
705714
DELEGATE_FIELD_CASE_START(ArrayCopy)
706715
DELEGATE_FIELD_CHILD(ArrayCopy, length)
707716
DELEGATE_FIELD_CHILD(ArrayCopy, srcIndex)
708-
DELEGATE_FIELD_CHILD(ArrayCopy, srcRef)
717+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ArrayCopy, srcRef)
709718
DELEGATE_FIELD_CHILD(ArrayCopy, destIndex)
710-
DELEGATE_FIELD_CHILD(ArrayCopy, destRef)
719+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ArrayCopy, destRef)
711720
DELEGATE_FIELD_CASE_END(ArrayCopy)
712721

713722
DELEGATE_FIELD_CASE_START(ArrayFill)
714723
DELEGATE_FIELD_CHILD(ArrayFill, size)
715724
DELEGATE_FIELD_CHILD(ArrayFill, value)
716725
DELEGATE_FIELD_CHILD(ArrayFill, index)
717-
DELEGATE_FIELD_CHILD(ArrayFill, ref)
726+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ArrayFill, ref)
718727
DELEGATE_FIELD_CASE_END(ArrayFill)
719728

720729
DELEGATE_FIELD_CASE_START(ArrayInitData)
721730
DELEGATE_FIELD_NAME_KIND(ArrayInitData, segment, ModuleItemKind::DataSegment)
722731
DELEGATE_FIELD_CHILD(ArrayInitData, size)
723732
DELEGATE_FIELD_CHILD(ArrayInitData, offset)
724733
DELEGATE_FIELD_CHILD(ArrayInitData, index)
725-
DELEGATE_FIELD_CHILD(ArrayInitData, ref)
734+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ArrayInitData, ref)
726735
DELEGATE_FIELD_CASE_END(ArrayInitData)
727736

728737
DELEGATE_FIELD_CASE_START(ArrayInitElem)
729738
DELEGATE_FIELD_NAME_KIND(ArrayInitElem, segment, ModuleItemKind::ElementSegment)
730739
DELEGATE_FIELD_CHILD(ArrayInitElem, size)
731740
DELEGATE_FIELD_CHILD(ArrayInitElem, offset)
732741
DELEGATE_FIELD_CHILD(ArrayInitElem, index)
733-
DELEGATE_FIELD_CHILD(ArrayInitElem, ref)
742+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ArrayInitElem, ref)
734743
DELEGATE_FIELD_CASE_END(ArrayInitElem)
735744

736745
DELEGATE_FIELD_CASE_START(RefAs)
@@ -788,7 +797,7 @@ DELEGATE_FIELD_CHILD(ContNew, func)
788797
DELEGATE_FIELD_CASE_END(ContNew)
789798

790799
DELEGATE_FIELD_CASE_START(ContBind)
791-
DELEGATE_FIELD_CHILD(ContBind, cont)
800+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ContBind, cont)
792801
DELEGATE_FIELD_CHILD_VECTOR(ContBind, operands)
793802
DELEGATE_FIELD_CASE_END(ContBind)
794803

@@ -799,23 +808,23 @@ DELEGATE_FIELD_CASE_END(Suspend)
799808

800809
DELEGATE_FIELD_CASE_START(Resume)
801810
DELEGATE_FIELD_TYPE_VECTOR(Resume, sentTypes)
802-
DELEGATE_FIELD_CHILD(Resume, cont)
811+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(Resume, cont)
803812
DELEGATE_FIELD_CHILD_VECTOR(Resume, operands)
804813
DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(Resume, handlerBlocks)
805814
DELEGATE_FIELD_NAME_KIND_VECTOR(Resume, handlerTags, ModuleItemKind::Tag)
806815
DELEGATE_FIELD_CASE_END(Resume)
807816

808817
DELEGATE_FIELD_CASE_START(ResumeThrow)
809818
DELEGATE_FIELD_TYPE_VECTOR(ResumeThrow, sentTypes)
810-
DELEGATE_FIELD_CHILD(ResumeThrow, cont)
819+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ResumeThrow, cont)
811820
DELEGATE_FIELD_CHILD_VECTOR(ResumeThrow, operands)
812821
DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(ResumeThrow, handlerBlocks)
813822
DELEGATE_FIELD_NAME_KIND_VECTOR(ResumeThrow, handlerTags, ModuleItemKind::Tag)
814823
DELEGATE_FIELD_NAME_KIND(ResumeThrow, tag, ModuleItemKind::Tag)
815824
DELEGATE_FIELD_CASE_END(ResumeThrow)
816825

817826
DELEGATE_FIELD_CASE_START(StackSwitch)
818-
DELEGATE_FIELD_CHILD(StackSwitch, cont)
827+
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(StackSwitch, cont)
819828
DELEGATE_FIELD_CHILD_VECTOR(StackSwitch, operands)
820829
DELEGATE_FIELD_NAME_KIND(StackSwitch, tag, ModuleItemKind::Tag)
821830
DELEGATE_FIELD_CASE_END(StackSwitch)
@@ -827,6 +836,7 @@ DELEGATE_FIELD_MAIN_END
827836
#undef DELEGATE_START
828837
#undef DELEGATE_END
829838
#undef DELEGATE_FIELD_CHILD
839+
#undef DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD
830840
#undef DELEGATE_FIELD_OPTIONAL_CHILD
831841
#undef DELEGATE_FIELD_CHILD_VECTOR
832842
#undef DELEGATE_FIELD_INT

0 commit comments

Comments
 (0)