Skip to content

DeadArgumentElimination/SignaturePruning: Prune params even if called with effects #6395

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 40 commits into from
Mar 18, 2024

Conversation

kripken
Copy link
Member

@kripken kripken commented Mar 13, 2024

Before this PR, when we saw a param was unused we sometimes could not remove it.
For example, if there was one call like this:

(call $target
  (call $other)
)

That nested call has effects, so we can't just remove it from the outer call - we'd need to
move it first. That motion was hard to integrate which was why it was left out, but it
turns out that is sometimes very important. E.g. in Java it is common to have such calls
that send the this parameter as the result of another call; not being able to remove such
params meant we kept those nested calls alive, creating empty structs just to have
something to send there.

To fix this, this builds on top of #6394 which makes it easier to move all children out of
a parent, leaving only nested things that can be easily moved around and removed. In
more detail, DeadArgumentElimination/SignaturePruning track whether we run into effects that
prevent removing a field. If we do, then we queue an operation to move the children
out, which we do using a new utility ParamUtils::localizeCallsTo. The pass then does
another iteration after that operation.

Alternatively we could try to move things around immediately, but that is quite hard:
those passes already track a lot of state. It is simpler to do the fixup in an entirely
separate utility. That does come at the cost of the utility doing another pass on the
module and the pass itself running another iteration, but this situation is not the most
common.

@kripken kripken requested a review from tlively March 14, 2024 21:32
@kripken
Copy link
Member Author

kripken commented Mar 14, 2024

Rebased after the other PR landed.

Comment on lines +85 to +87
if (operand->type == Type::unreachable) {
return Failure;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need the checks for call->isReturn anymore?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, the new logic for handling unreachable is simpler and handles it in a more general way.

;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $target
;; CHECK-NEXT: (local.get $0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In principle we should be able to eliminate this parameter as well, since it is not used for anything except supplying itself. (i.e. the fixed point we found is not the smallest fixed point)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, yeah, I think we don't try to handle such recursive cases. I wonder if we're missing out because of that...

@kripken kripken merged commit d8086c6 into WebAssembly:main Mar 18, 2024
@kripken kripken deleted the param.utils.origins.2 branch March 18, 2024 21:18
@gkdn gkdn mentioned this pull request Aug 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants