From d32133af7791325afd30ba999c2e11bf5c82b6f6 Mon Sep 17 00:00:00 2001 From: David Chase Date: Wed, 31 Jul 2024 09:55:14 -0400 Subject: [PATCH] cmd/compile: fix order of map iteration in deadlocals This makes builds reproducible again. Fixes #68672 Updates #65158 Change-Id: I260180f52e992c702ab89050deb6484087ae265f Reviewed-on: https://go-review.googlesource.com/c/go/+/602075 LUCI-TryBot-Result: Go LUCI Auto-Submit: Cuong Manh Le Reviewed-by: Cuong Manh Le Reviewed-by: Than McIntosh --- src/cmd/compile/internal/deadlocals/deadlocals.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/cmd/compile/internal/deadlocals/deadlocals.go b/src/cmd/compile/internal/deadlocals/deadlocals.go index f40ca71970..8bc04b7ff0 100644 --- a/src/cmd/compile/internal/deadlocals/deadlocals.go +++ b/src/cmd/compile/internal/deadlocals/deadlocals.go @@ -30,7 +30,8 @@ func Funcs(fns []*ir.Func) { v := newVisitor(fn) v.nodes(fn.Body) - for _, assigns := range v.defs { + for _, k := range v.defsKeys { + assigns := v.defs[k] for _, as := range assigns { // Kludge for "missing func info" linker panic. // See also closureInitLSym in inline/inl.go. @@ -51,7 +52,8 @@ type visitor struct { curfn *ir.Func // defs[name] contains assignments that can be discarded if name can be discarded. // if defs[name] is defined nil, then name is actually used. - defs map[*ir.Name][]assign + defs map[*ir.Name][]assign + defsKeys []*ir.Name // insertion order of keys, for reproducible iteration (and builds) doNode func(ir.Node) bool } @@ -96,9 +98,11 @@ func (v *visitor) node(n ir.Node) { n = n.Canonical() if isLocal(n, false) { // Force any lazy definitions. - s := v.defs[n] + s, ok := v.defs[n] + if !ok { + v.defsKeys = append(v.defsKeys, n) + } v.defs[n] = nil - for _, as := range s { // do the visit that was skipped in v.assign when as was appended to v.defs[n] v.node(*as.rhs) @@ -161,6 +165,9 @@ func (v *visitor) assign(pos src.XPos, lhs, rhs *ir.Node, blankIsNotUse bool) { if isLocal(name, blankIsNotUse) && !hasEffects(*rhs) { if s, ok := v.defs[name]; !ok || s != nil { // !ok || s != nil is FALSE if previously "v.defs[name] = nil" -- that marks a use. + if !ok { + v.defsKeys = append(v.defsKeys, name) + } v.defs[name] = append(s, assign{pos, lhs, rhs}) return // don't visit rhs unless that node ends up live, later. }