diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index db37b20e66d..9a2ad2bd352 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -408,11 +408,6 @@ Type GlobalTypeRewriter::getTempTupleType(Tuple tuple) { namespace TypeUpdating { -bool canHandleAsLocal(Type type) { - // TODO: Inline this into its callers. - return type.isConcrete(); -} - void handleNonDefaultableLocals(Function* func, Module& wasm) { if (!wasm.features.hasReferenceTypes()) { // No references, so no non-nullable ones at all. diff --git a/src/ir/type-updating.h b/src/ir/type-updating.h index d9ee174ce7c..52a3e09027f 100644 --- a/src/ir/type-updating.h +++ b/src/ir/type-updating.h @@ -556,10 +556,6 @@ class TypeMapper : public GlobalTypeRewriter { namespace TypeUpdating { -// Checks whether a type is valid as a local, or whether -// handleNonDefaultableLocals() can handle it if not. -bool canHandleAsLocal(Type type); - // Finds non-nullable locals, which are currently not supported, and handles // them. Atm this turns them into nullable ones, and adds ref.as_non_null on // their uses (which keeps the type of the users identical). diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index 7224f25168b..00bd1ad2cf2 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -1534,12 +1534,10 @@ struct Heap2Local { // constant indexes, so they are effectively structs, and turning them into // such allows uniform handling later. for (auto* allocation : finder.arrayNews) { - // The point of this optimization is to replace heap allocations with - // locals, so we must be able to place the data in locals. - if (!canHandleAsLocals(allocation->type)) { + if (allocation->type == Type::unreachable) { + // Leave this for DCE. continue; } - EscapeAnalyzer analyzer( localGraph, parents, branchTargets, passOptions, wasm); if (!analyzer.escapes(allocation)) { @@ -1554,11 +1552,10 @@ struct Heap2Local { // Next, process all structNews. for (auto* allocation : finder.structNews) { - // As above, we must be able to use locals for this data. - if (!canHandleAsLocals(allocation->type)) { + if (allocation->type == Type::unreachable) { + // Leave this for DCE. continue; } - // Check for escaping, noting relevant information as we go. If this does // not escape, optimize it into locals. EscapeAnalyzer analyzer( @@ -1576,30 +1573,6 @@ struct Heap2Local { EHUtils::handleBlockNestedPops(func, wasm); } } - - bool canHandleAsLocal(const Field& field) { - return TypeUpdating::canHandleAsLocal(field.type); - } - - bool canHandleAsLocals(Type type) { - if (type == Type::unreachable) { - return false; - } - - auto heapType = type.getHeapType(); - if (heapType.isStruct()) { - auto& fields = heapType.getStruct().fields; - for (auto field : fields) { - if (!canHandleAsLocal(field)) { - return false; - } - } - return true; - } - - assert(heapType.isArray()); - return canHandleAsLocal(heapType.getArray().element); - } }; struct Heap2LocalPass : public WalkerPass> { diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index fac71163c1c..ff5cac479b0 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -186,17 +186,6 @@ struct FunctionInfo { } }; -static bool canHandleParams(Function* func) { - // We cannot inline a function if we cannot handle placing its params in a - // locals, as all params become locals. - for (auto param : func->getParams()) { - if (!TypeUpdating::canHandleAsLocal(param)) { - return false; - } - } - return true; -} - using NameInfoMap = std::unordered_map; struct FunctionInfoScanner @@ -246,10 +235,6 @@ struct FunctionInfoScanner void visitFunction(Function* curr) { auto& info = infos[curr->name]; - if (!canHandleParams(curr)) { - info.inliningMode = InliningMode::Uninlineable; - } - info.size = Measurer::measure(curr->body); // If the body is a simple instruction with roughly the same encoded size as diff --git a/src/passes/LocalCSE.cpp b/src/passes/LocalCSE.cpp index 73720bed430..a5221ed0079 100644 --- a/src/passes/LocalCSE.cpp +++ b/src/passes/LocalCSE.cpp @@ -354,8 +354,7 @@ struct Scanner // them is not cheap, so leave them for later, after we know if there // actually are any requests for reuse of this value (which is rare). if (!curr->type.isConcrete() || curr->is() || - curr->is() || Properties::isConstantExpression(curr) || - !TypeUpdating::canHandleAsLocal(curr->type)) { + curr->is() || Properties::isConstantExpression(curr)) { return false; } diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 770cf75c391..0d01aef29a7 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -1432,10 +1432,6 @@ struct OptimizeInstructions // The call_ref is not reached; leave this for DCE. return; } - if (!TypeUpdating::canHandleAsLocal(lastOperandType)) { - // We cannot create a local, so we must give up. - return; - } Index tempLocal = builder.addVar( getFunction(), TypeUpdating::getValidLocalType(lastOperandType, features)); diff --git a/src/passes/call-utils.h b/src/passes/call-utils.h index 10106a75658..51b8b3fa4ec 100644 --- a/src/passes/call-utils.h +++ b/src/passes/call-utils.h @@ -101,8 +101,7 @@ convertToDirectCalls(T* curr, // execute first, so we'll use locals for them all. First, see if any are // unreachable, and if so stop trying to optimize and leave this for DCE. for (auto* operand : operands) { - if (operand->type == Type::unreachable || - !TypeUpdating::canHandleAsLocal(operand->type)) { + if (operand->type == Type::unreachable) { return nullptr; } } diff --git a/src/passes/param-utils.cpp b/src/passes/param-utils.cpp index 0b7aee94344..0d46345a14a 100644 --- a/src/passes/param-utils.cpp +++ b/src/passes/param-utils.cpp @@ -131,15 +131,6 @@ RemovalOutcome removeParameter(const std::vector& funcs, } } - // The type must be valid for us to handle as a local (since we - // replace the parameter with a local). - // TODO: if there are no references at all, we can avoid creating a - // local - bool typeIsValid = TypeUpdating::canHandleAsLocal(first->getLocalType(index)); - if (!typeIsValid) { - return Failure; - } - // We can do it! // Remove the parameter from the function. We must add a new local diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 8ee053eb371..fd1f206bf93 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -1687,11 +1687,7 @@ Function* TranslateToFuzzReader::addFunction() { Index numVars = upToSquared(fuzzParams->MAX_VARS); for (Index i = 0; i < numVars; i++) { - auto type = getConcreteType(); - if (!TypeUpdating::canHandleAsLocal(type)) { - type = Type::i32; - } - func->vars.push_back(type); + func->vars.push_back(getConcreteType()); } // Generate the function creation context after we filled in locals, which it // will scan. @@ -3122,7 +3118,7 @@ Expression* TranslateToFuzzReader::makeLocalGet(Type type) { // the time), or emit a local.get of a new local, or emit a local.tee of a new // local. auto choice = upTo(3); - if (choice == 0 || !TypeUpdating::canHandleAsLocal(type)) { + if (choice == 0) { return makeConst(type); } // Otherwise, add a new local. If the type is not non-nullable then we may