diff options
author | Thomas Lively <tlively@google.com> | 2023-10-18 20:37:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-18 18:37:48 +0000 |
commit | f50e933f639c24f3a5814980fb20e6f7e1435184 (patch) | |
tree | c118bfbfbb54a5c0e1879af650131503ad59bd97 /src/passes/Print.cpp | |
parent | 89c02aad305474aea1d413e110aadd68278a13d6 (diff) | |
download | binaryen-f50e933f639c24f3a5814980fb20e6f7e1435184.tar.gz binaryen-f50e933f639c24f3a5814980fb20e6f7e1435184.tar.bz2 binaryen-f50e933f639c24f3a5814980fb20e6f7e1435184.zip |
Reuse existing function types for blocks (#6022)
Type annotations on multivalue blocks (and loops, ifs, and trys) are type
indices that refer to function types in the type section. For these type
annotations, the identities of the function types does not matter. As long as
the referenced type has the correct parameters and results, it will be valid to
use.
Previously, when collecting module types, we always used the "default" function
type for multivalue control flow, i.e. we used a final function type with no
supertypes in a singleton rec group. However, in cases where the program already
contains another function type with the expected signature, using the default
type is unnecessary and bloats the type section.
Update the type collecting code to reuse existing function types for multivalue
control flow where possible rather than unconditionally adding the default
function type. Similarly, update the binary writer to use the first heap type
with the required signature when emitting annotations on multivalue control flow
structures. To make this all testable, update the printer to print the type
annotations as well, rather than just the result types. Since the parser was not
able to parse those newly emitted type annotations, update the parser as well.
Diffstat (limited to 'src/passes/Print.cpp')
-rw-r--r-- | src/passes/Print.cpp | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index edbb136a3..51d261126 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -169,6 +169,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { int controlFlowDepth = 0; std::vector<HeapType> heapTypes; + std::unordered_map<Signature, HeapType> signatureTypes; // Track the print indent so that we can see when it changes. That affects how // we print debug annotations. In particular, we don't want to print repeated @@ -242,6 +243,22 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { return printPrefixedTypes("param", type); } + std::ostream& printBlockType(Signature sig) { + assert(sig.params == Type::none); + if (sig.results == Type::none) { + return o; + } + if (sig.results.isTuple()) { + if (auto it = signatureTypes.find(sig); it != signatureTypes.end()) { + o << "(type "; + printHeapType(it->second); + o << ") "; + } + } + printResultType(sig.results); + return o; + } + void printDebugLocation(const Function::DebugLocation& location); void printDebugLocation(Expression* curr); @@ -370,6 +387,10 @@ struct PrintExpressionContents return parent.printParamType(type); } + std::ostream& printBlockType(Signature sig) { + return parent.printBlockType(sig); + } + void visitBlock(Block* curr) { printMedium(o, "block"); if (curr->name.is()) { @@ -378,14 +399,14 @@ struct PrintExpressionContents } if (curr->type.isConcrete()) { o << ' '; - printResultType(curr->type); + printBlockType(Signature(Type::none, curr->type)); } } void visitIf(If* curr) { printMedium(o, "if"); if (curr->type.isConcrete()) { o << ' '; - printResultType(curr->type); + printBlockType(Signature(Type::none, curr->type)); } } void visitLoop(Loop* curr) { @@ -396,7 +417,7 @@ struct PrintExpressionContents } if (curr->type.isConcrete()) { o << ' '; - printResultType(curr->type); + printBlockType(Signature(Type::none, curr->type)); } } void visitBreak(Break* curr) { @@ -1937,7 +1958,7 @@ struct PrintExpressionContents } if (curr->type.isConcrete()) { o << ' '; - printResultType(curr->type); + printBlockType(Signature(Type::none, curr->type)); } } void visitThrow(Throw* curr) { @@ -2369,8 +2390,14 @@ void PrintSExpression::setModule(Module* module) { currModule = module; if (module) { heapTypes = ModuleUtils::getOptimizedIndexedHeapTypes(*module).types; + for (auto type : heapTypes) { + if (type.isSignature()) { + signatureTypes.insert({type.getSignature(), type}); + } + } } else { heapTypes = {}; + signatureTypes = {}; } // Reset the type printer for this module's types (or absence thereof). typePrinter.~TypePrinter(); |