-
Notifications
You must be signed in to change notification settings - Fork 18k
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
cmd/compile: don't escape argument when all possible values of function pointer are known #73132
Comments
Related Issues
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.) |
I think that this is doable (at least for function locals), see my work at CL 652036, that change tracks concrete types of interfaces, but I think it could be extended to analyze funcs, and this result could then be feed into the escape analysis (for cases where devirtualization was unsuccessful), and thus escape analysis could then be aware of all possible concrete types of an interface and all possible functions that can be called. |
CC @golang/compiler |
I suspect many local func values could benefit from a sparse dataflow analysis that models the escape bits of each value of func type. An even more common and trivial case is that of a self-recursive local function (which requires the var trick): the dynamic call causes the current escape analysis to make very conservative judgments, even when the call could be made static with only local inferences, improving both the CALL instruction and the escape judgments. func f() {
var x int
var v func(x *int) // self-recursive function
v = func(x *int) {
v(x)
}
v(&x) // (apparently) dynamic call -> conservative "x escapes" judgment
v2(&x) // static call to self-recursive function -> no escape
}
func v2(x *int) {
v2(x)
} I think a good first step would be for the compiler to recognize the special case of |
Yep, i think that with mine approach described in #73132 (comment) that could be done entirely in the devirtualizer, unless there is some other edge-case that i am not aware of. For the implementation to be simple it will additionally require a nil check on the non-static func value (in your example |
The usual pattern is that v is assigned exactly once, before all uses, so it could (in effect) be turned from a variable into a function symbol. |
Yes. Currently there is only very limited dataflow analysis in the escape analysis, essentially only a few forms of "assigned only once". A more general solution is to do escape analysis in SSA, where the dataflow analysis follows naturally. That would need a good amount of work, though. It would probably not hard to recognize the |
Go version
go version go1.24.1 linux/amd64
Output of
go env
in your module/workspace:What did you do?
What did you see happen?
x
gets allocated on the heap because the compiler cannot tell that the call tofp
doesn't cause the argument to escape.What did you expect to see?
All possible values of
fp
are statically known and known not to cause the argument to escape. I would expect the escape information forbar1
andbar2
to be merged and maintained withfp
.This comes up when providing multiple assembly implementations of a function for the same overall CPU architecture, for example both SSE and AVX ones. The implementation has to be chosen dynamically and I would like to pull that out of any loops, hence the function pointer.
The text was updated successfully, but these errors were encountered: