1
0
mirror of https://github.com/golang/go synced 2024-11-19 16:24:45 -07:00

cmd/compile: make more use of value switches

Use them to replace if/else chains with at least three comparisons,
where the code becomes clearly simpler.

Passes toolstash -cmp on std cmd.

Change-Id: Ic98aa3905944ddcab5aef5f9d9ba376853263d94
Reviewed-on: https://go-review.googlesource.com/70934
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Daniel Martí 2017-10-15 22:49:52 +01:00 committed by Emmanuel Odeke
parent e0111bb0f4
commit bb45bc27b5
5 changed files with 58 additions and 68 deletions

View File

@ -129,7 +129,8 @@ func (v *bottomUpVisitor) visitcode(n *Node, min uint32) uint32 {
min = v.visitcodelist(n.Nbody, min) min = v.visitcodelist(n.Nbody, min)
min = v.visitcodelist(n.Rlist, min) min = v.visitcodelist(n.Rlist, min)
if n.Op == OCALLFUNC || n.Op == OCALLMETH { switch n.Op {
case OCALLFUNC, OCALLMETH:
fn := n.Left fn := n.Left
if n.Op == OCALLMETH { if n.Op == OCALLMETH {
fn = asNode(n.Left.Sym.Def) fn = asNode(n.Left.Sym.Def)
@ -140,9 +141,8 @@ func (v *bottomUpVisitor) visitcode(n *Node, min uint32) uint32 {
min = m min = m
} }
} }
}
if n.Op == OCLOSURE { case OCLOSURE:
m := v.visit(n.Func.Closure) m := v.visit(n.Func.Closure)
if m < min { if m < min {
min = m min = m
@ -1279,16 +1279,14 @@ func parsetag(note string) uint16 {
// to the second output (and if there are more than two outputs, there is no flow to those.) // to the second output (and if there are more than two outputs, there is no flow to those.)
func describeEscape(em uint16) string { func describeEscape(em uint16) string {
var s string var s string
if em&EscMask == EscUnknown { switch em & EscMask {
case EscUnknown:
s = "EscUnknown" s = "EscUnknown"
} case EscNone:
if em&EscMask == EscNone {
s = "EscNone" s = "EscNone"
} case EscHeap:
if em&EscMask == EscHeap {
s = "EscHeap" s = "EscHeap"
} case EscReturn:
if em&EscMask == EscReturn {
s = "EscReturn" s = "EscReturn"
} }
if em&EscContentEscapes != 0 { if em&EscContentEscapes != 0 {

View File

@ -224,15 +224,14 @@ func (p *noder) importDecl(imp *syntax.ImportDecl) {
pack.Sym = my pack.Sym = my
pack.Name.Pkg = ipkg pack.Name.Pkg = ipkg
if my.Name == "." { switch my.Name {
case ".":
importdot(ipkg, pack) importdot(ipkg, pack)
return return
} case "init":
if my.Name == "init" {
yyerrorl(pack.Pos, "cannot import package as init - init must be a func") yyerrorl(pack.Pos, "cannot import package as init - init must be a func")
return return
} case "_":
if my.Name == "_" {
return return
} }
if my.Def != nil { if my.Def != nil {

View File

@ -213,10 +213,10 @@ func init2(n *Node, out *[]*Node) {
init2list(n.Rlist, out) init2list(n.Rlist, out)
init2list(n.Nbody, out) init2list(n.Nbody, out)
if n.Op == OCLOSURE { switch n.Op {
case OCLOSURE:
init2list(n.Func.Closure.Nbody, out) init2list(n.Func.Closure.Nbody, out)
} case ODOTMETH, OCALLPART:
if n.Op == ODOTMETH || n.Op == OCALLPART {
init2(asNode(n.Type.FuncType().Nname), out) init2(asNode(n.Type.FuncType().Nname), out)
} }
} }

View File

@ -2323,7 +2323,8 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
// This function is intended to handle && and || better than just calling // This function is intended to handle && and || better than just calling
// s.expr(cond) and branching on the result. // s.expr(cond) and branching on the result.
func (s *state) condBranch(cond *Node, yes, no *ssa.Block, likely int8) { func (s *state) condBranch(cond *Node, yes, no *ssa.Block, likely int8) {
if cond.Op == OANDAND { switch cond.Op {
case OANDAND:
mid := s.f.NewBlock(ssa.BlockPlain) mid := s.f.NewBlock(ssa.BlockPlain)
s.stmtList(cond.Ninit) s.stmtList(cond.Ninit)
s.condBranch(cond.Left, mid, no, max8(likely, 0)) s.condBranch(cond.Left, mid, no, max8(likely, 0))
@ -2336,8 +2337,7 @@ func (s *state) condBranch(cond *Node, yes, no *ssa.Block, likely int8) {
// the likeliness of the first branch. // the likeliness of the first branch.
// TODO: have the frontend give us branch prediction hints for // TODO: have the frontend give us branch prediction hints for
// OANDAND and OOROR nodes (if it ever has such info). // OANDAND and OOROR nodes (if it ever has such info).
} case OOROR:
if cond.Op == OOROR {
mid := s.f.NewBlock(ssa.BlockPlain) mid := s.f.NewBlock(ssa.BlockPlain)
s.stmtList(cond.Ninit) s.stmtList(cond.Ninit)
s.condBranch(cond.Left, yes, mid, min8(likely, 0)) s.condBranch(cond.Left, yes, mid, min8(likely, 0))
@ -2347,8 +2347,7 @@ func (s *state) condBranch(cond *Node, yes, no *ssa.Block, likely int8) {
// Note: if likely==-1, then both recursive calls pass -1. // Note: if likely==-1, then both recursive calls pass -1.
// If likely==1, then we don't have enough info to decide // If likely==1, then we don't have enough info to decide
// the likelihood of the first branch. // the likelihood of the first branch.
} case ONOT:
if cond.Op == ONOT {
s.stmtList(cond.Ninit) s.stmtList(cond.Ninit)
s.condBranch(cond.Left, no, yes, -likely) s.condBranch(cond.Left, no, yes, -likely)
return return
@ -3990,14 +3989,15 @@ func (s *state) referenceTypeBuiltin(n *Node, x *ssa.Value) *ssa.Value {
b.AddEdgeTo(bElse) b.AddEdgeTo(bElse)
s.startBlock(bElse) s.startBlock(bElse)
if n.Op == OLEN { switch n.Op {
case OLEN:
// length is stored in the first word for map/chan // length is stored in the first word for map/chan
s.vars[n] = s.newValue2(ssa.OpLoad, lenType, x, s.mem()) s.vars[n] = s.newValue2(ssa.OpLoad, lenType, x, s.mem())
} else if n.Op == OCAP { case OCAP:
// capacity is stored in the second word for chan // capacity is stored in the second word for chan
sw := s.newValue1I(ssa.OpOffPtr, lenType.PtrTo(), lenType.Width, x) sw := s.newValue1I(ssa.OpOffPtr, lenType.PtrTo(), lenType.Width, x)
s.vars[n] = s.newValue2(ssa.OpLoad, lenType, sw, s.mem()) s.vars[n] = s.newValue2(ssa.OpLoad, lenType, sw, s.mem())
} else { default:
s.Fatalf("op must be OLEN or OCAP") s.Fatalf("op must be OLEN or OCAP")
} }
s.endBlock() s.endBlock()

View File

@ -990,61 +990,55 @@ opswitch:
n = walkexpr(n, init) n = walkexpr(n, init)
case OCONV, OCONVNOP: case OCONV, OCONVNOP:
if thearch.LinkArch.Family == sys.ARM || thearch.LinkArch.Family == sys.MIPS { switch thearch.LinkArch.Family {
case sys.ARM, sys.MIPS:
if n.Left.Type.IsFloat() { if n.Left.Type.IsFloat() {
if n.Type.Etype == TINT64 { switch n.Type.Etype {
case TINT64:
n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64])) n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break break opswitch
} case TUINT64:
if n.Type.Etype == TUINT64 {
n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64])) n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break break opswitch
} }
} }
if n.Type.IsFloat() { if n.Type.IsFloat() {
if n.Left.Type.Etype == TINT64 { switch n.Left.Type.Etype {
case TINT64:
n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type) n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type)
break break opswitch
} case TUINT64:
if n.Left.Type.Etype == TUINT64 {
n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type) n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type)
break break opswitch
} }
} }
}
if thearch.LinkArch.Family == sys.I386 { case sys.I386:
if n.Left.Type.IsFloat() { if n.Left.Type.IsFloat() {
if n.Type.Etype == TINT64 { switch n.Type.Etype {
case TINT64:
n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64])) n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break break opswitch
} case TUINT64:
if n.Type.Etype == TUINT64 {
n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64])) n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break break opswitch
} case TUINT32, TUINT, TUINTPTR:
if n.Type.Etype == TUINT32 || n.Type.Etype == TUINT || n.Type.Etype == TUINTPTR {
n = mkcall("float64touint32", n.Type, init, conv(n.Left, types.Types[TFLOAT64])) n = mkcall("float64touint32", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break break opswitch
} }
} }
if n.Type.IsFloat() { if n.Type.IsFloat() {
if n.Left.Type.Etype == TINT64 { switch n.Left.Type.Etype {
case TINT64:
n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type) n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type)
break break opswitch
} case TUINT64:
if n.Left.Type.Etype == TUINT64 {
n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type) n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type)
break break opswitch
} case TUINT32, TUINT, TUINTPTR:
if n.Left.Type.Etype == TUINT32 || n.Left.Type.Etype == TUINT || n.Left.Type.Etype == TUINTPTR {
n = conv(mkcall("uint32tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT32])), n.Type) n = conv(mkcall("uint32tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT32])), n.Type)
break break opswitch
} }
} }
} }
@ -2419,22 +2413,21 @@ func reorder3save(n *Node, all []*Node, i int, early *[]*Node) *Node {
// outer value means containing struct or array. // outer value means containing struct or array.
func outervalue(n *Node) *Node { func outervalue(n *Node) *Node {
for { for {
if n.Op == OXDOT { switch n.Op {
case OXDOT:
Fatalf("OXDOT in walk") Fatalf("OXDOT in walk")
} case ODOT, OPAREN, OCONVNOP:
if n.Op == ODOT || n.Op == OPAREN || n.Op == OCONVNOP {
n = n.Left
continue
}
if n.Op == OINDEX && n.Left.Type != nil && n.Left.Type.IsArray() {
n = n.Left n = n.Left
continue continue
case OINDEX:
if n.Left.Type != nil && n.Left.Type.IsArray() {
n = n.Left
continue
}
} }
break break
} }
return n return n
} }