mirror of
https://github.com/golang/go
synced 2024-11-22 14:34:45 -07:00
[dev.regabi] cmd/compile: make ir.StaticValue safer
ir.StaticValue currently relies on CaptureVars setting Addrtaken for variables that are assigned within nested function literals. We want to move that logic to escape analysis, but ir.StaticValue is used in inlining and devirtualization, which happen before escape analysis. The long-term solution here is to generalize escape analysis's precise reassignment tracking for use by other optimization passes, but for now we just generalize ir.StaticValue to not depend on Addrtaken anymore. Instead, it now also pays attention to OADDR nodes as well as recurses into OCLOSURE bodies. Passes toolstash -cmp. Change-Id: I6114e3277fb70b235f4423d2983d0433c881f79f Reviewed-on: https://go-review.googlesource.com/c/go/+/281540 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
parent
9aa950c407
commit
e09783cbc0
@ -771,7 +771,7 @@ func staticValue1(nn Node) Node {
|
||||
return nil
|
||||
}
|
||||
n := nn.(*Name)
|
||||
if n.Class != PAUTO || n.Addrtaken() {
|
||||
if n.Class != PAUTO {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -823,23 +823,51 @@ func reassigned(name *Name) bool {
|
||||
if name.Curfn == nil {
|
||||
return true
|
||||
}
|
||||
return Any(name.Curfn, func(n Node) bool {
|
||||
|
||||
// TODO(mdempsky): This is inefficient and becoming increasingly
|
||||
// unwieldy. Figure out a way to generalize escape analysis's
|
||||
// reassignment detection for use by inlining and devirtualization.
|
||||
|
||||
// isName reports whether n is a reference to name.
|
||||
isName := func(n Node) bool {
|
||||
if n, ok := n.(*Name); ok && n.Op() == ONAME {
|
||||
if n.IsClosureVar() && n.Defn != nil {
|
||||
n = n.Defn.(*Name)
|
||||
}
|
||||
return n == name
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var do func(n Node) bool
|
||||
do = func(n Node) bool {
|
||||
switch n.Op() {
|
||||
case OAS:
|
||||
n := n.(*AssignStmt)
|
||||
if n.X == name && n != name.Defn {
|
||||
if isName(n.X) && n != name.Defn {
|
||||
return true
|
||||
}
|
||||
case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV, OSELRECV2:
|
||||
n := n.(*AssignListStmt)
|
||||
for _, p := range n.Lhs {
|
||||
if p == name && n != name.Defn {
|
||||
if isName(p) && n != name.Defn {
|
||||
return true
|
||||
}
|
||||
}
|
||||
case OADDR:
|
||||
n := n.(*AddrExpr)
|
||||
if isName(OuterValue(n.X)) {
|
||||
return true
|
||||
}
|
||||
case OCLOSURE:
|
||||
n := n.(*ClosureExpr)
|
||||
if Any(n.Func, do) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
}
|
||||
return Any(name.Curfn, do)
|
||||
}
|
||||
|
||||
// IsIntrinsicCall reports whether the compiler back end will treat the call as an intrinsic operation.
|
||||
|
Loading…
Reference in New Issue
Block a user