diff options
author | Ruslan Andreev <ruslan.andreev@huawei.com> | 2021-01-19 22:30:10 +0800 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2021-05-12 16:23:30 +0000 |
commit | 3b321a9d122f0dbf8b333cc79bbf61218e3d05ba (patch) | |
tree | 8bc8bfeb9f886a84f695ca542623e58df30d544d /src/cmd/compile/internal/ssa/rewriteARM64.go | |
parent | 07ff596404b03a8e01ed53f1553c59eb215dc697 (diff) | |
download | go-3b321a9d122f0dbf8b333cc79bbf61218e3d05ba.tar.gz go-3b321a9d122f0dbf8b333cc79bbf61218e3d05ba.zip |
cmd/compile: add arch-specific inlining for runtime.memmove
This CL add runtime.memmove inlining for AMD64 and ARM64.
According to ssa dump from testcases generic rules can't inline
memmomve properly due to one of the arguments is Phi operation. But this
Phi op will be optimized out by later optimization stages. As a result
memmove can be inlined during arch-specific rules.
The commit add new optimization rules to arch-specific rules that can
inline runtime.memmove if it possible during lowering stage.
Optimization fires 5 times in Go source-code using regabi.
Fixes #41662
Change-Id: Iaffaf4c482d068b5f0683d141863892202cc8824
Reviewed-on: https://go-review.googlesource.com/c/go/+/289151
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: David Chase <drchase@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/rewriteARM64.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/rewriteARM64.go | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go index 0ba3951df5..3cdc4d36cb 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM64.go +++ b/src/cmd/compile/internal/ssa/rewriteARM64.go @@ -984,6 +984,8 @@ func rewriteValueARM64(v *Value) bool { return rewriteValueARM64_OpSelect0(v) case OpSelect1: return rewriteValueARM64_OpSelect1(v) + case OpSelectN: + return rewriteValueARM64_OpSelectN(v) case OpSignExt16to32: v.Op = OpARM64MOVHreg return true @@ -25983,6 +25985,54 @@ func rewriteValueARM64_OpSelect1(v *Value) bool { } return false } +func rewriteValueARM64_OpSelectN(v *Value) bool { + v_0 := v.Args[0] + b := v.Block + config := b.Func.Config + // match: (SelectN [0] call:(CALLstatic {sym} s1:(MOVDstore _ (MOVDconst [sz]) s2:(MOVDstore _ src s3:(MOVDstore {t} _ dst mem))))) + // cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1, s2, s3, call) + // result: (Move [sz] dst src mem) + for { + if auxIntToInt64(v.AuxInt) != 0 { + break + } + call := v_0 + if call.Op != OpARM64CALLstatic { + break + } + sym := auxToCall(call.Aux) + s1 := call.Args[0] + if s1.Op != OpARM64MOVDstore { + break + } + _ = s1.Args[2] + s1_1 := s1.Args[1] + if s1_1.Op != OpARM64MOVDconst { + break + } + sz := auxIntToInt64(s1_1.AuxInt) + s2 := s1.Args[2] + if s2.Op != OpARM64MOVDstore { + break + } + _ = s2.Args[2] + src := s2.Args[1] + s3 := s2.Args[2] + if s3.Op != OpARM64MOVDstore { + break + } + mem := s3.Args[2] + dst := s3.Args[1] + if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1, s2, s3, call)) { + break + } + v.reset(OpMove) + v.AuxInt = int64ToAuxInt(sz) + v.AddArg3(dst, src, mem) + return true + } + return false +} func rewriteValueARM64_OpSlicemask(v *Value) bool { v_0 := v.Args[0] b := v.Block |