aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorlimeidan <limeidan@loongson.cn>2025-09-19 11:18:13 +0800
committerabner chenc <chenguoqi@loongson.cn>2025-09-27 05:02:58 -0700
commitaf6999e60d498887fceaeca89f4aa88ff35c91df (patch)
treef3a76706b883a23539817c53cbc4dab709318705 /src/cmd
parent63cd9120836fe935bf39dc9b3a19ad44eab7f063 (diff)
downloadgo-af6999e60d498887fceaeca89f4aa88ff35c91df.tar.xz
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>
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/compile/internal/loong64/ssa.go23
-rw-r--r--src/cmd/compile/internal/ssa/_gen/LOONG64.rules2
-rw-r--r--src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go6
-rw-r--r--src/cmd/compile/internal/ssa/opGen.go30
-rw-r--r--src/cmd/compile/internal/ssa/rewriteLOONG64.go13
-rw-r--r--src/cmd/internal/obj/loong64/asm.go9
-rw-r--r--src/cmd/internal/sys/arch.go1
7 files changed, 70 insertions, 14 deletions
diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go
index 100ebf0456..bd0d96a695 100644
--- a/src/cmd/compile/internal/loong64/ssa.go
+++ b/src/cmd/compile/internal/loong64/ssa.go
@@ -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())
}
diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules
index 0d2384143c..287eedee37 100644
--- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules
+++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules
@@ -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 ...)
diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go
index a3db4def56..a85a566660 100644
--- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go
+++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go
@@ -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{
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index b4aae50b89..92adf5341b 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -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",
diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go
index 3990b2833b..3fc57e9f49 100644
--- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go
+++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go
@@ -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
diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go
index e20ceaae95..ca6e2be4aa 100644
--- a/src/cmd/internal/obj/loong64/asm.go
+++ b/src/cmd/internal/obj/loong64/asm.go
@@ -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.
diff --git a/src/cmd/internal/sys/arch.go b/src/cmd/internal/sys/arch.go
index 484538f28f..3c92a6bbf2 100644
--- a/src/cmd/internal/sys/arch.go
+++ b/src/cmd/internal/sys/arch.go
@@ -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
}