[wasm-split] Take functions out of shareImportableItems (NFC) (#8829)
This takes `getUsedNames`, which got blown out of proportion, out of
`shareImportableItems` and renames it to `scanModule`, and put it in a
new function `computeUsedNames`. This also takes some routines out of
`scanModule` and put it in `computeUsedNames`.
The rationale is twofold:
- `shareImportableItems` is too blown up and not easy to read.
- Before I tried to do all things necessary to figure out where each
module itesm is used within `getUsedNames` in order to make other things
tidier, but this is just untenable going forward.
diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp
index 1abc1ab..3e9d5d1 100644
--- a/src/ir/module-splitting.cpp
+++ b/src/ir/module-splitting.cpp
@@ -360,6 +360,16 @@
ExternalKind kind);
Name getTrampoline(Name funcName);
+ struct UsedNames {
+ std::unordered_set<Name> globals;
+ std::unordered_set<Name> memories;
+ std::unordered_set<Name> tables;
+ std::unordered_set<Name> tags;
+ };
+ using PrimarySecondaryUsedNames =
+ std::pair<UsedNames, std::vector<UsedNames>>;
+ PrimarySecondaryUsedNames computeUsedNames();
+
// Main splitting steps
void classifyFunctions();
void moveSecondaryFunctions();
@@ -638,15 +648,7 @@
}
}
-void ModuleSplitter::shareImportableItems() {
-
- struct UsedNames {
- std::unordered_set<Name> globals;
- std::unordered_set<Name> memories;
- std::unordered_set<Name> tables;
- std::unordered_set<Name> tags;
- };
-
+ModuleSplitter::PrimarySecondaryUsedNames ModuleSplitter::computeUsedNames() {
auto walkSegments = [](auto& walker, Module* module) {
walker.setModule(module);
for (auto& curr : module->elementSegments) {
@@ -712,7 +714,7 @@
};
// Given a module, collect names used in the module
- auto getUsedNames = [&](Module& module) {
+ auto scanModule = [&](Module& module) {
UsedNames used;
ModuleUtils::ParallelFunctionAnalysis<UsedNames> nameCollector(
module, [&](Function* func, UsedNames& used) {
@@ -729,39 +731,6 @@
}
NameCollector collector(used);
-
- // If primary module has exports, they are "used" in it. Secondary modules
- // don't have exports, so this only applies to the primary module.
- for (auto& ex : module.exports) {
- switch (ex->kind) {
- case ExternalKind::Global:
- used.globals.insert(*ex->getInternalName());
- break;
- case ExternalKind::Memory:
- used.memories.insert(*ex->getInternalName());
- break;
- case ExternalKind::Table:
- used.tables.insert(*ex->getInternalName());
- break;
- case ExternalKind::Tag:
- used.tags.insert(*ex->getInternalName());
- break;
- default:
- break;
- }
- }
-
- // We need to assume the dispatch table and its base global are used in the
- // primary module, because we will create segments there later.
- if (&module == &primary) {
- if (tableManager.dispatchTable) {
- used.tables.insert(tableManager.dispatchTable->name);
- }
- if (tableManager.dispatchBase.global) {
- used.globals.insert(tableManager.dispatchBase.global);
- }
- }
-
// We shouldn't use collector.walkModuleCode here, because we don't want to
// walk global initializers. At this point, all globals are still in the
// primary module, so if we walk global initializers here, other globals
@@ -785,6 +754,7 @@
used.tables.insert(segment->table);
}
}
+
for (auto name : used.tables) {
if (auto* table = primary.getTableOrNull(name)) {
if (table->init) {
@@ -816,10 +786,40 @@
return used;
};
- UsedNames primaryUsed = getUsedNames(primary);
+ UsedNames primaryUsed = scanModule(primary);
std::vector<UsedNames> secondaryUsed;
for (auto& secondaryPtr : secondaries) {
- secondaryUsed.push_back(getUsedNames(*secondaryPtr));
+ secondaryUsed.push_back(scanModule(*secondaryPtr));
+ }
+
+ // If primary module has exports, they are "used" in it. Secondary modules
+ // don't have exports, so this only applies to the primary module.
+ for (auto& ex : primary.exports) {
+ switch (ex->kind) {
+ case ExternalKind::Global:
+ primaryUsed.globals.insert(*ex->getInternalName());
+ break;
+ case ExternalKind::Memory:
+ primaryUsed.memories.insert(*ex->getInternalName());
+ break;
+ case ExternalKind::Table:
+ primaryUsed.tables.insert(*ex->getInternalName());
+ break;
+ case ExternalKind::Tag:
+ primaryUsed.tags.insert(*ex->getInternalName());
+ break;
+ default:
+ break;
+ }
+ }
+
+ // We need to assume the dispatch table and its base global are used in the
+ // primary module, because we will create segments there later.
+ if (tableManager.dispatchTable) {
+ primaryUsed.tables.insert(tableManager.dispatchTable->name);
+ }
+ if (tableManager.dispatchBase.global) {
+ primaryUsed.globals.insert(tableManager.dispatchBase.global);
}
// If custom-descirptors is enabled, global and table initializers can trap.
@@ -842,6 +842,14 @@
}
}
+ return std::make_pair(primaryUsed, secondaryUsed);
+}
+
+void ModuleSplitter::shareImportableItems() {
+ auto usedNames = computeUsedNames();
+ auto& primaryUsed = usedNames.first;
+ auto& secondaryUsed = usedNames.second;
+
// Given a name and module item kind, returns the list of secondary modules
// using that name
auto getUsingSecondaries = [&](const Name& name, auto UsedNames::* field) {