Skip to content

cmd/compile: exploiting the capabilities of reassigned oracle to make escape analysis a little less conservative #76488

@ashu3103

Description

@ashu3103

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    ImplementationIssues describing a semantics-preserving change to the Go implementation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions