Skip to content

[NFC] Move and generalize parameter-removing logic from DeadArgumentElimination#4544

Merged
kripken merged 14 commits into
mainfrom
gendae
Mar 24, 2022
Merged

[NFC] Move and generalize parameter-removing logic from DeadArgumentElimination#4544
kripken merged 14 commits into
mainfrom
gendae

Conversation

@kripken

@kripken kripken commented Mar 23, 2022

Copy link
Copy Markdown
Member

In preparation for removing dead arguments from all functions sharing a heap
type (which seems useful for j2wasm output), first this PR refactors that code
so it is reusable. This moves the code out of the pass into FunctionUtils, and
also generalizes it slightly by

  • supporting a set of functions and not just a single one, and
  • receiving a list of call_refs and not just calls

(no other changes to anything).

@kripken kripken requested review from aheejin and tlively March 23, 2022 17:25

@tlively tlively left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you move the function definitions into a .cpp file?

Comment thread src/ir/function-utils.h Outdated
// use cases are either to send a single function, or to send a set of functions
// that all have the same heap type (and so if they all do not use some
// parameter, it can be removed from them all).
inline bool removeParameter(const std::vector<Function*> funcs,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There are an awful lot of preconditions that have to be met to use this function correctly. I wonder if there is some more encapsulated abstraction that would work as well.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Maybe the comment isn't clear enough - I think it's not that complex? Or maybe I don't understand your concern.

Another way to phrase the comment might be: This function assumes you have already checked for "logical" correctness. It then simply removes the parameter, and if you made a mistake then you would be breaking the wasm. The function does check for "hard constraints" and returns false if it hits them, such constraints are things that basically would make the wasm not validate if applied, or otherwise be obviously wrong.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The preconditions:

  1. All calls and call_refs must be passed in.
  2. Removing the parameter should not change semantics.
  3. All functions must have the same signature.

I guess this isn't as bad as I initially thought, but this is more preconditions than I would expect from a general-purpose utility that's supposed to be useful in many potential situations. I guess it's more of a special-purpose utility that we only expect to ever call in a couple places.

Why can't we collapse the call sites into a single DAE optimization? It seems unfortunate to have such similar optimizations that share so much code but are still separate.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks, I see what you mean better now.

I think this is somewhat specialized and not fully general purpose, yes. But it is a way to avoid duplication between the existing DAE which optimizes single functions, and a future signature-pruning pass which does the same logical operation but on entire heap types at once. With this shared code split out, that new pass will be very simple.

We could in principle put all that code into a single file, DAE.cpp, and then these methods would go in there. Then it would be obvious it's not truly general purpose. I'd still prefer to have a new file SignaturePruning.cpp, however, just to keep that pass nice and separate and simple.

One option that might achieve both goals is to put this code in a separate file, but not in a "general" place like ir/function-utils.h? It could perhaps be in a file remove-parameters.cpp which would live alongside DAE.cpp and SignaturePruning.cpp?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

remove-parameters.cpp sounds good to me!

@kripken

kripken commented Mar 23, 2022

Copy link
Copy Markdown
Member Author

Good idea to split it out to a cpp file, done. These don't need to be inlined so there is no speed downside here.

@tlively tlively left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM with the code living in a more specialized location.

@kripken

kripken commented Mar 23, 2022

Copy link
Copy Markdown
Member Author

I named it passes/param-utils as it also has the code to check if a param is used, and not just remove them. I also added a comment about how tied it is to the opt passes that use it.

Comment on lines +133 to +135
for (auto* call : callRefs) {
call->operands.erase(call->operands.begin() + index);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This doesn't seem to update call_refs' target types. Is that OK?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ah, good point. Yes, this is intentional (the caller is expected to update types in all the places, its easier if a single place does it), but it should be documented. I'll open a PR.

kripken added a commit that referenced this pull request Mar 25, 2022
…imination (#4547)

Similar to #4544, this moves the code to a utility function, and also
slightly generalizes it to support a list of functions (and not just 1)
and also a list of call_refs (and not just calls).
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.

3 participants