diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2022-01-21 15:58:27 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-21 23:58:27 +0000 |
commit | 26d0df73150e0207e6ce6262214bba1453a740d7 (patch) | |
tree | 7dec9c4219e0a3a0284446bae8651781adae0b9a /src/passes/Print.cpp | |
parent | 830b18b34197ad791e7b0d5bd5f5bade2a704395 (diff) | |
download | binaryen-26d0df73150e0207e6ce6262214bba1453a740d7.tar.gz binaryen-26d0df73150e0207e6ce6262214bba1453a740d7.tar.bz2 binaryen-26d0df73150e0207e6ce6262214bba1453a740d7.zip |
Parse, create, and print isorecursive recursion groups (#4464)
In `--hybrid` isorecursive mode, associate each defined type with a recursion
group, represented as a `(rec ...)` wrapping the type definitions in the text
format. Parse that text format, create the rec groups using a new TypeBuilder
method, and print the rec groups in the printer.
The only semantic difference rec groups currently make is that if one type in a
rec group will be included in the output, all the types in that rec group will
be included. This is because changing a rec group in any way (for example by
removing a type) changes the identity of the types in that group in the
isorecursive type system. Notably, rec groups do not yet participate in
validation, so `--hybrid` is largely equivalent to `--nominal` for now.
Diffstat (limited to 'src/passes/Print.cpp')
-rw-r--r-- | src/passes/Print.cpp | 46 |
1 files changed, 39 insertions, 7 deletions
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 7bcf23b8e..5bdf84aba 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2582,7 +2582,10 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { void handleSignature(HeapType curr, Name name = Name()) { Signature sig = curr.getSignature(); - if (!name.is() && getTypeSystem() == TypeSystem::Nominal) { + bool hasSupertype = + !name.is() && (getTypeSystem() == TypeSystem::Nominal || + getTypeSystem() == TypeSystem::Isorecursive); + if (hasSupertype) { o << "(func_subtype"; } else { o << "(func"; @@ -2612,7 +2615,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { } o << ')'; } - if (!name.is() && getTypeSystem() == TypeSystem::Nominal) { + if (hasSupertype) { o << ' '; printSupertypeOr(curr, "func"); } @@ -2638,21 +2641,25 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { } } void handleArray(HeapType curr) { - if (getTypeSystem() == TypeSystem::Nominal) { + bool hasSupertype = getTypeSystem() == TypeSystem::Nominal || + getTypeSystem() == TypeSystem::Isorecursive; + if (hasSupertype) { o << "(array_subtype "; } else { o << "(array "; } handleFieldBody(curr.getArray().element); - if (getTypeSystem() == TypeSystem::Nominal) { + if (hasSupertype) { o << ' '; printSupertypeOr(curr, "data"); } o << ')'; } void handleStruct(HeapType curr) { + bool hasSupertype = getTypeSystem() == TypeSystem::Nominal || + getTypeSystem() == TypeSystem::Isorecursive; const auto& fields = curr.getStruct().fields; - if (getTypeSystem() == TypeSystem::Nominal) { + if (hasSupertype) { o << "(struct_subtype "; } else { o << "(struct "; @@ -2669,7 +2676,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { o << ')'; sep = " "; } - if (getTypeSystem() == TypeSystem::Nominal) { + if (hasSupertype) { o << ' '; printSupertypeOr(curr, "data"); } @@ -2779,7 +2786,8 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { o << '('; printMajor(o, "func "); printName(curr->name, o); - if (getTypeSystem() == TypeSystem::Nominal) { + if (getTypeSystem() == TypeSystem::Nominal || + getTypeSystem() == TypeSystem::Isorecursive) { o << " (type "; printHeapType(o, curr->type, currModule) << ')'; } @@ -3064,10 +3072,32 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { printName(curr->name, o); } incIndent(); + // Use the same type order as the binary output would even though there is // no code size benefit in the text format. auto indexedTypes = ModuleUtils::getOptimizedIndexedHeapTypes(*curr); + std::optional<RecGroup> currGroup; + bool nontrivialGroup = false; + auto finishGroup = [&]() { + if (nontrivialGroup) { + decIndent(); + o << maybeNewLine; + } + }; for (auto type : indexedTypes.types) { + RecGroup newGroup = type.getRecGroup(); + if (!currGroup || *currGroup != newGroup) { + if (currGroup) { + finishGroup(); + } + currGroup = newGroup; + nontrivialGroup = currGroup->size() > 1; + if (nontrivialGroup) { + doIndent(o, indent); + o << "(rec "; + incIndent(); + } + } doIndent(o, indent); o << '('; printMedium(o, "type") << ' '; @@ -3076,6 +3106,8 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { handleHeapType(type); o << ")" << maybeNewLine; } + finishGroup(); + ModuleUtils::iterImportedMemories( *curr, [&](Memory* memory) { visitMemory(memory); }); ModuleUtils::iterImportedTables(*curr, |