Skip to content

Improve indirect call effects in GlobalEffects#8644

Open
stevenfontanella wants to merge 3 commits intomainfrom
indirect-effects-address
Open

Improve indirect call effects in GlobalEffects#8644
stevenfontanella wants to merge 3 commits intomainfrom
indirect-effects-address

Conversation

@stevenfontanella
Copy link
Copy Markdown
Member

@stevenfontanella stevenfontanella commented Apr 23, 2026

Part of #8615. We currently union the effects of all functions of a given type when computing the effects for indirect calls. Make this more precise by excluding effects of functions that never have their address taken.

Continued from #8628 which was accidentally merged.

@stevenfontanella stevenfontanella changed the title Indirect effects address Improve indirect call effects in GlobalEffects Apr 23, 2026
@stevenfontanella stevenfontanella marked this pull request as ready for review April 23, 2026 20:01
@stevenfontanella stevenfontanella requested a review from a team as a code owner April 23, 2026 20:01
Comment on lines +93 to +96
ElementUtils::iterAllElementFunctionNames(
&module, [&addressedFuncs, &module](Name func) {
addressedFuncs.insert(module.getFunction(func));
});
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.

No need to do this separately. Walking the module code will already walk all the element segments and find the RefFunc expressions inside them.

an indirect call and we don't need to include its effects in indirect calls.
*/
std::unordered_set<Function*> getAddressedFuncs(Module& module) {
struct AddressedFuncsWalker : PostWalker<AddressedFuncsWalker> {
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.

Might as well make this a WalkerPass so it can be run on all the functions in parallel. Then instead of walkModule below, you would use walkModuleCode. Alternatively you could use ModuleUtils::ParallelFunctionAnalysis + walkModuleCode.

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.

+1 on using ParallelFunctionAnalysis

Base automatically changed from indirect-effects-scc to main April 24, 2026 21:36
@stevenfontanella stevenfontanella force-pushed the indirect-effects-address branch from cafaa9b to dd80924 Compare April 24, 2026 22:10
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.

LGTM % some nits + Thomas's comments

;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $f (param $ref (ref $only-has-effects-in-not-addressable-function))
;; The type $has-effects-but-not-exported doesn't have an address because
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.

Suggested change
;; The type $has-effects-but-not-exported doesn't have an address because
;; The func $has-effects-but-not-exported doesn't have an address because

;; it's not exported and it's never the target of a ref.func.
;; We should be able to determine that $ref can only point to $nop.
;; TODO: Only aggregate effects from functions that are addressed.
;; So the call_ref has no potential targets and thus no effects.
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.

Suggested change
;; So the call_ref has no potential targets and thus no effects.
;; So the call_ref has no potential targets with effects.

It has a target, $nop (without effects), so this was slightly confusing.

}

// Type -> Type
// Do a DFS up the type heirarchy for all function implementations.
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.

Suggested change
// Do a DFS up the type hierarchy for all function implementations.

Just a drive-by typo fix

an indirect call and we don't need to include its effects in indirect calls.
*/
std::unordered_set<Function*> getAddressedFuncs(Module& module) {
struct AddressedFuncsWalker : PostWalker<AddressedFuncsWalker> {
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.

+1 on using ParallelFunctionAnalysis

statements in our IR, but we check separately for funcs that appear in
`ref.func`).
- It's exported, because it may flow back to us as a reference.
- It's imported, which implies it is `elem declare`d.
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.

Maybe it's only me but 'it is elem declared' sounds a little confusing (because it is not, even though I get what you mean). How about just saying imported functions can be passed a reference (as you did with the exported functions)?

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