1
0
mirror of https://github.com/golang/go synced 2024-11-16 17:14:40 -07:00

cmd/compile: enable brachelim pass on loong64

Change-Id: I4fd1c307901c265ab9865bf8a74460ddc15e5d14
Reviewed-on: https://go-review.googlesource.com/c/go/+/416735
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: xiaodong liu <teaofmoli@gmail.com>
Auto-Submit: Wayne Zuo <wdvxdr@golangcn.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Wayne Zuo <wdvxdr@golangcn.org>
This commit is contained in:
Wayne Zuo 2022-07-09 19:26:47 +08:00 committed by Gopher Robot
parent 6b45863e47
commit 268f4629df
7 changed files with 127 additions and 1 deletions

View File

@ -786,6 +786,13 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p := s.Prog(obj.AGETCALLERPC)
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.OpLOONG64MASKEQZ, ssa.OpLOONG64MASKNEZ:
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG
p.From.Reg = v.Args[1].Reg()
p.Reg = v.Args[0].Reg()
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.OpClobber, ssa.OpClobberReg:
// TODO: implement for clobberdead experiment. Nop is ok for now.
default:

View File

@ -422,6 +422,8 @@
(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
(CondSelect <t> x y cond) => (OR (MASKEQZ <t> x cond) (MASKNEZ <t> y cond))
// Optimizations
// Absorb boolean tests into block
@ -615,6 +617,8 @@
(ORconst [-1] _) => (MOVVconst [-1])
(XORconst [0] x) => x
(XORconst [-1] x) => (NORconst [0] x)
(MASKEQZ (MOVVconst [0]) cond) => (MOVVconst [0])
(MASKNEZ (MOVVconst [0]) cond) => (MOVVconst [0])
// generic constant folding
(ADDVconst [c] (MOVVconst [d])) => (MOVVconst [c+d])

View File

@ -192,6 +192,9 @@ func init() {
{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
{name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
{name: "MASKEQZ", argLength: 2, reg: gp21, asm: "MASKEQZ"}, // returns 0 if arg1 == 0, otherwise returns arg0
{name: "MASKNEZ", argLength: 2, reg: gp21, asm: "MASKNEZ"}, // returns 0 if arg1 != 0, otherwise returns arg0
// shifts
{name: "SLLV", argLength: 2, reg: gp21, asm: "SLLV"}, // arg0 << arg1, shift amount is mod 64
{name: "SLLVconst", argLength: 1, reg: gp11, asm: "SLLV", aux: "Int64"}, // arg0 << auxInt

View File

@ -22,7 +22,7 @@ import "cmd/internal/src"
func branchelim(f *Func) {
// FIXME: add support for lowering CondSelects on more architectures
switch f.Config.arch {
case "arm64", "ppc64le", "ppc64", "amd64", "wasm":
case "arm64", "ppc64le", "ppc64", "amd64", "wasm", "loong64":
// implemented
default:
return
@ -83,6 +83,15 @@ func canCondSelect(v *Value, arch string, loadAddr *sparseSet) bool {
// See issue #26306.
return false
}
if arch == "loong64" {
// We should not generate conditional moves if neither of the arguments is constant zero,
// because it requires three instructions (OR, MASKEQZ, MASKNEZ) and will increase the
// register pressure.
if !(v.Args[0].isGenericIntConst() && v.Args[0].AuxInt == 0) &&
!(v.Args[1].isGenericIntConst() && v.Args[1].AuxInt == 0) {
return false
}
}
// For now, stick to simple scalars that fit in registers
switch {
case v.Type.Size() > v.Block.Func.Config.RegSize:

View File

@ -1740,6 +1740,8 @@ const (
OpLOONG64NEGD
OpLOONG64SQRTD
OpLOONG64SQRTF
OpLOONG64MASKEQZ
OpLOONG64MASKNEZ
OpLOONG64SLLV
OpLOONG64SLLVconst
OpLOONG64SRLV
@ -23263,6 +23265,34 @@ var opcodeTable = [...]opInfo{
},
},
},
{
name: "MASKEQZ",
argLen: 2,
asm: loong64.AMASKEQZ,
reg: regInfo{
inputs: []inputInfo{
{0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
{1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
},
outputs: []outputInfo{
{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
},
},
},
{
name: "MASKNEZ",
argLen: 2,
asm: loong64.AMASKNEZ,
reg: regInfo{
inputs: []inputInfo{
{0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
{1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
},
outputs: []outputInfo{
{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
},
},
},
{
name: "SLLV",
argLen: 2,

View File

@ -100,6 +100,8 @@ func rewriteValueLOONG64(v *Value) bool {
return rewriteValueLOONG64_OpCom64(v)
case OpCom8:
return rewriteValueLOONG64_OpCom8(v)
case OpCondSelect:
return rewriteValueLOONG64_OpCondSelect(v)
case OpConst16:
return rewriteValueLOONG64_OpConst16(v)
case OpConst32:
@ -229,6 +231,10 @@ func rewriteValueLOONG64(v *Value) bool {
return rewriteValueLOONG64_OpLOONG64LoweredAtomicStore32(v)
case OpLOONG64LoweredAtomicStore64:
return rewriteValueLOONG64_OpLOONG64LoweredAtomicStore64(v)
case OpLOONG64MASKEQZ:
return rewriteValueLOONG64_OpLOONG64MASKEQZ(v)
case OpLOONG64MASKNEZ:
return rewriteValueLOONG64_OpLOONG64MASKNEZ(v)
case OpLOONG64MOVBUload:
return rewriteValueLOONG64_OpLOONG64MOVBUload(v)
case OpLOONG64MOVBUreg:
@ -779,6 +785,27 @@ func rewriteValueLOONG64_OpCom8(v *Value) bool {
return true
}
}
func rewriteValueLOONG64_OpCondSelect(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (CondSelect <t> x y cond)
// result: (OR (MASKEQZ <t> x cond) (MASKNEZ <t> y cond))
for {
t := v.Type
x := v_0
y := v_1
cond := v_2
v.reset(OpLOONG64OR)
v0 := b.NewValue0(v.Pos, OpLOONG64MASKEQZ, t)
v0.AddArg2(x, cond)
v1 := b.NewValue0(v.Pos, OpLOONG64MASKNEZ, t)
v1.AddArg2(y, cond)
v.AddArg2(v0, v1)
return true
}
}
func rewriteValueLOONG64_OpConst16(v *Value) bool {
// match: (Const16 [val])
// result: (MOVVconst [int64(val)])
@ -1596,6 +1623,34 @@ func rewriteValueLOONG64_OpLOONG64LoweredAtomicStore64(v *Value) bool {
}
return false
}
func rewriteValueLOONG64_OpLOONG64MASKEQZ(v *Value) bool {
v_0 := v.Args[0]
// match: (MASKEQZ (MOVVconst [0]) cond)
// result: (MOVVconst [0])
for {
if v_0.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
v.reset(OpLOONG64MOVVconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueLOONG64_OpLOONG64MASKNEZ(v *Value) bool {
v_0 := v.Args[0]
// match: (MASKNEZ (MOVVconst [0]) cond)
// result: (MOVVconst [0])
for {
if v_0.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
v.reset(OpLOONG64MOVVconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueLOONG64_OpLOONG64MOVBUload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]

View File

@ -422,3 +422,21 @@ func cmovFcmp1(s, t float64, a, b int) {
// arm64:"CSINC\tEQ", -"CSEL"
r5 = x5
}
func cmovzero1(c bool) int {
var x int
if c {
x = 182
}
// loong64:"MASKEQZ", -"MASKNEZ"
return x
}
func cmovzero2(c bool) int {
var x int
if !c {
x = 182
}
// loong64:"MASKNEZ", -"MASKEQZ"
return x
}