aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2021-09-16 13:55:45 -0400
committerCherry Mui <cherryyz@google.com>2021-09-17 23:21:29 +0000
commitf01721efb941edadc2e6a897e42919b0d68480e1 (patch)
tree9415c4b5d041916eb53118e013b1193147a2b651
parent163871feb177ca0d7c690052b4cdd17bd57fcc04 (diff)
downloadgo-f01721efb941edadc2e6a897e42919b0d68480e1.tar.gz
go-f01721efb941edadc2e6a897e42919b0d68480e1.zip
cmd/compile: remove self copies in tail-call wrappers
The previous CL re-enables tail calls for method wrappers. But with the changed IR and SSA representation, for stack arguments it generates self copies. This CL makes the compiler detect the self copies and remove them. Change-Id: I7252572a1a47834f28b6706e45906e2356408e02 Reviewed-on: https://go-review.googlesource.com/c/go/+/350349 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
-rw-r--r--src/cmd/compile/internal/ssa/expand_calls.go19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go
index 79434f33d3..a0f0e653aa 100644
--- a/src/cmd/compile/internal/ssa/expand_calls.go
+++ b/src/cmd/compile/internal/ssa/expand_calls.go
@@ -1098,6 +1098,17 @@ func (x *expandState) rewriteArgs(v *Value, firstArg int) {
if a.MemoryArg() != m0 {
x.f.Fatalf("Op...LECall and OpDereference have mismatched mem, %s and %s", v.LongString(), a.LongString())
}
+ if v.Op == OpTailLECall {
+ // It's common for a tail call passing the same arguments (e.g. method wrapper),
+ // so this would be a self copy. Detect this and optimize it out.
+ a0 := a.Args[0]
+ if a0.Op == OpLocalAddr {
+ n := a0.Aux.(*ir.Name)
+ if n.Class == ir.PPARAM && n.FrameOffset()+x.f.Config.ctxt.FixedFrameSize() == aOffset {
+ continue
+ }
+ }
+ }
// "Dereference" of addressed (probably not-SSA-eligible) value becomes Move
// TODO(register args) this will be more complicated with registers in the picture.
mem = x.rewriteDereference(v.Block, sp, a, mem, aOffset, aux.SizeOfArg(auxI), aType, a.Pos)
@@ -1110,6 +1121,14 @@ func (x *expandState) rewriteArgs(v *Value, firstArg int) {
} else {
aOffset = aux.OffsetOfArg(auxI)
}
+ if v.Op == OpTailLECall && a.Op == OpArg && a.AuxInt == 0 {
+ // It's common for a tail call passing the same arguments (e.g. method wrapper),
+ // so this would be a self copy. Detect this and optimize it out.
+ n := a.Aux.(*ir.Name)
+ if n.Class == ir.PPARAM && n.FrameOffset()+x.f.Config.ctxt.FixedFrameSize() == aOffset {
+ continue
+ }
+ }
if x.debug > 1 {
x.Printf("...storeArg %s, %v, %d\n", a.LongString(), aType, aOffset)
}