go/src/cmd/compile/internal/gc/swt.go

918 lines
24 KiB
Go
Raw Normal View History

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gc
import (
"cmd/compile/internal/types"
"cmd/internal/src"
"sort"
)
const (
// expression switch
switchKindExpr = iota // switch a {...} or switch 5 {...}
switchKindTrue // switch true {...} or switch {...}
switchKindFalse // switch false {...}
)
const (
binarySearchMin = 4 // minimum number of cases for binary search
integerRangeMin = 2 // minimum size of integer ranges
)
// An exprSwitch walks an expression switch.
type exprSwitch struct {
exprname *Node // node for the expression being switched on
kind int // kind of switch statement (switchKind*)
}
// A typeSwitch walks a type switch.
type typeSwitch struct {
hashname *Node // node for the hash of the type of the variable being switched on
facename *Node // node for the concrete type of the variable being switched on
okname *Node // boolean node used for comma-ok type assertions
}
// A caseClause is a single case clause in a switch statement.
type caseClause struct {
node *Node // points at case statement
ordinal int // position in switch
hash uint32 // hash of a type switch
// isconst indicates whether this case clause is a constant,
// for the purposes of the switch code generation.
// For expression switches, that's generally literals (case 5:, not case x:).
// For type switches, that's concrete types (case time.Time:), not interfaces (case io.Reader:).
isconst bool
}
// caseClauses are all the case clauses in a switch statement.
type caseClauses struct {
list []caseClause // general cases
defjmp *Node // OGOTO for default case or OBREAK if no default case present
niljmp *Node // OGOTO for nil type case in a type switch
}
// typecheckswitch typechecks a switch statement.
func typecheckswitch(n *Node) {
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
typecheckslice(n.Ninit.Slice(), ctxStmt)
if n.Left != nil && n.Left.Op == OTYPESW {
typecheckTypeSwitch(n)
} else {
typecheckExprSwitch(n)
}
}
func typecheckTypeSwitch(n *Node) {
n.Left.Right = typecheck(n.Left.Right, ctxExpr)
t := n.Left.Right.Type
if t != nil && !t.IsInterface() {
yyerrorl(n.Pos, "cannot type switch on non-interface value %L", n.Left.Right)
t = nil
}
n.Type = t // TODO(mdempsky): Remove; statements aren't typed.
// We don't actually declare the type switch's guarded
// declaration itself. So if there are no cases, we won't
// notice that it went unused.
if v := n.Left.Left; v != nil && !v.isBlank() && n.List.Len() == 0 {
yyerrorl(v.Pos, "%v declared and not used", v.Sym)
}
var defCase, nilCase *Node
var ts typeSet
for _, ncase := range n.List.Slice() {
ls := ncase.List.Slice()
if len(ls) == 0 { // default:
if defCase != nil {
yyerrorl(ncase.Pos, "multiple defaults in switch (first at %v)", defCase.Line())
} else {
defCase = ncase
}
}
for i := range ls {
ls[i] = typecheck(ls[i], ctxExpr|ctxType)
n1 := ls[i]
if t == nil || n1.Type == nil {
continue
}
var missing, have *types.Field
var ptr int
switch {
case n1.isNil(): // case nil:
if nilCase != nil {
yyerrorl(ncase.Pos, "multiple nil cases in type switch (first at %v)", nilCase.Line())
} else {
nilCase = ncase
}
case n1.Op != OTYPE:
yyerrorl(ncase.Pos, "%L is not a type", n1)
case !n1.Type.IsInterface() && !implements(n1.Type, t, &missing, &have, &ptr) && !missing.Broke():
if have != nil && !have.Broke() {
yyerrorl(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
" (wrong type for %v method)\n\thave %v%S\n\twant %v%S", n.Left.Right, n1.Type, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
} else if ptr != 0 {
yyerrorl(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
" (%v method has pointer receiver)", n.Left.Right, n1.Type, missing.Sym)
} else {
yyerrorl(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
" (missing %v method)", n.Left.Right, n1.Type, missing.Sym)
}
}
if n1.Op == OTYPE {
ts.add(ncase.Pos, n1.Type)
}
}
if ncase.Rlist.Len() != 0 {
// Assign the clause variable's type.
vt := t
if len(ls) == 1 {
if ls[0].Op == OTYPE {
vt = ls[0].Type
} else if ls[0].Op != OLITERAL { // TODO(mdempsky): Should be !ls[0].isNil()
// Invalid single-type case;
// mark variable as broken.
vt = nil
}
}
// TODO(mdempsky): It should be possible to
// still typecheck the case body.
if vt == nil {
continue
}
nvar := ncase.Rlist.First()
nvar.Type = vt
nvar = typecheck(nvar, ctxExpr|ctxAssign)
ncase.Rlist.SetFirst(nvar)
}
typecheckslice(ncase.Nbody.Slice(), ctxStmt)
}
}
type typeSet struct {
m map[string][]typeSetEntry
}
type typeSetEntry struct {
pos src.XPos
typ *types.Type
}
func (s *typeSet) add(pos src.XPos, typ *types.Type) {
if s.m == nil {
s.m = make(map[string][]typeSetEntry)
}
// LongString does not uniquely identify types, so we need to
// disambiguate collisions with types.Identical.
// TODO(mdempsky): Add a method that *is* unique.
ls := typ.LongString()
prevs := s.m[ls]
for _, prev := range prevs {
if types.Identical(typ, prev.typ) {
yyerrorl(pos, "duplicate case %v in type switch\n\tprevious case at %s", typ, linestr(prev.pos))
return
}
}
s.m[ls] = append(prevs, typeSetEntry{pos, typ})
}
func typecheckExprSwitch(n *Node) {
t := types.Types[TBOOL]
if n.Left != nil {
n.Left = typecheck(n.Left, ctxExpr)
n.Left = defaultlit(n.Left, nil)
t = n.Left.Type
}
var nilonly string
if t != nil {
switch {
case t.IsMap():
nilonly = "map"
case t.Etype == TFUNC:
nilonly = "func"
case t.IsSlice():
nilonly = "slice"
case !IsComparable(t):
if t.IsStruct() {
yyerrorl(n.Pos, "cannot switch on %L (struct containing %v cannot be compared)", n.Left, IncomparableField(t).Type)
} else {
yyerrorl(n.Pos, "cannot switch on %L", n.Left)
}
t = nil
}
}
n.Type = t // TODO(mdempsky): Remove; statements aren't typed.
var defCase *Node
var cs constSet
for _, ncase := range n.List.Slice() {
ls := ncase.List.Slice()
if len(ls) == 0 { // default:
if defCase != nil {
yyerrorl(ncase.Pos, "multiple defaults in switch (first at %v)", defCase.Line())
} else {
defCase = ncase
}
}
for i := range ls {
setlineno(ncase)
ls[i] = typecheck(ls[i], ctxExpr)
ls[i] = defaultlit(ls[i], t)
n1 := ls[i]
if t == nil || n1.Type == nil {
continue
}
switch {
case nilonly != "" && !n1.isNil():
yyerrorl(ncase.Pos, "invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left)
case t.IsInterface() && !n1.Type.IsInterface() && !IsComparable(n1.Type):
yyerrorl(ncase.Pos, "invalid case %L in switch (incomparable type)", n1)
case assignop(n1.Type, t, nil) == 0 && assignop(t, n1.Type, nil) == 0:
if n.Left != nil {
yyerrorl(ncase.Pos, "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left, n1.Type, t)
} else {
yyerrorl(ncase.Pos, "invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type)
}
}
// Don't check for duplicate bools. Although the spec allows it,
// (1) the compiler hasn't checked it in the past, so compatibility mandates it, and
// (2) it would disallow useful things like
// case GOARCH == "arm" && GOARM == "5":
// case GOARCH == "arm":
// which would both evaluate to false for non-ARM compiles.
if !n1.Type.IsBoolean() {
cs.add(ncase.Pos, n1, "case", "switch")
}
}
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
typecheckslice(ncase.Nbody.Slice(), ctxStmt)
}
}
// walkswitch walks a switch statement.
func walkswitch(sw *Node) {
// convert switch {...} to switch true {...}
if sw.Left == nil {
sw.Left = nodbool(true)
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
sw.Left = typecheck(sw.Left, ctxExpr)
sw.Left = defaultlit(sw.Left, nil)
}
if sw.Left.Op == OTYPESW {
var s typeSwitch
s.walk(sw)
} else {
var s exprSwitch
s.walk(sw)
}
}
// walk generates an AST implementing sw.
// sw is an expression switch.
// The AST is generally of the form of a linear
// search using if..goto, although binary search
// is used with long runs of constants.
func (s *exprSwitch) walk(sw *Node) {
// Guard against double walk, see #25776.
if sw.List.Len() == 0 && sw.Nbody.Len() > 0 {
return // Was fatal, but eliminating every possible source of double-walking is hard
}
casebody(sw, nil)
cond := sw.Left
sw.Left = nil
s.kind = switchKindExpr
if Isconst(cond, CTBOOL) {
s.kind = switchKindTrue
if !cond.Val().U.(bool) {
s.kind = switchKindFalse
}
}
// Given "switch string(byteslice)",
// with all cases being constants (or the default case),
// use a zero-cost alias of the byte slice.
// In theory, we could be more aggressive,
// allowing any side-effect-free expressions in cases,
// but it's a bit tricky because some of that information
// is unavailable due to the introduction of temporaries during order.
// Restricting to constants is simple and probably powerful enough.
// Do this before calling walkexpr on cond,
// because walkexpr will lower the string
// conversion into a runtime call.
// See issue 24937 for more discussion.
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
if cond.Op == OBYTES2STR {
ok := true
for _, cas := range sw.List.Slice() {
if cas.Op != OCASE {
Fatalf("switch string(byteslice) bad op: %v", cas.Op)
}
if cas.Left != nil && !Isconst(cas.Left, CTSTR) {
ok = false
break
}
}
if ok {
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
cond.Op = OBYTES2STRTMP
}
}
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
cond = walkexpr(cond, &sw.Ninit)
t := sw.Type
if t == nil {
return
}
// convert the switch into OIF statements
var cas []*Node
if s.kind == switchKindTrue || s.kind == switchKindFalse {
s.exprname = nodbool(s.kind == switchKindTrue)
} else if consttype(cond) > 0 {
// leave constants to enable dead code elimination (issue 9608)
s.exprname = cond
} else {
s.exprname = temp(cond.Type)
cas = []*Node{nod(OAS, s.exprname, cond)} // This gets walk()ed again in walkstmtlist just before end of this function. See #29562.
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
typecheckslice(cas, ctxStmt)
}
// Enumerate the cases and prepare the default case.
clauses := s.genCaseClauses(sw.List.Slice())
sw.List.Set(nil)
cc := clauses.list
// handle the cases in order
for len(cc) > 0 {
run := 1
if okforcmp[t.Etype] && cc[0].isconst {
// do binary search on runs of constants
for ; run < len(cc) && cc[run].isconst; run++ {
}
// sort and compile constants
sort.Sort(caseClauseByConstVal(cc[:run]))
}
a := s.walkCases(cc[:run])
cas = append(cas, a)
cc = cc[run:]
}
// handle default case
if nerrors == 0 {
cas = append(cas, clauses.defjmp)
sw.Nbody.Prepend(cas...)
walkstmtlist(sw.Nbody.Slice())
}
}
// walkCases generates an AST implementing the cases in cc.
func (s *exprSwitch) walkCases(cc []caseClause) *Node {
if len(cc) < binarySearchMin {
// linear search
var cas []*Node
for _, c := range cc {
n := c.node
lno := setlineno(n)
a := nod(OIF, nil, nil)
if rng := n.List.Slice(); rng != nil {
// Integer range.
// exprname is a temp or a constant,
// so it is safe to evaluate twice.
// In most cases, this conjunction will be
// rewritten by walkinrange into a single comparison.
low := nod(OGE, s.exprname, rng[0])
high := nod(OLE, s.exprname, rng[1])
a.Left = nod(OANDAND, low, high)
} else if (s.kind != switchKindTrue && s.kind != switchKindFalse) || assignop(n.Left.Type, s.exprname.Type, nil) == OCONVIFACE || assignop(s.exprname.Type, n.Left.Type, nil) == OCONVIFACE {
a.Left = nod(OEQ, s.exprname, n.Left) // if name == val
} else if s.kind == switchKindTrue {
a.Left = n.Left // if val
} else {
// s.kind == switchKindFalse
a.Left = nod(ONOT, n.Left, nil) // if !val
}
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
a.Left = typecheck(a.Left, ctxExpr)
a.Left = defaultlit(a.Left, nil)
a.Nbody.Set1(n.Right) // goto l
cas = append(cas, a)
lineno = lno
}
return liststmt(cas)
}
// find the middle and recur
half := len(cc) / 2
a := nod(OIF, nil, nil)
n := cc[half-1].node
var mid *Node
if rng := n.List.Slice(); rng != nil {
mid = rng[1] // high end of range
} else {
mid = n.Left
}
le := nod(OLE, s.exprname, mid)
if Isconst(mid, CTSTR) {
// Search by length and then by value; see caseClauseByConstVal.
lenlt := nod(OLT, nod(OLEN, s.exprname, nil), nod(OLEN, mid, nil))
leneq := nod(OEQ, nod(OLEN, s.exprname, nil), nod(OLEN, mid, nil))
a.Left = nod(OOROR, lenlt, nod(OANDAND, leneq, le))
} else {
a.Left = le
}
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
a.Left = typecheck(a.Left, ctxExpr)
a.Left = defaultlit(a.Left, nil)
a.Nbody.Set1(s.walkCases(cc[:half]))
a.Rlist.Set1(s.walkCases(cc[half:]))
return a
}
// casebody builds separate lists of statements and cases.
// It makes labels between cases and statements
// and deals with fallthrough, break, and unreachable statements.
func casebody(sw *Node, typeswvar *Node) {
if sw.List.Len() == 0 {
return
}
lno := setlineno(sw)
var cas []*Node // cases
var stat []*Node // statements
var def *Node // defaults
br := nod(OBREAK, nil, nil)
for _, n := range sw.List.Slice() {
setlineno(n)
if n.Op != OXCASE {
Fatalf("casebody %v", n.Op)
}
n.Op = OCASE
needvar := n.List.Len() != 1 || n.List.First().Op == OLITERAL
lbl := autolabel(".s")
jmp := nodSym(OGOTO, nil, lbl)
switch n.List.Len() {
case 0:
// default
if def != nil {
yyerrorl(n.Pos, "more than one default case")
}
// reuse original default case
n.Right = jmp
def = n
case 1:
// one case -- reuse OCASE node
n.Left = n.List.First()
n.Right = jmp
n.List.Set(nil)
cas = append(cas, n)
default:
// Expand multi-valued cases and detect ranges of integer cases.
if typeswvar != nil || sw.Left.Type.IsInterface() || !n.List.First().Type.IsInteger() || n.List.Len() < integerRangeMin {
// Can't use integer ranges. Expand each case into a separate node.
for _, n1 := range n.List.Slice() {
cas = append(cas, nod(OCASE, n1, jmp))
}
break
}
// Find integer ranges within runs of constants.
s := n.List.Slice()
j := 0
for j < len(s) {
// Find a run of constants.
var run int
for run = j; run < len(s) && Isconst(s[run], CTINT); run++ {
}
if run-j >= integerRangeMin {
// Search for integer ranges in s[j:run].
// Typechecking is done, so all values are already in an appropriate range.
search := s[j:run]
sort.Sort(constIntNodesByVal(search))
for beg, end := 0, 1; end <= len(search); end++ {
if end < len(search) && search[end].Int64() == search[end-1].Int64()+1 {
continue
}
if end-beg >= integerRangeMin {
// Record range in List.
c := nod(OCASE, nil, jmp)
c.List.Set2(search[beg], search[end-1])
cas = append(cas, c)
} else {
// Not large enough for range; record separately.
for _, n := range search[beg:end] {
cas = append(cas, nod(OCASE, n, jmp))
}
}
beg = end
}
j = run
}
// Advance to next constant, adding individual non-constant
// or as-yet-unhandled constant cases as we go.
for ; j < len(s) && (j < run || !Isconst(s[j], CTINT)); j++ {
cas = append(cas, nod(OCASE, s[j], jmp))
}
}
}
stat = append(stat, nodSym(OLABEL, nil, lbl))
if typeswvar != nil && needvar && n.Rlist.Len() != 0 {
l := []*Node{
nod(ODCL, n.Rlist.First(), nil),
nod(OAS, n.Rlist.First(), typeswvar),
}
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
typecheckslice(l, ctxStmt)
stat = append(stat, l...)
}
stat = append(stat, n.Nbody.Slice()...)
// Search backwards for the index of the fallthrough
// statement. Do not assume it'll be in the last
// position, since in some cases (e.g. when the statement
// list contains autotmp_ variables), one or more OVARKILL
// nodes will be at the end of the list.
fallIndex := len(stat) - 1
for stat[fallIndex].Op == OVARKILL {
fallIndex--
}
last := stat[fallIndex]
if last.Op != OFALL {
stat = append(stat, br)
}
}
stat = append(stat, br)
if def != nil {
cas = append(cas, def)
}
sw.List.Set(cas)
sw.Nbody.Set(stat)
lineno = lno
}
// genCaseClauses generates the caseClauses value for clauses.
func (s *exprSwitch) genCaseClauses(clauses []*Node) caseClauses {
var cc caseClauses
for _, n := range clauses {
if n.Left == nil && n.List.Len() == 0 {
// default case
if cc.defjmp != nil {
Fatalf("duplicate default case not detected during typechecking")
}
cc.defjmp = n.Right
continue
}
c := caseClause{node: n, ordinal: len(cc.list)}
if n.List.Len() > 0 {
c.isconst = true
}
switch consttype(n.Left) {
case CTFLT, CTINT, CTRUNE, CTSTR:
c.isconst = true
}
cc.list = append(cc.list, c)
}
if cc.defjmp == nil {
cc.defjmp = nod(OBREAK, nil, nil)
}
return cc
}
// genCaseClauses generates the caseClauses value for clauses.
func (s *typeSwitch) genCaseClauses(clauses []*Node) caseClauses {
var cc caseClauses
for _, n := range clauses {
switch {
case n.Left == nil:
// default case
if cc.defjmp != nil {
Fatalf("duplicate default case not detected during typechecking")
}
cc.defjmp = n.Right
continue
case n.Left.Op == OLITERAL:
// nil case in type switch
if cc.niljmp != nil {
Fatalf("duplicate nil case not detected during typechecking")
}
cc.niljmp = n.Right
continue
}
// general case
c := caseClause{
node: n,
ordinal: len(cc.list),
isconst: !n.Left.Type.IsInterface(),
hash: typehash(n.Left.Type),
}
cc.list = append(cc.list, c)
}
if cc.defjmp == nil {
cc.defjmp = nod(OBREAK, nil, nil)
}
return cc
}
// walk generates an AST that implements sw,
// where sw is a type switch.
// The AST is generally of the form of a linear
// search using if..goto, although binary search
// is used with long runs of concrete types.
func (s *typeSwitch) walk(sw *Node) {
cond := sw.Left
sw.Left = nil
if cond == nil {
sw.List.Set(nil)
return
}
if cond.Right == nil {
yyerrorl(sw.Pos, "type switch must have an assignment")
return
}
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
cond.Right = walkexpr(cond.Right, &sw.Ninit)
if !cond.Right.Type.IsInterface() {
yyerrorl(sw.Pos, "type switch must be on an interface")
return
}
var cas []*Node
// predeclare temporary variables and the boolean var
s.facename = temp(cond.Right.Type)
a := nod(OAS, s.facename, cond.Right)
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
a = typecheck(a, ctxStmt)
cas = append(cas, a)
s.okname = temp(types.Types[TBOOL])
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
s.okname = typecheck(s.okname, ctxExpr)
s.hashname = temp(types.Types[TUINT32])
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
s.hashname = typecheck(s.hashname, ctxExpr)
// set up labels and jumps
casebody(sw, s.facename)
clauses := s.genCaseClauses(sw.List.Slice())
sw.List.Set(nil)
def := clauses.defjmp
// For empty interfaces, do:
// if e._type == nil {
// do nil case if it exists, otherwise default
// }
// h := e._type.hash
// Use a similar strategy for non-empty interfaces.
// Get interface descriptor word.
// For empty interfaces this will be the type.
// For non-empty interfaces this will be the itab.
itab := nod(OITAB, s.facename, nil)
// Check for nil first.
i := nod(OIF, nil, nil)
i.Left = nod(OEQ, itab, nodnil())
if clauses.niljmp != nil {
// Do explicit nil case right here.
i.Nbody.Set1(clauses.niljmp)
} else {
// Jump to default case.
lbl := autolabel(".s")
i.Nbody.Set1(nodSym(OGOTO, nil, lbl))
// Wrap default case with label.
blk := nod(OBLOCK, nil, nil)
blk.List.Set2(nodSym(OLABEL, nil, lbl), def)
def = blk
}
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
i.Left = typecheck(i.Left, ctxExpr)
i.Left = defaultlit(i.Left, nil)
cas = append(cas, i)
// Load hash from type or itab.
h := nodSym(ODOTPTR, itab, nil)
h.Type = types.Types[TUINT32]
h.SetTypecheck(1)
if cond.Right.Type.IsEmptyInterface() {
h.Xoffset = int64(2 * Widthptr) // offset of hash in runtime._type
} else {
h.Xoffset = int64(2 * Widthptr) // offset of hash in runtime.itab
}
cmd/compile: pack bool fields in Node, Name, Func and Type structs to bitsets This reduces compiler memory usage by up to 4% - see compilebench results below. name old time/op new time/op delta Template 245ms ± 4% 241ms ± 2% -1.88% (p=0.029 n=10+10) Unicode 126ms ± 3% 124ms ± 3% ~ (p=0.105 n=10+10) GoTypes 805ms ± 2% 813ms ± 3% ~ (p=0.515 n=8+10) Compiler 3.95s ± 2% 3.83s ± 1% -2.96% (p=0.000 n=9+10) MakeBash 47.4s ± 4% 46.6s ± 1% -1.59% (p=0.028 n=9+10) name old user-ns/op new user-ns/op delta Template 324M ± 5% 326M ± 3% ~ (p=0.935 n=10+10) Unicode 186M ± 5% 178M ±10% ~ (p=0.067 n=9+10) GoTypes 1.08G ± 7% 1.09G ± 4% ~ (p=0.956 n=10+10) Compiler 5.34G ± 4% 5.31G ± 1% ~ (p=0.501 n=10+8) name old alloc/op new alloc/op delta Template 41.0MB ± 0% 39.8MB ± 0% -3.03% (p=0.000 n=10+10) Unicode 32.3MB ± 0% 31.0MB ± 0% -4.13% (p=0.000 n=10+10) GoTypes 119MB ± 0% 116MB ± 0% -2.39% (p=0.000 n=10+10) Compiler 499MB ± 0% 487MB ± 0% -2.48% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Template 380k ± 1% 379k ± 1% ~ (p=0.436 n=10+10) Unicode 324k ± 1% 324k ± 0% ~ (p=0.853 n=10+10) GoTypes 1.15M ± 0% 1.15M ± 0% ~ (p=0.481 n=10+10) Compiler 4.41M ± 0% 4.41M ± 0% -0.12% (p=0.007 n=10+10) name old text-bytes new text-bytes delta HelloSize 623k ± 0% 623k ± 0% ~ (all equal) CmdGoSize 6.64M ± 0% 6.64M ± 0% ~ (all equal) name old data-bytes new data-bytes delta HelloSize 5.81k ± 0% 5.81k ± 0% ~ (all equal) CmdGoSize 238k ± 0% 238k ± 0% ~ (all equal) name old bss-bytes new bss-bytes delta HelloSize 134k ± 0% 134k ± 0% ~ (all equal) CmdGoSize 152k ± 0% 152k ± 0% ~ (all equal) name old exe-bytes new exe-bytes delta HelloSize 967k ± 0% 967k ± 0% ~ (all equal) CmdGoSize 10.2M ± 0% 10.2M ± 0% ~ (all equal) Change-Id: I1f40af738254892bd6c8ba2eb43390b175753d52 Reviewed-on: https://go-review.googlesource.com/37445 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-02-27 19:56:38 +02:00
h.SetBounded(true) // guaranteed not to fault
a = nod(OAS, s.hashname, h)
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
a = typecheck(a, ctxStmt)
cas = append(cas, a)
cc := clauses.list
// insert type equality check into each case block
for _, c := range cc {
c.node.Right = s.typeone(c.node)
}
// generate list of if statements, binary search for constant sequences
for len(cc) > 0 {
if !cc[0].isconst {
n := cc[0].node
cas = append(cas, n.Right)
cc = cc[1:]
continue
}
// identify run of constants
var run int
for run = 1; run < len(cc) && cc[run].isconst; run++ {
}
// sort by hash
sort.Sort(caseClauseByType(cc[:run]))
// for debugging: linear search
if false {
for i := 0; i < run; i++ {
n := cc[i].node
cas = append(cas, n.Right)
}
continue
}
// combine adjacent cases with the same hash
var batch []caseClause
for i, j := 0, 0; i < run; i = j {
hash := []*Node{cc[i].node.Right}
for j = i + 1; j < run && cc[i].hash == cc[j].hash; j++ {
hash = append(hash, cc[j].node.Right)
}
cc[i].node.Right = liststmt(hash)
batch = append(batch, cc[i])
}
// binary search among cases to narrow by hash
cas = append(cas, s.walkCases(batch))
cc = cc[run:]
}
// handle default case
if nerrors == 0 {
cas = append(cas, def)
sw.Nbody.Prepend(cas...)
sw.List.Set(nil)
walkstmtlist(sw.Nbody.Slice())
}
}
// typeone generates an AST that jumps to the
// case body if the variable is of type t.
func (s *typeSwitch) typeone(t *Node) *Node {
var name *Node
var init Nodes
if t.Rlist.Len() == 0 {
name = nblank
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
nblank = typecheck(nblank, ctxExpr|ctxAssign)
} else {
name = t.Rlist.First()
init.Append(nod(ODCL, name, nil))
a := nod(OAS, name, nil)
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
a = typecheck(a, ctxStmt)
init.Append(a)
}
a := nod(OAS2, nil, nil)
a.List.Set2(name, s.okname) // name, ok =
b := nod(ODOTTYPE, s.facename, nil)
b.Type = t.Left.Type // interface.(type)
a.Rlist.Set1(b)
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
a = typecheck(a, ctxStmt)
a = walkexpr(a, &init)
init.Append(a)
c := nod(OIF, nil, nil)
c.Left = s.okname
c.Nbody.Set1(t.Right) // if ok { goto l }
init.Append(c)
return init.asblock()
}
// walkCases generates an AST implementing the cases in cc.
func (s *typeSwitch) walkCases(cc []caseClause) *Node {
if len(cc) < binarySearchMin {
var cas []*Node
for _, c := range cc {
n := c.node
if !c.isconst {
Fatalf("typeSwitch walkCases")
}
a := nod(OIF, nil, nil)
a.Left = nod(OEQ, s.hashname, nodintconst(int64(c.hash)))
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
a.Left = typecheck(a.Left, ctxExpr)
a.Left = defaultlit(a.Left, nil)
a.Nbody.Set1(n.Right)
cas = append(cas, a)
}
return liststmt(cas)
}
// find the middle and recur
half := len(cc) / 2
a := nod(OIF, nil, nil)
a.Left = nod(OLE, s.hashname, nodintconst(int64(cc[half-1].hash)))
cmd/compile: bulk rename This change does a bulk rename of several identifiers in the compiler. See #27167 and https://docs.google.com/document/d/19_ExiylD9MRfeAjKIfEsMU1_RGhuxB9sA0b5Zv7byVI/ for context and for discussion of these particular renames. Commands run to generate this change: gorename -from '"cmd/compile/internal/gc".OPROC' -to OGO gorename -from '"cmd/compile/internal/gc".OCOM' -to OBITNOT gorename -from '"cmd/compile/internal/gc".OMINUS' -to ONEG gorename -from '"cmd/compile/internal/gc".OIND' -to ODEREF gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTR' -to OBYTES2STR gorename -from '"cmd/compile/internal/gc".OARRAYBYTESTRTMP' -to OBYTES2STRTMP gorename -from '"cmd/compile/internal/gc".OARRAYRUNESTR' -to ORUNES2STR gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTE' -to OSTR2BYTES gorename -from '"cmd/compile/internal/gc".OSTRARRAYBYTETMP' -to OSTR2BYTESTMP gorename -from '"cmd/compile/internal/gc".OSTRARRAYRUNE' -to OSTR2RUNES gorename -from '"cmd/compile/internal/gc".Etop' -to ctxStmt gorename -from '"cmd/compile/internal/gc".Erv' -to ctxExpr gorename -from '"cmd/compile/internal/gc".Ecall' -to ctxCallee gorename -from '"cmd/compile/internal/gc".Efnstruct' -to ctxMultiOK gorename -from '"cmd/compile/internal/gc".Easgn' -to ctxAssign gorename -from '"cmd/compile/internal/gc".Ecomplit' -to ctxCompLit Not altered: parameters and local variables (mostly in typecheck.go) named top, which should probably now be called ctx (and which should probably have a named type). Also not altered: Field called Top in gc.Func. gorename -from '"cmd/compile/internal/gc".Node.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/gc".Node.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/gc".nodeIsddd' -to nodeIsDDD gorename -from '"cmd/compile/internal/types".Field.Isddd' -to IsDDD gorename -from '"cmd/compile/internal/types".Field.SetIsddd' -to SetIsDDD gorename -from '"cmd/compile/internal/types".fieldIsddd' -to fieldIsDDD Not altered: function gc.hasddd, params and local variables called isddd Also not altered: fmt.go prints nodes using "isddd(%v)". cd cmd/compile/internal/gc; go generate I then manually found impacted comments using exact string match and fixed them up by hand. The comment changes were trivial. Passes toolstash-check. Fixes #27167. If this experiment is deemed a success, we will open a new tracking issue for renames to do at the end of the 1.13 cycles. Change-Id: I2dc541533d2ab0d06cb3d31d65df205ecfb151e8 Reviewed-on: https://go-review.googlesource.com/c/150140 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-11-18 08:34:38 -08:00
a.Left = typecheck(a.Left, ctxExpr)
a.Left = defaultlit(a.Left, nil)
a.Nbody.Set1(s.walkCases(cc[:half]))
a.Rlist.Set1(s.walkCases(cc[half:]))
return a
}
// caseClauseByConstVal sorts clauses by constant value to enable binary search.
type caseClauseByConstVal []caseClause
func (x caseClauseByConstVal) Len() int { return len(x) }
func (x caseClauseByConstVal) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x caseClauseByConstVal) Less(i, j int) bool {
// n1 and n2 might be individual constants or integer ranges.
// We have checked for duplicates already,
// so ranges can be safely represented by any value in the range.
n1 := x[i].node
var v1 interface{}
if s := n1.List.Slice(); s != nil {
v1 = s[0].Val().U
} else {
v1 = n1.Left.Val().U
}
n2 := x[j].node
var v2 interface{}
if s := n2.List.Slice(); s != nil {
v2 = s[0].Val().U
} else {
v2 = n2.Left.Val().U
}
switch v1 := v1.(type) {
case *Mpflt:
return v1.Cmp(v2.(*Mpflt)) < 0
case *Mpint:
return v1.Cmp(v2.(*Mpint)) < 0
case string:
// Sort strings by length and then by value.
// It is much cheaper to compare lengths than values,
// and all we need here is consistency.
// We respect this sorting in exprSwitch.walkCases.
a := v1
b := v2.(string)
if len(a) != len(b) {
return len(a) < len(b)
}
return a < b
}
Fatalf("caseClauseByConstVal passed bad clauses %v < %v", x[i].node.Left, x[j].node.Left)
return false
}
type caseClauseByType []caseClause
func (x caseClauseByType) Len() int { return len(x) }
func (x caseClauseByType) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x caseClauseByType) Less(i, j int) bool {
c1, c2 := x[i], x[j]
// sort by hash code, then ordinal (for the rare case of hash collisions)
if c1.hash != c2.hash {
return c1.hash < c2.hash
}
return c1.ordinal < c2.ordinal
}
type constIntNodesByVal []*Node
func (x constIntNodesByVal) Len() int { return len(x) }
func (x constIntNodesByVal) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x constIntNodesByVal) Less(i, j int) bool {
return x[i].Val().U.(*Mpint).Cmp(x[j].Val().U.(*Mpint)) < 0
}