summaryrefslogtreecommitdiff
path: root/src/passes/SignaturePruning.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-03-28 14:57:48 -0700
committerGitHub <noreply@github.com>2022-03-28 21:57:48 +0000
commitdbb7047289d5bc7d12a4c7fb1982f153f5e0127a (patch)
tree0e66f6282bb80d8d2c911b00c0f9ccde0d9337a0 /src/passes/SignaturePruning.cpp
parent4643f26e113476ebb273ee4f69e89c61801c7c2f (diff)
downloadbinaryen-dbb7047289d5bc7d12a4c7fb1982f153f5e0127a.tar.gz
binaryen-dbb7047289d5bc7d12a4c7fb1982f153f5e0127a.tar.bz2
binaryen-dbb7047289d5bc7d12a4c7fb1982f153f5e0127a.zip
[Wasm GC] Signature Pruning: Remove params passed constant values (#4551)
This basically just adds a call to ParamUtils::applyConstantValues, however, we also need to be careful to not optimize in the presence of imports or exports, so this adds a boolean that indicates unoptimizability.
Diffstat (limited to 'src/passes/SignaturePruning.cpp')
-rw-r--r--src/passes/SignaturePruning.cpp47
1 files changed, 34 insertions, 13 deletions
diff --git a/src/passes/SignaturePruning.cpp b/src/passes/SignaturePruning.cpp
index d41c04d57..033333758 100644
--- a/src/passes/SignaturePruning.cpp
+++ b/src/passes/SignaturePruning.cpp
@@ -22,6 +22,10 @@
// looks at each heap type at a time, and if all functions with a heap type do
// not use a particular param, will remove the param.
//
+// Like in DAE, as part of pruning parameters this will find parameters that are
+// always sent the same constant value. We can then apply that value in the
+// function, making the parameter's value unused, which means we can prune it.
+//
#include "ir/find_all.h"
#include "ir/lubs.h"
@@ -65,20 +69,16 @@ struct SignaturePruning : public Pass {
std::unordered_set<Index> usedParams;
- void markUnoptimizable(Function* func) {
- // To prevent any optimization, mark all the params as if there were
- // used.
- for (Index i = 0; i < func->getNumParams(); i++) {
- usedParams.insert(i);
- }
- }
+ // If we set this to false, we may not attempt to perform any optimization
+ // whatsoever on this data.
+ bool optimizable = true;
};
ModuleUtils::ParallelFunctionAnalysis<Info> analysis(
*module, [&](Function* func, Info& info) {
if (func->imported()) {
// Imports cannot be modified.
- info.markUnoptimizable(func);
+ info.optimizable = false;
return;
}
@@ -116,6 +116,11 @@ struct SignaturePruning : public Pass {
for (auto index : info.usedParams) {
allUsedParams.insert(index);
}
+
+ if (!info.optimizable) {
+ allInfo[func->type].optimizable = false;
+ }
+
sigFuncs[func->type].push_back(func);
}
@@ -123,7 +128,7 @@ struct SignaturePruning : public Pass {
for (auto& exp : module->exports) {
if (exp->kind == ExternalKind::Function) {
auto* func = module->getFunction(exp->value);
- allInfo[func->type].markUnoptimizable(func);
+ allInfo[func->type].optimizable = false;
}
}
@@ -131,17 +136,33 @@ struct SignaturePruning : public Pass {
for (auto& [type, funcs] : sigFuncs) {
auto sig = type.getSignature();
auto& info = allInfo[type];
+ auto& usedParams = info.usedParams;
auto numParams = sig.params.size();
- if (info.usedParams.size() == numParams) {
+
+ if (!info.optimizable) {
+ continue;
+ }
+
+ // Apply constant indexes: find the parameters that are always sent a
+ // constant value, and apply that value in the function. That then makes
+ // the parameter unused (since the applied value makes us ignore the value
+ // arriving in the parameter).
+ auto optimizedIndexes = ParamUtils::applyConstantValues(
+ funcs, info.calls, info.callRefs, module);
+ for (auto i : optimizedIndexes) {
+ usedParams.erase(i);
+ }
+
+ if (usedParams.size() == numParams) {
// All parameters are used, give up on this one.
continue;
}
- // We found possible work! Find the specific params that are unused try to
- // prune them.
+ // We found possible work! Find the specific params that are unused & try
+ // to prune them.
SortedVector unusedParams;
for (Index i = 0; i < numParams; i++) {
- if (info.usedParams.count(i) == 0) {
+ if (usedParams.count(i) == 0) {
unusedParams.insert(i);
}
}