summaryrefslogtreecommitdiff
path: root/src/passes/DeadArgumentElimination.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/DeadArgumentElimination.cpp')
-rw-r--r--src/passes/DeadArgumentElimination.cpp92
1 files changed, 2 insertions, 90 deletions
diff --git a/src/passes/DeadArgumentElimination.cpp b/src/passes/DeadArgumentElimination.cpp
index d7b4d7db2..e997c591f 100644
--- a/src/passes/DeadArgumentElimination.cpp
+++ b/src/passes/DeadArgumentElimination.cpp
@@ -589,98 +589,10 @@ private:
}
// We can do this!
+ TypeUpdating::updateParamTypes(func, newParamTypes, *module);
- // Before making this update, we must be careful if the param was "reused",
- // specifically, if it is assigned a less-specific type in the body then
- // we'd get a validation error when we refine it. To handle that, if a less-
- // specific type is assigned simply switch to a new local, that is, we can
- // do a fixup like this:
- //
- // function foo(x : oldType) {
- // ..
- // x = (oldType)val;
- //
- // =>
- //
- // function foo(x : newType) {
- // var x_oldType = x; // assign the param immediately to a fixup var
- // ..
- // x_oldType = (oldType)val; // fixup var is used throughout the body
- //
- // Later optimization passes may be able to remove the extra var, and can
- // take advantage of the refined argument type while doing so.
-
- // A map of params that need a fixup to the new fixup var used for it.
- std::unordered_map<Index, Index> paramFixups;
-
- FindAll<LocalSet> sets(func->body);
-
- for (auto* set : sets.list) {
- auto index = set->index;
- if (func->isParam(index) && !paramFixups.count(index) &&
- !Type::isSubType(set->value->type, newParamTypes[index])) {
- paramFixups[index] = Builder::addVar(func, func->getLocalType(index));
- }
- }
-
- FindAll<LocalGet> gets(func->body);
-
- // Apply the fixups we identified that we need.
- if (!paramFixups.empty()) {
- // Write the params immediately to the fixups.
- Builder builder(*module);
- std::vector<Expression*> contents;
- for (Index index = 0; index < func->getNumParams(); index++) {
- auto iter = paramFixups.find(index);
- if (iter != paramFixups.end()) {
- auto fixup = iter->second;
- contents.push_back(builder.makeLocalSet(
- fixup, builder.makeLocalGet(index, newParamTypes[index])));
- }
- }
- contents.push_back(func->body);
- func->body = builder.makeBlock(contents);
-
- // Update gets and sets using the param to use the fixup.
- for (auto* get : gets.list) {
- auto iter = paramFixups.find(get->index);
- if (iter != paramFixups.end()) {
- get->index = iter->second;
- }
- }
- for (auto* set : sets.list) {
- auto iter = paramFixups.find(set->index);
- if (iter != paramFixups.end()) {
- set->index = iter->second;
- }
- }
- }
-
- // Now that fixups are done, we can apply the new types.
+ // Also update the function's type.
func->setParams(newParams);
-
- // Update local.get/local.tee operations that use the modified param type.
- for (auto* get : gets.list) {
- auto index = get->index;
- if (func->isParam(index)) {
- get->type = func->getLocalType(index);
- }
- }
- for (auto* set : sets.list) {
- auto index = set->index;
- if (func->isParam(index) && set->isTee()) {
- set->type = func->getLocalType(index);
- set->finalize();
- }
- }
-
- // Propagate the new get and set types outwards.
- ReFinalize().walkFunctionInModule(func, module);
-
- if (!paramFixups.empty()) {
- // We have added locals, and must handle non-nullability of them.
- TypeUpdating::handleNonDefaultableLocals(func, *module);
- }
}
// See if the types returned from a function allow us to define a more refined