mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: improve escape analysis of known calls
Escape analysis is currently very naive about identifying calls to known functions: it only recognizes direct calls to a declared function, or direct calls to a closure. This CL adds a new "staticValue" helper function that can trace back through local variables that were initialized and never reassigned based on a similar optimization already used by inlining. (And to be used by inlining in a followup CL.) Updates #41474. Change-Id: I8204fd3b1e150ab77a27f583985cf099a8572b2e Reviewed-on: https://go-review.googlesource.com/c/go/+/256458 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
cced777026
commit
c0417df156
3 changed files with 69 additions and 6 deletions
|
|
@ -751,6 +751,55 @@ func inlinableClosure(n *Node) *Node {
|
|||
return f
|
||||
}
|
||||
|
||||
func staticValue(n *Node) *Node {
|
||||
for {
|
||||
n1 := staticValue1(n)
|
||||
if n1 == nil {
|
||||
return n
|
||||
}
|
||||
n = n1
|
||||
}
|
||||
}
|
||||
|
||||
// staticValue1 implements a simple SSA-like optimization.
|
||||
func staticValue1(n *Node) *Node {
|
||||
if n.Op != ONAME || n.Class() != PAUTO || n.Name.Addrtaken() {
|
||||
return nil
|
||||
}
|
||||
|
||||
defn := n.Name.Defn
|
||||
if defn == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var rhs *Node
|
||||
FindRHS:
|
||||
switch defn.Op {
|
||||
case OAS:
|
||||
rhs = defn.Right
|
||||
case OAS2:
|
||||
for i, lhs := range defn.List.Slice() {
|
||||
if lhs == n {
|
||||
rhs = defn.Rlist.Index(i)
|
||||
break FindRHS
|
||||
}
|
||||
}
|
||||
Fatalf("%v missing from LHS of %v", n, defn)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
if rhs == nil {
|
||||
Fatalf("RHS is nil: %v", defn)
|
||||
}
|
||||
|
||||
unsafe, _ := reassigned(n)
|
||||
if unsafe {
|
||||
return nil
|
||||
}
|
||||
|
||||
return rhs
|
||||
}
|
||||
|
||||
// reassigned takes an ONAME node, walks the function in which it is defined, and returns a boolean
|
||||
// indicating whether the name has any assignments other than its declaration.
|
||||
// The second return value is the first such assignment encountered in the walk, if any. It is mostly
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue