diff options
author | Joel Sing <joel@sing.id.au> | 2020-03-31 02:04:45 +1100 |
---|---|---|
committer | Joel Sing <joel@sing.id.au> | 2020-05-10 14:43:46 +0000 |
commit | 57e32c4fbd4f20d567d1767dfc2d94bec828a8dc (patch) | |
tree | b0524682ed6fc484bace3aafca552a4d78ee6ade /src | |
parent | 000636fdb58c9444b17e54977382dc1d6357e8c3 (diff) | |
download | go-git-57e32c4fbd4f20d567d1767dfc2d94bec828a8dc.tar.gz |
cmd/compile: optimise branchs on riscv64
Make use of multi-control values and branch pseudo-instructions to optimise
compiler generated branches.
Change-Id: I7a8bf754db3c2082a390bf6a662ccf18cbcbee39
Reviewed-on: https://go-review.googlesource.com/c/go/+/226400
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/compile/internal/ssa/gen/RISCV64.rules | 32 | ||||
-rw-r--r-- | src/cmd/compile/internal/ssa/rewriteRISCV64.go | 125 |
2 files changed, 146 insertions, 11 deletions
diff --git a/src/cmd/compile/internal/ssa/gen/RISCV64.rules b/src/cmd/compile/internal/ssa/gen/RISCV64.rules index fbd87360ac..9437c8e9d4 100644 --- a/src/cmd/compile/internal/ssa/gen/RISCV64.rules +++ b/src/cmd/compile/internal/ssa/gen/RISCV64.rules @@ -445,16 +445,6 @@ (Addr {sym} base) => (MOVaddr {sym} [0] base) (LocalAddr {sym} base _) => (MOVaddr {sym} base) -// Conditional branches -// -// cond is 1 if true. -// -// TODO(prattmic): RISCV branch instructions take two operands to compare, -// so we could generate more efficient code by computing the condition in the -// branch itself. This should be revisited now that the compiler has support -// for two control values (https://golang.org/cl/196557). -(If cond yes no) => (BNEZ cond yes no) - // Calls (StaticCall ...) => (CALLstatic ...) (ClosureCall ...) => (CALLclosure ...) @@ -480,11 +470,31 @@ (AtomicExchange32 ...) => (LoweredAtomicExchange32 ...) (AtomicExchange64 ...) => (LoweredAtomicExchange64 ...) +// Conditional branches +(If cond yes no) => (BNEZ cond yes no) + // Optimizations -// Absorb SNEZ into branch. +// Absorb SEQZ/SNEZ into branch. +(BEQZ (SEQZ x) yes no) => (BNEZ x yes no) +(BEQZ (SNEZ x) yes no) => (BEQZ x yes no) +(BNEZ (SEQZ x) yes no) => (BEQZ x yes no) (BNEZ (SNEZ x) yes no) => (BNEZ x yes no) +// Convert BEQZ/BNEZ into more optimal branch conditions. +(BEQZ (SUB x y) yes no) => (BEQ x y yes no) +(BNEZ (SUB x y) yes no) => (BNE x y yes no) +(BEQZ (SLT x y) yes no) => (BGE x y yes no) +(BNEZ (SLT x y) yes no) => (BLT x y yes no) +(BEQZ (SLTU x y) yes no) => (BGEU x y yes no) +(BNEZ (SLTU x y) yes no) => (BLTU x y yes no) + +// Convert branch with zero to BEQZ/BNEZ. +(BEQ (MOVDconst [0]) cond yes no) => (BEQZ cond yes no) +(BEQ cond (MOVDconst [0]) yes no) => (BEQZ cond yes no) +(BNE (MOVDconst [0]) cond yes no) => (BNEZ cond yes no) +(BNE cond (MOVDconst [0]) yes no) => (BNEZ cond yes no) + // Store zero (MOVBstore [off] {sym} ptr (MOVBconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem) (MOVHstore [off] {sym} ptr (MOVHconst [0]) mem) => (MOVHstorezero [off] {sym} ptr mem) diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64.go b/src/cmd/compile/internal/ssa/rewriteRISCV64.go index 6b91c08628..c178290343 100644 --- a/src/cmd/compile/internal/ssa/rewriteRISCV64.go +++ b/src/cmd/compile/internal/ssa/rewriteRISCV64.go @@ -5120,7 +5120,105 @@ func rewriteValueRISCV64_OpZeroExt8to64(v *Value) bool { } func rewriteBlockRISCV64(b *Block) bool { switch b.Kind { + case BlockRISCV64BEQ: + // match: (BEQ (MOVDconst [0]) cond yes no) + // result: (BEQZ cond yes no) + for b.Controls[0].Op == OpRISCV64MOVDconst { + v_0 := b.Controls[0] + if auxIntToInt64(v_0.AuxInt) != 0 { + break + } + cond := b.Controls[1] + b.resetWithControl(BlockRISCV64BEQZ, cond) + return true + } + // match: (BEQ cond (MOVDconst [0]) yes no) + // result: (BEQZ cond yes no) + for b.Controls[1].Op == OpRISCV64MOVDconst { + cond := b.Controls[0] + v_1 := b.Controls[1] + if auxIntToInt64(v_1.AuxInt) != 0 { + break + } + b.resetWithControl(BlockRISCV64BEQZ, cond) + return true + } + case BlockRISCV64BEQZ: + // match: (BEQZ (SEQZ x) yes no) + // result: (BNEZ x yes no) + for b.Controls[0].Op == OpRISCV64SEQZ { + v_0 := b.Controls[0] + x := v_0.Args[0] + b.resetWithControl(BlockRISCV64BNEZ, x) + return true + } + // match: (BEQZ (SNEZ x) yes no) + // result: (BEQZ x yes no) + for b.Controls[0].Op == OpRISCV64SNEZ { + v_0 := b.Controls[0] + x := v_0.Args[0] + b.resetWithControl(BlockRISCV64BEQZ, x) + return true + } + // match: (BEQZ (SUB x y) yes no) + // result: (BEQ x y yes no) + for b.Controls[0].Op == OpRISCV64SUB { + v_0 := b.Controls[0] + y := v_0.Args[1] + x := v_0.Args[0] + b.resetWithControl2(BlockRISCV64BEQ, x, y) + return true + } + // match: (BEQZ (SLT x y) yes no) + // result: (BGE x y yes no) + for b.Controls[0].Op == OpRISCV64SLT { + v_0 := b.Controls[0] + y := v_0.Args[1] + x := v_0.Args[0] + b.resetWithControl2(BlockRISCV64BGE, x, y) + return true + } + // match: (BEQZ (SLTU x y) yes no) + // result: (BGEU x y yes no) + for b.Controls[0].Op == OpRISCV64SLTU { + v_0 := b.Controls[0] + y := v_0.Args[1] + x := v_0.Args[0] + b.resetWithControl2(BlockRISCV64BGEU, x, y) + return true + } + case BlockRISCV64BNE: + // match: (BNE (MOVDconst [0]) cond yes no) + // result: (BNEZ cond yes no) + for b.Controls[0].Op == OpRISCV64MOVDconst { + v_0 := b.Controls[0] + if auxIntToInt64(v_0.AuxInt) != 0 { + break + } + cond := b.Controls[1] + b.resetWithControl(BlockRISCV64BNEZ, cond) + return true + } + // match: (BNE cond (MOVDconst [0]) yes no) + // result: (BNEZ cond yes no) + for b.Controls[1].Op == OpRISCV64MOVDconst { + cond := b.Controls[0] + v_1 := b.Controls[1] + if auxIntToInt64(v_1.AuxInt) != 0 { + break + } + b.resetWithControl(BlockRISCV64BNEZ, cond) + return true + } case BlockRISCV64BNEZ: + // match: (BNEZ (SEQZ x) yes no) + // result: (BEQZ x yes no) + for b.Controls[0].Op == OpRISCV64SEQZ { + v_0 := b.Controls[0] + x := v_0.Args[0] + b.resetWithControl(BlockRISCV64BEQZ, x) + return true + } // match: (BNEZ (SNEZ x) yes no) // result: (BNEZ x yes no) for b.Controls[0].Op == OpRISCV64SNEZ { @@ -5129,6 +5227,33 @@ func rewriteBlockRISCV64(b *Block) bool { b.resetWithControl(BlockRISCV64BNEZ, x) return true } + // match: (BNEZ (SUB x y) yes no) + // result: (BNE x y yes no) + for b.Controls[0].Op == OpRISCV64SUB { + v_0 := b.Controls[0] + y := v_0.Args[1] + x := v_0.Args[0] + b.resetWithControl2(BlockRISCV64BNE, x, y) + return true + } + // match: (BNEZ (SLT x y) yes no) + // result: (BLT x y yes no) + for b.Controls[0].Op == OpRISCV64SLT { + v_0 := b.Controls[0] + y := v_0.Args[1] + x := v_0.Args[0] + b.resetWithControl2(BlockRISCV64BLT, x, y) + return true + } + // match: (BNEZ (SLTU x y) yes no) + // result: (BLTU x y yes no) + for b.Controls[0].Op == OpRISCV64SLTU { + v_0 := b.Controls[0] + y := v_0.Args[1] + x := v_0.Args[0] + b.resetWithControl2(BlockRISCV64BLTU, x, y) + return true + } case BlockIf: // match: (If cond yes no) // result: (BNEZ cond yes no) |