aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/arm
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2018-04-05 16:14:42 -0400
committerDavid Chase <drchase@google.com>2018-04-11 17:35:34 +0000
commitab48574bab55eec033c4fed7f7eb4cedfaef90aa (patch)
treed3925ff6f0b4ebea6b2c292b502e44c704141009 /src/cmd/compile/internal/arm
parent2b239969390553726d5042e723b344f897bf810d (diff)
downloadgo-ab48574bab55eec033c4fed7f7eb4cedfaef90aa.tar.gz
go-ab48574bab55eec033c4fed7f7eb4cedfaef90aa.zip
cmd/compile: use Block.Likely to put likely branch first
When a neither of a conditional block's successors follows, the block must end with a conditional branch followed by a an unconditional branch. If the (conditional) branch is "unlikely", invert it and swap successors to make it likely instead. This doesn't matter to most benchmarks on amd64, but in one instance on amd64 it caused a 30% improvement, and it is otherwise harmless. The problematic loop is for i := 0; i < w; i++ { if pw[i] != 0 { return true } } compiled under GOEXPERIMENT=preemptibleloops This the very worst-case benchmark for that experiment. Also in this CL is a commoning up of heavily-repeated boilerplate, which made it much easier to see that the changes were applied correctly. In the future this should allow un-exporting of SSAGenState.Branches once the boilerplate-replacement is done everywhere. Change-Id: I0e5ded6eeb3ab1e3e0138e12d54c7e056bd99335 Reviewed-on: https://go-review.googlesource.com/104977 Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/arm')
-rw-r--r--src/cmd/compile/internal/arm/ssa.go22
1 files changed, 9 insertions, 13 deletions
diff --git a/src/cmd/compile/internal/arm/ssa.go b/src/cmd/compile/internal/arm/ssa.go
index abe40dfa9f..1c3b7eae11 100644
--- a/src/cmd/compile/internal/arm/ssa.go
+++ b/src/cmd/compile/internal/arm/ssa.go
@@ -884,23 +884,19 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
ssa.BlockARMULT, ssa.BlockARMUGT,
ssa.BlockARMULE, ssa.BlockARMUGE:
jmp := blockJump[b.Kind]
- var p *obj.Prog
switch next {
case b.Succs[0].Block():
- p = s.Prog(jmp.invasm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+ s.Br(jmp.invasm, b.Succs[1].Block())
case b.Succs[1].Block():
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+ s.Br(jmp.asm, b.Succs[0].Block())
default:
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
- q := s.Prog(obj.AJMP)
- q.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
+ if b.Likely != ssa.BranchUnlikely {
+ s.Br(jmp.asm, b.Succs[0].Block())
+ s.Br(obj.AJMP, b.Succs[1].Block())
+ } else {
+ s.Br(jmp.invasm, b.Succs[1].Block())
+ s.Br(obj.AJMP, b.Succs[0].Block())
+ }
}
default: