-
Notifications
You must be signed in to change notification settings - Fork 18.6k
Description
Proposal Details
Currently, when analyzing an assignment statement of the form *X = Y, the compiler typically treats the left-hand side as a heap hole, for example:
package main
func indirectStore () {
var c , d int // c should not escape
var pc* int = &c
var pd* int = &d
var ppd** int = &pd
*ppd = pc
}
func main() {
indirectStore();
}
In this code, *ppd is interpreted as a heap hole. Since pc (which stores address of c) flows into *ppd, the analysis concludes that pc must outlive c, which causes c to be placed on the heap. However, in reality, there is no need for c to escape at all.
If the reassign oracle proves that a dereferenced variable is written only once within a function, then the original source value can be propagated directly to that dereferenced target. In the example above, *ppd can only refer to the variable pd, so we can safely add a value-flow edge from pc to pd as a consequence. This may slightly boost the performance, possibly significantly for some applications, since this approach reduces heap-moved objects. Additionally, it can be integrated into the same escape analysis phase.
So the above example code will behave similar to this code in terms of escape analysis:
package main
func indirectStore () {
var c , d int // c should not escape
var pc* int = &c
var pd* int = &d
pd = pc
}
func main() {
indirectStore();
}
Initial Thought
Inside src/compile/internal/escape/assign.go where an addressable expression is evaluated:
func (e *escape) addr(n ir.Node) hole
The check can be added right here and a hole of de-referenced value can be generated and returned:
case ir.ODEREF:
n := n.(*ir.StarExpr)
// check if n.X is not reassigned, if not create a hole of the defining assignment of n.X and return it
e.mutate(n.X)
I haven’t examined how other language features might impact this solution, so if possible please let me know, if anything might break or the analysis might become unsound due to the proposed solution.
Thanks