mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: implement jump table on loong64
Following CL 357330, use jump tables on Loong64.
goos: linux
goarch: loong64
pkg: cmd/compile/internal/test
cpu: Loongson-3A6000-HV @ 2500.00MHz
│ old │ new │
│ sec/op │ sec/op vs base │
Switch8Predictable 2.352n ± 0% 2.101n ± 0% -10.65% (p=0.000 n=10)
Switch8Unpredictable 11.99n ± 0% 10.25n ± 0% -14.51% (p=0.000 n=10)
Switch32Predictable 3.153n ± 0% 1.887n ± 1% -40.14% (p=0.000 n=10)
Switch32Unpredictable 12.47n ± 0% 10.22n ± 0% -18.00% (p=0.000 n=10)
SwitchStringPredictable 3.162n ± 0% 3.352n ± 0% +6.01% (p=0.000 n=10)
SwitchStringUnpredictable 14.70n ± 0% 13.31n ± 0% -9.46% (p=0.000 n=10)
SwitchTypePredictable 3.702n ± 0% 2.201n ± 0% -40.55% (p=0.000 n=10)
SwitchTypeUnpredictable 16.18n ± 0% 14.48n ± 0% -10.51% (p=0.000 n=10)
SwitchInterfaceTypePredictable 7.654n ± 0% 9.680n ± 0% +26.47% (p=0.000 n=10)
SwitchInterfaceTypeUnpredictable 22.04n ± 0% 22.44n ± 0% +1.81% (p=0.000 n=10)
geomean 7.441n 6.469n -13.07%
Change-Id: Id6f30fa73349c60fac17670084daee56973a955f
Reviewed-on: https://go-review.googlesource.com/c/go/+/705396
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
This commit is contained in:
parent
63cd912083
commit
af6999e60d
8 changed files with 72 additions and 14 deletions
|
|
@ -1266,6 +1266,29 @@ func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
|
|||
p.From.Reg = b.Controls[0].Reg()
|
||||
}
|
||||
}
|
||||
case ssa.BlockLOONG64JUMPTABLE:
|
||||
// ALSLV $3, Rarg0, Rarg1, REGTMP
|
||||
// MOVV (REGTMP), REGTMP
|
||||
// JMP (REGTMP)
|
||||
p := s.Prog(loong64.AALSLV)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = 3 // idx*8
|
||||
p.Reg = b.Controls[0].Reg()
|
||||
p.AddRestSourceReg(b.Controls[1].Reg())
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = loong64.REGTMP
|
||||
p1 := s.Prog(loong64.AMOVV)
|
||||
p1.From.Type = obj.TYPE_MEM
|
||||
p1.From.Reg = loong64.REGTMP
|
||||
p1.From.Offset = 0
|
||||
p1.To.Type = obj.TYPE_REG
|
||||
p1.To.Reg = loong64.REGTMP
|
||||
p2 := s.Prog(obj.AJMP)
|
||||
p2.To.Type = obj.TYPE_MEM
|
||||
p2.To.Reg = loong64.REGTMP
|
||||
// Save jump tables for later resolution of the target blocks.
|
||||
s.JumpTables = append(s.JumpTables, b)
|
||||
|
||||
default:
|
||||
b.Fatalf("branch not implemented: %s", b.LongString())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -504,6 +504,8 @@
|
|||
(MOVBUreg x:((SGT|SGTU) _ _)) => x
|
||||
(MOVBUreg x:(XOR (MOVVconst [1]) ((SGT|SGTU) _ _))) => x
|
||||
|
||||
(JumpTable idx) => (JUMPTABLE {makeJumpTableSym(b)} idx (MOVVaddr <typ.Uintptr> {makeJumpTableSym(b)} (SB)))
|
||||
|
||||
// Write barrier.
|
||||
(WB ...) => (LoweredWB ...)
|
||||
|
||||
|
|
|
|||
|
|
@ -577,6 +577,12 @@ func init() {
|
|||
{name: "BLT", controls: 2}, // controls[0] < controls[1]
|
||||
{name: "BGEU", controls: 2}, // controls[0] >= controls[1], unsigned
|
||||
{name: "BLTU", controls: 2}, // controls[0] < controls[1], unsigned
|
||||
|
||||
// JUMPTABLE implements jump tables.
|
||||
// Aux is the symbol (an *obj.LSym) for the jump table.
|
||||
// control[0] is the index into the jump table.
|
||||
// control[1] is the address of the jump table (the address of the symbol stored in Aux).
|
||||
{name: "JUMPTABLE", controls: 2, aux: "Sym"},
|
||||
}
|
||||
|
||||
archs = append(archs, arch{
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ const (
|
|||
BlockLOONG64BLT
|
||||
BlockLOONG64BGEU
|
||||
BlockLOONG64BLTU
|
||||
BlockLOONG64JUMPTABLE
|
||||
|
||||
BlockMIPSEQ
|
||||
BlockMIPSNE
|
||||
|
|
@ -250,20 +251,21 @@ var blockString = [...]string{
|
|||
BlockARM64GEnoov: "GEnoov",
|
||||
BlockARM64JUMPTABLE: "JUMPTABLE",
|
||||
|
||||
BlockLOONG64EQZ: "EQZ",
|
||||
BlockLOONG64NEZ: "NEZ",
|
||||
BlockLOONG64LTZ: "LTZ",
|
||||
BlockLOONG64LEZ: "LEZ",
|
||||
BlockLOONG64GTZ: "GTZ",
|
||||
BlockLOONG64GEZ: "GEZ",
|
||||
BlockLOONG64FPT: "FPT",
|
||||
BlockLOONG64FPF: "FPF",
|
||||
BlockLOONG64BEQ: "BEQ",
|
||||
BlockLOONG64BNE: "BNE",
|
||||
BlockLOONG64BGE: "BGE",
|
||||
BlockLOONG64BLT: "BLT",
|
||||
BlockLOONG64BGEU: "BGEU",
|
||||
BlockLOONG64BLTU: "BLTU",
|
||||
BlockLOONG64EQZ: "EQZ",
|
||||
BlockLOONG64NEZ: "NEZ",
|
||||
BlockLOONG64LTZ: "LTZ",
|
||||
BlockLOONG64LEZ: "LEZ",
|
||||
BlockLOONG64GTZ: "GTZ",
|
||||
BlockLOONG64GEZ: "GEZ",
|
||||
BlockLOONG64FPT: "FPT",
|
||||
BlockLOONG64FPF: "FPF",
|
||||
BlockLOONG64BEQ: "BEQ",
|
||||
BlockLOONG64BNE: "BNE",
|
||||
BlockLOONG64BGE: "BGE",
|
||||
BlockLOONG64BLT: "BLT",
|
||||
BlockLOONG64BGEU: "BGEU",
|
||||
BlockLOONG64BLTU: "BLTU",
|
||||
BlockLOONG64JUMPTABLE: "JUMPTABLE",
|
||||
|
||||
BlockMIPSEQ: "EQ",
|
||||
BlockMIPSNE: "NE",
|
||||
|
|
|
|||
|
|
@ -12148,6 +12148,19 @@ func rewriteBlockLOONG64(b *Block) bool {
|
|||
b.resetWithControl(BlockLOONG64NEZ, v0)
|
||||
return true
|
||||
}
|
||||
case BlockJumpTable:
|
||||
// match: (JumpTable idx)
|
||||
// result: (JUMPTABLE {makeJumpTableSym(b)} idx (MOVVaddr <typ.Uintptr> {makeJumpTableSym(b)} (SB)))
|
||||
for {
|
||||
idx := b.Controls[0]
|
||||
v0 := b.NewValue0(b.Pos, OpLOONG64MOVVaddr, typ.Uintptr)
|
||||
v0.Aux = symToAux(makeJumpTableSym(b))
|
||||
v1 := b.NewValue0(b.Pos, OpSB, typ.Uintptr)
|
||||
v0.AddArg(v1)
|
||||
b.resetWithControl2(BlockLOONG64JUMPTABLE, idx, v0)
|
||||
b.Aux = symToAux(makeJumpTableSym(b))
|
||||
return true
|
||||
}
|
||||
case BlockLOONG64LEZ:
|
||||
// match: (LEZ (MOVVconst [c]) yes no)
|
||||
// cond: c <= 0
|
||||
|
|
|
|||
|
|
@ -707,6 +707,15 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
// so instruction sequences that use REGTMP are unsafe to
|
||||
// preempt asynchronously.
|
||||
obj.MarkUnsafePoints(c.ctxt, c.cursym.Func().Text, c.newprog, c.isUnsafePoint, c.isRestartable)
|
||||
|
||||
// Now that we know byte offsets, we can generate jump table entries.
|
||||
for _, jt := range cursym.Func().JumpTables {
|
||||
for i, p := range jt.Targets {
|
||||
// The ith jumptable entry points to the p.Pc'th
|
||||
// byte in the function symbol s.
|
||||
jt.Sym.WriteAddr(ctxt, int64(i)*8, 8, cursym, p.Pc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// isUnsafePoint returns whether p is an unsafe point.
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ var ArchLoong64 = &Arch{
|
|||
MinLC: 4,
|
||||
Alignment: 8, // Unaligned accesses are not guaranteed to be fast
|
||||
CanMergeLoads: true,
|
||||
CanJumpTable: true,
|
||||
HasLR: true,
|
||||
FixedFrameSize: 8, // LR
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ func f(x string) int {
|
|||
func square(x int) int {
|
||||
// amd64:`JMP\s\(.*\)\(.*\)$`
|
||||
// arm64:`MOVD\s\(R.*\)\(R.*<<3\)`,`JMP\s\(R.*\)$`
|
||||
// loong64: `ALSLV`,`MOVV`,`JMP`
|
||||
switch x {
|
||||
case 1:
|
||||
return 1
|
||||
|
|
@ -51,6 +52,7 @@ func square(x int) int {
|
|||
func length(x string) int {
|
||||
// amd64:`JMP\s\(.*\)\(.*\)$`
|
||||
// arm64:`MOVD\s\(R.*\)\(R.*<<3\)`,`JMP\s\(R.*\)$`
|
||||
// loong64:`ALSLV`,`MOVV`,`JMP`
|
||||
switch x {
|
||||
case "a":
|
||||
return 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue