From f50e933f639c24f3a5814980fb20e6f7e1435184 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 18 Oct 2023 20:37:48 +0200 Subject: 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. --- src/passes/Print.cpp | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'src/passes/Print.cpp') 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 { int controlFlowDepth = 0; std::vector heapTypes; + std::unordered_map 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 { 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(); -- cgit v1.2.3