-
Notifications
You must be signed in to change notification settings - Fork 861
[wasm-split] Support Table::init #8818
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -729,29 +729,6 @@ void ModuleSplitter::shareImportableItems() { | |
| } | ||
|
|
||
| NameCollector collector(used); | ||
| // 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 | ||
| // appearing in their initializers will all be marked as used in the primary | ||
| // module, which is not what we want. | ||
| // | ||
| // For example, we have (global $a i32 (global.get $b)). Because $a is at | ||
| // this point still in the primary module, $b will be marked as "used" in | ||
| // the primary module. But $a can be moved to a secondary module later if it | ||
| // is used exclusively by that module. Then $b can be also moved, in case it | ||
| // doesn't have other uses. But if it is marked as "used" in the primary | ||
| // module, it can't. | ||
| walkSegments(collector, &module); | ||
| for (auto& segment : module.dataSegments) { | ||
| if (segment->isActive()) { | ||
| used.memories.insert(segment->memory); | ||
| } | ||
| } | ||
| for (auto& segment : module.elementSegments) { | ||
| if (segment->isActive()) { | ||
| used.tables.insert(segment->table); | ||
| } | ||
| } | ||
|
|
||
| // If primary module has exports, they are "used" in it. Secondary modules | ||
| // don't have exports, so this only applies to the primary module. | ||
|
|
@@ -785,6 +762,37 @@ void ModuleSplitter::shareImportableItems() { | |
| } | ||
| } | ||
|
|
||
| // 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 | ||
| // appearing in their initializers will all be marked as used in the primary | ||
| // module, which is not what we want. | ||
| // | ||
| // For example, we have (global $a i32 (global.get $b)). Because $a is at | ||
| // this point still in the primary module, $b will be marked as "used" in | ||
| // the primary module. But $a can be moved to a secondary module later if it | ||
| // is used exclusively by that module. Then $b can be also moved, in case it | ||
| // doesn't have other uses. But if it is marked as "used" in the primary | ||
| // module, it can't. | ||
| walkSegments(collector, &module); | ||
| for (auto& segment : module.dataSegments) { | ||
| if (segment->isActive()) { | ||
| used.memories.insert(segment->memory); | ||
| } | ||
| } | ||
| for (auto& segment : module.elementSegments) { | ||
| if (segment->isActive()) { | ||
| used.tables.insert(segment->table); | ||
| } | ||
| } | ||
| for (auto name : used.tables) { | ||
| if (auto* table = primary.getTableOrNull(name)) { | ||
| if (table->init) { | ||
| collector.walk(table->init); | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+788
to
+794
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth adding a TODO about not walking table initializers here just like we don't walk global initializers? Then we could let tables be moved to secondary modules and if their initializers are the only uses of globals, we could move those globals as well.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we don't walk table initializers assuming they are all used in the primary. We walk the expressions on the current |
||
|
|
||
| // Compute the transitive closure of globals referenced in other globals' | ||
| // initializers. Since globals can reference other globals, we must ensure | ||
| // that if a global is used in a module, all its dependencies are also | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part was just moved, because I felt this was tidier