From 7087b8ac4c2eeab4fe52e498fa55a0c95ea89933 Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Fri, 30 Jun 2023 16:06:10 -0400 Subject: [PATCH] cmd/compile/internal/ir: export 'reassigned', handle OASOP Rename the ir-local function "reassigned" to "Reassigned" so that it can be used as part of inline heuristic analysis. Fix up the header comment along that way, which had some stale material. Add support for detecting reassignments via OASOP (as opposed to just simple assignments). Updates #61502. Change-Id: I50f40f81263c0d7f61f30fcf0258f0b0f93acdca Reviewed-on: https://go-review.googlesource.com/c/go/+/511560 Reviewed-by: Matthew Dempsky TryBot-Result: Gopher Robot Run-TryBot: Than McIntosh --- src/cmd/compile/internal/ir/expr.go | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/cmd/compile/internal/ir/expr.go b/src/cmd/compile/internal/ir/expr.go index 5355edc17691c..02b1733f04029 100644 --- a/src/cmd/compile/internal/ir/expr.go +++ b/src/cmd/compile/internal/ir/expr.go @@ -906,20 +906,20 @@ FindRHS: base.Fatalf("RHS is nil: %v", defn) } - if reassigned(n) { + if Reassigned(n) { 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 -// useful for -m output documenting the reason for inhibited optimizations. +// 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. // NB: global variables are always considered to be re-assigned. -// TODO: handle initial declaration not including an assignment and followed by a single assignment? -func reassigned(name *Name) bool { +// TODO: handle initial declaration not including an assignment and +// followed by a single assignment? +func Reassigned(name *Name) bool { if name.Op() != ONAME { base.Fatalf("reassigned %v", name) } @@ -934,7 +934,10 @@ func reassigned(name *Name) bool { // isName reports whether n is a reference to name. isName := func(x Node) bool { - n, ok := x.(*Name) + if x == nil { + return false + } + n, ok := OuterValue(x).(*Name) return ok && n.Canonical() == name } @@ -953,9 +956,14 @@ func reassigned(name *Name) bool { return true } } + case OASOP: + n := n.(*AssignOpStmt) + if isName(n.X) { + return true + } case OADDR: n := n.(*AddrExpr) - if isName(OuterValue(n.X)) { + if isName(n.X) { return true } case ORANGE: