mirror of https://github.com/golang/go.git
cmd/compile: fold negation into subtraction on riscv64
Fold negation into subtraction and avoid double negation. This removes around 500 instructions from the Go binary on riscv64. Change-Id: I4aac6c87baa2a0759b180ba87876d488a23df6d7 Reviewed-on: https://go-review.googlesource.com/c/go/+/431105 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Joedian Reid <joedian@golang.org> Reviewed-by: Wayne Zuo <wdvxdr@golangcn.org> Run-TryBot: Joel Sing <joel@sing.id.au> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
ba8c94b5f2
commit
4274ffd4b8
|
|
@ -778,6 +778,13 @@
|
||||||
(SUB (MOVDconst [0]) x) => (NEG x)
|
(SUB (MOVDconst [0]) x) => (NEG x)
|
||||||
(SUBW (MOVDconst [0]) x) => (NEGW x)
|
(SUBW (MOVDconst [0]) x) => (NEGW x)
|
||||||
|
|
||||||
|
// Fold negation into subtraction.
|
||||||
|
(NEG (SUB x y)) => (SUB y x)
|
||||||
|
(NEG <t> s:(ADDI [val] (SUB x y))) && s.Uses == 1 && is32Bit(-val) => (ADDI [-val] (SUB <t> y x))
|
||||||
|
|
||||||
|
// Double negation.
|
||||||
|
(NEG (NEG x)) => x
|
||||||
|
|
||||||
// Addition of zero or two constants.
|
// Addition of zero or two constants.
|
||||||
(ADDI [0] x) => x
|
(ADDI [0] x) => x
|
||||||
(ADDI [x] (MOVDconst [y])) && is32Bit(x + y) => (MOVDconst [x + y])
|
(ADDI [x] (MOVDconst [y])) && is32Bit(x + y) => (MOVDconst [x + y])
|
||||||
|
|
|
||||||
|
|
@ -5437,6 +5437,55 @@ func rewriteValueRISCV64_OpRISCV64MOVWstorezero(v *Value) bool {
|
||||||
}
|
}
|
||||||
func rewriteValueRISCV64_OpRISCV64NEG(v *Value) bool {
|
func rewriteValueRISCV64_OpRISCV64NEG(v *Value) bool {
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
|
b := v.Block
|
||||||
|
// match: (NEG (SUB x y))
|
||||||
|
// result: (SUB y x)
|
||||||
|
for {
|
||||||
|
if v_0.Op != OpRISCV64SUB {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
y := v_0.Args[1]
|
||||||
|
x := v_0.Args[0]
|
||||||
|
v.reset(OpRISCV64SUB)
|
||||||
|
v.AddArg2(y, x)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (NEG <t> s:(ADDI [val] (SUB x y)))
|
||||||
|
// cond: s.Uses == 1 && is32Bit(-val)
|
||||||
|
// result: (ADDI [-val] (SUB <t> y x))
|
||||||
|
for {
|
||||||
|
t := v.Type
|
||||||
|
s := v_0
|
||||||
|
if s.Op != OpRISCV64ADDI {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
val := auxIntToInt64(s.AuxInt)
|
||||||
|
s_0 := s.Args[0]
|
||||||
|
if s_0.Op != OpRISCV64SUB {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
y := s_0.Args[1]
|
||||||
|
x := s_0.Args[0]
|
||||||
|
if !(s.Uses == 1 && is32Bit(-val)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpRISCV64ADDI)
|
||||||
|
v.AuxInt = int64ToAuxInt(-val)
|
||||||
|
v0 := b.NewValue0(v.Pos, OpRISCV64SUB, t)
|
||||||
|
v0.AddArg2(y, x)
|
||||||
|
v.AddArg(v0)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (NEG (NEG x))
|
||||||
|
// result: x
|
||||||
|
for {
|
||||||
|
if v_0.Op != OpRISCV64NEG {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
x := v_0.Args[0]
|
||||||
|
v.copyOf(x)
|
||||||
|
return true
|
||||||
|
}
|
||||||
// match: (NEG (MOVDconst [x]))
|
// match: (NEG (MOVDconst [x]))
|
||||||
// result: (MOVDconst [-x])
|
// result: (MOVDconst [-x])
|
||||||
for {
|
for {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue