Skip to content

[RemoveUnusedModuleElements] Handle global.get in element segments - #9371

Open
tlively wants to merge 5 commits into
mainfrom
remove-unused-elem-global-get
Open

tlively wants to merge 5 commits into
mainfrom
remove-unused-elem-global-get

Conversation

@tlively

@tlively tlively commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

Active element segments (and table initializers) can initialize table slots using global.get expressions referencing either module-defined immutable globals or imported globals. Previously, Analyzer::prepare() only checked for RefFunc items when populating FlatTableInfo::typeFuncs and FlatTableInfo::typeElems, so active element segments whose items were global.gets were omitted from typeElems, causing RemoveUnusedModuleElements to delete the element segment and its referenced global even when a reachable call_indirect could call through that table slot.

Fix this by tracing through module-defined immutable globals in notePossibleFunc so chains ending in RefFunc populate typeFuncs and typeElems directly, preserving called functions' bodies and maintaining type precision when a defined global has a broader declared type like funcref. For remaining function-typed items in active element segments whose concrete target is unknown (such as imported globals), propagateUnknownFuncElem pre-propagates the segment into typeElems for the item's heap type and its supertypes. Elements with inexact types are also recorded and keep their element segments alive when there are indirect calls to their subtypes.

Fixes #9366.

Active element segments (and table initializers) can initialize table slots using global.get expressions referencing either module-defined immutable globals or imported globals. Previously, Analyzer::prepare() only checked for RefFunc items when populating FlatTableInfo::typeFuncs and FlatTableInfo::typeElems, so active element segments whose items were global.gets were omitted from typeElems, causing RemoveUnusedModuleElements to delete the element segment and its referenced global even when a reachable call_indirect could call through that table slot.

Fix this by tracing through module-defined immutable globals in notePossibleFunc so chains ending in RefFunc populate typeFuncs and typeElems directly, preserving called functions' bodies and maintaining type precision when a defined global has a broader declared type like funcref. For remaining function-typed items in active element segments whose concrete target is unknown (such as imported globals), propagateUnknownFuncElem pre-propagates the segment into typeElems for the item's heap type, its supertypes, and (when inexact) its subtypes using a lazily cached subtypes() helper.

Fixes #9366.
@tlively
tlively requested a review from a team as a code owner November 9, 2026 03:17
@tlively
tlively requested review from brendandahl and removed request for a team November 9, 2026 03:17

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates the RemoveUnusedModuleElements pass to trace through module-defined immutable globals to find underlying constant expressions and introduces propagateUnknownFuncElem to handle unknown function elements. It also refactors SubTypes computation to be lazily computed and cached. The review feedback highlights a potential null pointer dereference and infinite loop risk when tracing through GlobalGet chains, and suggests optimizing subtype iterations by using iterSubTypes instead of methods that allocate and return vectors by value.

@tlively
tlively marked this pull request as draft November 10, 2026 01:05
Record inexact unknown function segment items in FlatTableInfo::inexactTypeElems and match them by walking call_indirect supertypes instead of eagerly expanding to all subtypes via SubTypes(*module). Also rename _subTypes/subtypes() to subTypes/getSubTypes(), clarify comments in notePossibleFunc, and add shared function global tests.
@tlively
tlively marked this pull request as ready for review November 10, 2026 05:34

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request enhances the RemoveUnusedModuleElements pass to trace through module-defined immutable globals and handle inexact unknown function items (such as imported globals) when identifying used element segments. It also introduces lazy subtype computation and adds comprehensive test cases. The review feedback identifies a potential null pointer dereference when resolving globals, which could lead to a segmentation fault, and suggests adding a null check.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 Google Antigravity Code Review

I have reviewed the changes in this Pull Request and left inline feedback.

This branch has not been deployed

No deployments
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.

RemoveUnusedModuleElements drops an active elem segment whose items are global.get, so call_indirect traps

1 participant