summaryrefslogtreecommitdiff
path: root/src/passes/Directize.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-10-07 13:23:03 -0700
committerGitHub <noreply@github.com>2021-10-07 20:23:03 +0000
commitc2fa907f010b6418e5cbfc3c5baface3c0898062 (patch)
treef6bf35104ec6e7d68be00ffd317ac3cdcffb83e9 /src/passes/Directize.cpp
parent2dff27c086e8f2a9913096ebf3dc93e97051d85a (diff)
downloadbinaryen-c2fa907f010b6418e5cbfc3c5baface3c0898062.tar.gz
binaryen-c2fa907f010b6418e5cbfc3c5baface3c0898062.tar.bz2
binaryen-c2fa907f010b6418e5cbfc3c5baface3c0898062.zip
Directize: Do not optimize if a table has a table.set (#4218)
Followup to #4215
Diffstat (limited to 'src/passes/Directize.cpp')
-rw-r--r--src/passes/Directize.cpp57
1 files changed, 44 insertions, 13 deletions
diff --git a/src/passes/Directize.cpp b/src/passes/Directize.cpp
index 92953c47b..67d9e77a8 100644
--- a/src/passes/Directize.cpp
+++ b/src/passes/Directize.cpp
@@ -171,28 +171,59 @@ private:
}
};
-// TODO: handle table.get / table.set here as well
struct Directize : public Pass {
void run(PassRunner* runner, Module* module) override {
+ // Find which tables are valid to optimize on. They must not be imported nor
+ // exported (so the outside cannot modify them), and must have no sets in
+ // any part of the module.
+
+ // First, find which tables have sets.
+ using TablesWithSet = std::unordered_set<Name>;
+
+ ModuleUtils::ParallelFunctionAnalysis<TablesWithSet> analysis(
+ *module, [&](Function* func, TablesWithSet& tablesWithSet) {
+ if (func->imported()) {
+ return;
+ }
+ for (auto* set : FindAll<TableSet>(func->body).list) {
+ tablesWithSet.insert(set->table);
+ }
+ });
+
+ TablesWithSet tablesWithSet;
+ for (auto& kv : analysis.map) {
+ for (auto name : kv.second) {
+ tablesWithSet.insert(name);
+ }
+ }
+
std::unordered_map<Name, TableUtils::FlatTable> validTables;
for (auto& table : module->tables) {
- if (!table->imported()) {
- bool canOptimizeCallIndirect = true;
+ if (table->imported()) {
+ continue;
+ }
- for (auto& ex : module->exports) {
- if (ex->kind == ExternalKind::Table && ex->value == table->name) {
- canOptimizeCallIndirect = false;
- }
- }
+ if (tablesWithSet.count(table->name)) {
+ continue;
+ }
- if (canOptimizeCallIndirect) {
- TableUtils::FlatTable flatTable(*module, *table);
- if (flatTable.valid) {
- validTables.emplace(table->name, flatTable);
- }
+ bool canOptimizeCallIndirect = true;
+ for (auto& ex : module->exports) {
+ if (ex->kind == ExternalKind::Table && ex->value == table->name) {
+ canOptimizeCallIndirect = false;
+ break;
}
}
+ if (!canOptimizeCallIndirect) {
+ continue;
+ }
+
+ // All conditions are valid, this is optimizable.
+ TableUtils::FlatTable flatTable(*module, *table);
+ if (flatTable.valid) {
+ validTables.emplace(table->name, flatTable);
+ }
}
// Without typed function references, all we can do is optimize table