aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2022-09-22 14:09:21 -0700
committerKeith Randall <khr@golang.org>2022-09-27 20:09:33 +0000
commit6485e8f50334f4ff369984759c22fba327a5d064 (patch)
treecd0edbb2ffd3fc7bb8e1e93d1916c8deb489882f /src
parent92a94a702469e1e57662fa2a7e6b4dc3d7161bd1 (diff)
downloadgo-6485e8f50334f4ff369984759c22fba327a5d064.tar.xz
cmd/compile: use stricter rule for possible partial overlap
Partial overlaps can only happen for strict sub-pieces of larger arrays. That's a much stronger condition than the current optimization rules. Update #54467 Change-Id: I11e539b71099e50175f37ee78fddf69283f83ee5 Reviewed-on: https://go-review.googlesource.com/c/go/+/433056 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/ssagen/ssa.go28
1 files changed, 10 insertions, 18 deletions
diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go
index 88d43b9915..bafa385579 100644
--- a/src/cmd/compile/internal/ssagen/ssa.go
+++ b/src/cmd/compile/internal/ssagen/ssa.go
@@ -1588,18 +1588,16 @@ func (s *state) stmt(n ir.Node) {
}
// mayOverlap keeps track of whether the LHS and RHS might
- // refer to overlapping memory.
- mayOverlap := true
- if n.Y == nil {
- // Not a move at all, mayOverlap is not relevant.
- } else if n.Def {
- // A variable being defined cannot overlap anything else.
- mayOverlap = false
- } else if n.X.Op() == ir.ONAME && n.Y.Op() == ir.ONAME {
- // Two named things never overlap.
- // (Or they are identical, which we treat as nonoverlapping.)
- mayOverlap = false
- } else if n.Y.Op() == ir.ODEREF {
+ // refer to partially overlapping memory. Partial overlapping can
+ // only happen for arrays, see the comment in moveWhichMayOverlap.
+ //
+ // If both sides of the assignment are not dereferences, then partial
+ // overlap can't happen. Partial overlap can only occur only when the
+ // arrays referenced are strictly smaller parts of the same base array.
+ // If one side of the assignment is a full array, then partial overlap
+ // can't happen. (The arrays are either disjoint or identical.)
+ mayOverlap := n.X.Op() == ir.ODEREF && (n.Y != nil && n.Y.Op() == ir.ODEREF)
+ if n.Y != nil && n.Y.Op() == ir.ODEREF {
p := n.Y.(*ir.StarExpr).X
for p.Op() == ir.OCONVNOP {
p = p.(*ir.ConvExpr).X
@@ -1609,12 +1607,6 @@ func (s *state) stmt(n ir.Node) {
// That memory can't overlap with the memory being written.
mayOverlap = false
}
- } else if n.Y.Op() == ir.ORESULT || n.Y.Op() == ir.OCALLFUNC || n.Y.Op() == ir.OCALLINTER {
- // When copying values out of the return area of a call, we know
- // the source and destination don't overlap. Importantly, we must
- // set mayOverlap so we don't introduce a call to memmove while
- // we still have live data in the argument area.
- mayOverlap = false
}
// Evaluate RHS.