[dev.ssa] cmd/compile: initial implementation of likely direction
Change-Id: Id8457b18c07bf717d13c9423d8f314f253eee64f
Reviewed-on: https://go-review.googlesource.com/13580
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index 2a1c184..0086fec 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -504,7 +504,7 @@
b := s.endBlock()
b.Kind = ssa.BlockIf
b.Control = cond
- // TODO(khr): likely direction
+ b.Likely = ssa.BranchPrediction(n.Likely) // gc and ssa both use -1/0/+1 for likeliness
bThen := s.f.NewBlock(ssa.BlockPlain)
bEnd := s.f.NewBlock(ssa.BlockPlain)
@@ -613,7 +613,7 @@
b = s.endBlock()
b.Kind = ssa.BlockIf
b.Control = cond
- // TODO(khr): likely direction
+ b.Likely = ssa.BranchLikely
addEdge(b, bBody)
addEdge(b, bEnd)
@@ -1181,6 +1181,10 @@
b := s.endBlock()
b.Kind = ssa.BlockIf
b.Control = el
+ // In theory, we should set b.Likely here based on context.
+ // However, gc only gives us likeliness hints
+ // in a single place, for plain OIF statements,
+ // and passing around context is finnicky, so don't bother for now.
bRight := s.f.NewBlock(ssa.BlockPlain)
bResult := s.f.NewBlock(ssa.BlockPlain)
@@ -1516,8 +1520,9 @@
}
c := s.newValue1(ssa.OpIsNonNil, Types[TBOOL], ptr)
b := s.endBlock()
- b.Kind = ssa.BlockIf // TODO: likeliness hint
+ b.Kind = ssa.BlockIf
b.Control = c
+ b.Likely = ssa.BranchLikely
bNext := s.f.NewBlock(ssa.BlockPlain)
bPanic := s.f.NewBlock(ssa.BlockPlain)
addEdge(b, bNext)
@@ -1541,6 +1546,7 @@
b := s.endBlock()
b.Kind = ssa.BlockIf
b.Control = cmp
+ b.Likely = ssa.BranchLikely
bNext := s.f.NewBlock(ssa.BlockPlain)
addEdge(b, bNext)
addEdge(b, s.exit)
@@ -2295,17 +2301,20 @@
ssa.BlockAMD64ULE, ssa.BlockAMD64UGE:
jmp := blockJump[b.Kind]
+ likely := b.Likely
+ var p *obj.Prog
switch next {
case b.Succs[0]:
- p := Prog(jmp.invasm)
+ p = Prog(jmp.invasm)
+ likely *= -1
p.To.Type = obj.TYPE_BRANCH
branches = append(branches, branch{p, b.Succs[1]})
case b.Succs[1]:
- p := Prog(jmp.asm)
+ p = Prog(jmp.asm)
p.To.Type = obj.TYPE_BRANCH
branches = append(branches, branch{p, b.Succs[0]})
default:
- p := Prog(jmp.asm)
+ p = Prog(jmp.asm)
p.To.Type = obj.TYPE_BRANCH
branches = append(branches, branch{p, b.Succs[0]})
q := Prog(obj.AJMP)
@@ -2313,6 +2322,19 @@
branches = append(branches, branch{q, b.Succs[1]})
}
+ // liblink reorders the instruction stream as it sees fit.
+ // Pass along what we know so liblink can make use of it.
+ // TODO: Once we've fully switched to SSA,
+ // make liblink leave our output alone.
+ switch likely {
+ case ssa.BranchUnlikely:
+ p.From.Type = obj.TYPE_CONST
+ p.From.Offset = 0
+ case ssa.BranchLikely:
+ p.From.Type = obj.TYPE_CONST
+ p.From.Offset = 1
+ }
+
default:
b.Unimplementedf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
}