Skip to content

[wasm-split] Do not split out the start function#8711

Open
kripken wants to merge 5 commits into
WebAssembly:mainfrom
kripken:split.start
Open

[wasm-split] Do not split out the start function#8711
kripken wants to merge 5 commits into
WebAssembly:mainfrom
kripken:split.start

Conversation

@kripken
Copy link
Copy Markdown
Member

@kripken kripken commented May 15, 2026

Like imports, automatically keep it in the primary module.

@kripken kripken requested a review from a team as a code owner May 15, 2026 18:29
@kripken kripken requested review from aheejin and removed request for a team May 15, 2026 18:29
Copy link
Copy Markdown
Member

@aheejin aheejin left a comment

Choose a reason for hiding this comment

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

Thanks! Can you handle it in multiSplitModule too?

@kripken
Copy link
Copy Markdown
Member Author

kripken commented May 15, 2026

Ok, I think I managed to do that. The first commit runs into a crash where the table is not present yet. I fixed that in the last commit by reordering operations: shareImportableItems needs the other code to run first so it can see which tables etc. need to be used.

The change to the existing test seems valid to me - now it is using the more accurate table definition from the primary module (which is larger).

However, I'm not very familiar with this code, so PTAL carefully!

indirectReferencesToSecondaryFunctions();
indirectCallsToSecondaryFunctions();
exportImportCalledPrimaryFunctions();
shareImportableItems();
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.

Why the order change?

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.

This is what I meant by this:

The first commit runs into a crash where the table is not present yet. I fixed that in the last commit by reordering operations: shareImportableItems needs the other code to run first so it can see which tables etc. need to be used.

That is the table needs to be created at the right time. I think...

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.

I don't see why that would be related to this change 🤔

Copy link
Copy Markdown
Member

@aheejin aheejin May 15, 2026

Choose a reason for hiding this comment

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

I don't either... Can you give an example?
That order change was the gist of #8688, so without breaking a lot of new assumptions, it is not easy to flip...

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.

For an example, run the multi-split test in this PR. (That is, take all of this PR but the part in question. The test crashes because it doesn't find the table. Reordering makes the table exist - but I have no high-level understanding of the flow here 😄 so maybe it is the wrong fix)

Comment on lines +435 to +437
// The start function must always be kept in the primary module.
if (func->imported() || !configSecondaryFuncs.contains(func->name) ||
segmentReferrers.contains(func->name)) {
segmentReferrers.contains(func->name) || func->name == primary.start) {
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 we just do something like

if (primary.start)
  primaryFuncs.insert(primary.start)

at the start of the function, rather than in this loop?

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.

We also need the if's else not to happen, though. That is, we need to add it in the primary and not in the secondary. If the loop body is not modified, it will add it to the second.

@kripken
Copy link
Copy Markdown
Member Author

kripken commented May 15, 2026

Looks like there are a bunch of tests that do not use the auto-updater, so I will need to update them manually. I did one in the last commit. I'll wait on the others to see if this fix is even the right one.

@tlively
Copy link
Copy Markdown
Member

tlively commented May 15, 2026

The fix looks right to me, but changing the order of splitting steps shouldn't be necessary.

@aheejin
Copy link
Copy Markdown
Member

aheejin commented May 15, 2026

Looks like there are a bunch of tests that do not use the auto-updater, so I will need to update them manually.

I didn't use update_lit_checks.py in some tests because it doesn't work very well on split modules. For example, it somehow omits some module elements. But other module elements are still shown. Not sure what the exact rule is, but I guess update_lit_checks.py wasn't designed to match resulting module elements to existing module elements well when there are split modules.

And AI is fairly good at updating those expectations 😀 I often give prompts like "Don't change whether each test uses update_lit_checks.py or not, and update expectations for tests in test/lit/wasm-split"

But I also don't see why this PR should change existing tests' expectations, who don't have start function.

Comment on lines +299 to +305
if (function->name == wasm.start) {
if (!options.quiet) {
std::cerr << "warning: cannot split out start function " << func
<< "\n";
}
continue;
}
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't you do the same thing in multiSplitModule after this line?

assert(currFuncs);

Then we don't need to do anything in module-splitting.cpp.

Also while you're at it you can add this there too, to be consistent with splitModule:

if (!function) {
if (!options.quiet) {
std::cerr << "warning: function " << func << " does not exist\n";
}
continue;
}
if (function->imported()) {
if (!options.quiet) {
std::cerr << "warning: cannot split out imported function " << func
<< "\n";
}
continue;
}

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