Skip to content

Commit

Permalink
cmd/compile: do more type conversion inline
Browse files Browse the repository at this point in the history
The code to do the conversion is smaller than the
call to the runtime.
The 1-result asserts need to call panic if they fail, but that
code is out of line.

The only conversions left in the runtime are those which
might allocate and those which might need to generate an itab.

Given the following types:
  type E interface{}
  type I interface { foo() }
  type I2 iterface { foo(); bar() }
  type Big [10]int
  func (b Big) foo() { ... }

This CL inlines the following conversions:

was assertE2T
  var e E = ...
  b := i.(Big)
was assertE2T2
  var e E = ...
  b, ok := i.(Big)
was assertI2T
  var i I = ...
  b := i.(Big)
was assertI2T2
  var i I = ...
  b, ok := i.(Big)
was assertI2E
  var i I = ...
  e := i.(E)
was assertI2E2
  var i I = ...
  e, ok := i.(E)

These are the remaining runtime calls:

convT2E:
  var b Big = ...
  var e E = b
convT2I:
  var b Big = ...
  var i I = b
convI2I:
  var i2 I2 = ...
  var i I = i2
assertE2I:
  var e E = ...
  i := e.(I)
assertE2I2:
  var e E = ...
  i, ok := e.(I)
assertI2I:
  var i I = ...
  i2 := i.(I2)
assertI2I2:
  var i I = ...
  i2, ok := i.(I2)

Fixes #17405
Fixes #8422

Change-Id: Ida2367bf8ce3cd2c6bb599a1814f1d275afabe21
Reviewed-on: https://go-review.googlesource.com/32313
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
  • Loading branch information
randall77 committed Nov 2, 2016
1 parent 761443e commit 688995d
Show file tree
Hide file tree
Showing 14 changed files with 375 additions and 464 deletions.
130 changes: 61 additions & 69 deletions src/cmd/compile/internal/gc/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,12 @@ var runtimeDecls = [...]struct {
{"convI2I", funcTag, 53},
{"convT2E", funcTag, 54},
{"convT2I", funcTag, 54},
{"assertE2E", funcTag, 55},
{"assertE2E2", funcTag, 56},
{"assertE2I", funcTag, 55},
{"assertE2I2", funcTag, 56},
{"assertE2T", funcTag, 55},
{"assertE2T2", funcTag, 56},
{"assertI2E", funcTag, 55},
{"assertI2E2", funcTag, 56},
{"assertI2I", funcTag, 55},
{"assertI2I2", funcTag, 56},
{"assertI2T", funcTag, 55},
{"assertI2T2", funcTag, 56},
{"panicdottype", funcTag, 57},
{"assertE2I", funcTag, 53},
{"assertE2I2", funcTag, 55},
{"assertI2I", funcTag, 53},
{"assertI2I2", funcTag, 55},
{"panicdottype", funcTag, 56},
{"panicnildottype", funcTag, 57},
{"ifaceeq", funcTag, 58},
{"efaceeq", funcTag, 58},
{"makemap", funcTag, 60},
Expand Down Expand Up @@ -97,43 +90,43 @@ var runtimeDecls = [...]struct {
{"selectrecv", funcTag, 73},
{"selectrecv2", funcTag, 86},
{"selectdefault", funcTag, 87},
{"selectgo", funcTag, 88},
{"selectgo", funcTag, 57},
{"block", funcTag, 5},
{"makeslice", funcTag, 90},
{"makeslice64", funcTag, 91},
{"growslice", funcTag, 92},
{"memmove", funcTag, 93},
{"memclrNoHeapPointers", funcTag, 94},
{"memclrHasPointers", funcTag, 94},
{"memequal", funcTag, 95},
{"memequal8", funcTag, 96},
{"memequal16", funcTag, 96},
{"memequal32", funcTag, 96},
{"memequal64", funcTag, 96},
{"memequal128", funcTag, 96},
{"int64div", funcTag, 97},
{"uint64div", funcTag, 98},
{"int64mod", funcTag, 97},
{"uint64mod", funcTag, 98},
{"float64toint64", funcTag, 99},
{"float64touint64", funcTag, 100},
{"float64touint32", funcTag, 102},
{"int64tofloat64", funcTag, 103},
{"uint64tofloat64", funcTag, 104},
{"uint32tofloat64", funcTag, 105},
{"complex128div", funcTag, 106},
{"racefuncenter", funcTag, 107},
{"makeslice", funcTag, 89},
{"makeslice64", funcTag, 90},
{"growslice", funcTag, 91},
{"memmove", funcTag, 92},
{"memclrNoHeapPointers", funcTag, 93},
{"memclrHasPointers", funcTag, 93},
{"memequal", funcTag, 94},
{"memequal8", funcTag, 95},
{"memequal16", funcTag, 95},
{"memequal32", funcTag, 95},
{"memequal64", funcTag, 95},
{"memequal128", funcTag, 95},
{"int64div", funcTag, 96},
{"uint64div", funcTag, 97},
{"int64mod", funcTag, 96},
{"uint64mod", funcTag, 97},
{"float64toint64", funcTag, 98},
{"float64touint64", funcTag, 99},
{"float64touint32", funcTag, 101},
{"int64tofloat64", funcTag, 102},
{"uint64tofloat64", funcTag, 103},
{"uint32tofloat64", funcTag, 104},
{"complex128div", funcTag, 105},
{"racefuncenter", funcTag, 106},
{"racefuncexit", funcTag, 5},
{"raceread", funcTag, 107},
{"racewrite", funcTag, 107},
{"racereadrange", funcTag, 108},
{"racewriterange", funcTag, 108},
{"msanread", funcTag, 108},
{"msanwrite", funcTag, 108},
{"raceread", funcTag, 106},
{"racewrite", funcTag, 106},
{"racereadrange", funcTag, 107},
{"racewriterange", funcTag, 107},
{"msanread", funcTag, 107},
{"msanwrite", funcTag, 107},
}

func runtimeTypes() []*Type {
var typs [109]*Type
var typs [108]*Type
typs[0] = bytetype
typs[1] = typPtr(typs[0])
typs[2] = Types[TANY]
Expand Down Expand Up @@ -189,9 +182,9 @@ func runtimeTypes() []*Type {
typs[52] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[33])})
typs[53] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
typs[54] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
typs[55] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[3])}, nil)
typs[56] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[3])}, []*Node{anonfield(typs[13])})
typs[57] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
typs[55] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[13])})
typs[56] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
typs[57] = functype(nil, []*Node{anonfield(typs[1])}, nil)
typs[58] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[13])})
typs[59] = typMap(typs[2], typs[2])
typs[60] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17]), anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[59])})
Expand Down Expand Up @@ -222,26 +215,25 @@ func runtimeTypes() []*Type {
typs[85] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17]), anonfield(typs[10])}, nil)
typs[86] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[71]), anonfield(typs[3]), anonfield(typs[83])}, []*Node{anonfield(typs[13])})
typs[87] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[13])})
typs[88] = functype(nil, []*Node{anonfield(typs[1])}, nil)
typs[89] = typSlice(typs[2])
typs[90] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[33]), anonfield(typs[33])}, []*Node{anonfield(typs[89])})
typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[89])})
typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[89]), anonfield(typs[33])}, []*Node{anonfield(typs[89])})
typs[93] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[50])}, nil)
typs[94] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[50])}, nil)
typs[95] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[50])}, []*Node{anonfield(typs[13])})
typs[96] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[13])})
typs[97] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])})
typs[98] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
typs[99] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[17])})
typs[100] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[19])})
typs[101] = Types[TUINT32]
typs[102] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[101])})
typs[103] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[15])})
typs[104] = functype(nil, []*Node{anonfield(typs[19])}, []*Node{anonfield(typs[15])})
typs[105] = functype(nil, []*Node{anonfield(typs[101])}, []*Node{anonfield(typs[15])})
typs[106] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
typs[107] = functype(nil, []*Node{anonfield(typs[50])}, nil)
typs[108] = functype(nil, []*Node{anonfield(typs[50]), anonfield(typs[50])}, nil)
typs[88] = typSlice(typs[2])
typs[89] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[33]), anonfield(typs[33])}, []*Node{anonfield(typs[88])})
typs[90] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[88])})
typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[88]), anonfield(typs[33])}, []*Node{anonfield(typs[88])})
typs[92] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[50])}, nil)
typs[93] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[50])}, nil)
typs[94] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[50])}, []*Node{anonfield(typs[13])})
typs[95] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[13])})
typs[96] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])})
typs[97] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
typs[98] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[17])})
typs[99] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[19])})
typs[100] = Types[TUINT32]
typs[101] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[100])})
typs[102] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[15])})
typs[103] = functype(nil, []*Node{anonfield(typs[19])}, []*Node{anonfield(typs[15])})
typs[104] = functype(nil, []*Node{anonfield(typs[100])}, []*Node{anonfield(typs[15])})
typs[105] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
typs[106] = functype(nil, []*Node{anonfield(typs[50])}, nil)
typs[107] = functype(nil, []*Node{anonfield(typs[50]), anonfield(typs[50])}, nil)
return typs[:]
}
17 changes: 5 additions & 12 deletions src/cmd/compile/internal/gc/builtin/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,12 @@ func convT2E(typ *byte, elem *any) (ret any)
func convT2I(tab *byte, elem *any) (ret any)

// interface type assertions x.(T)
func assertE2E(typ *byte, iface any, ret *any)
func assertE2E2(typ *byte, iface any, ret *any) bool
func assertE2I(typ *byte, iface any, ret *any)
func assertE2I2(typ *byte, iface any, ret *any) bool
func assertE2T(typ *byte, iface any, ret *any)
func assertE2T2(typ *byte, iface any, ret *any) bool
func assertI2E(typ *byte, iface any, ret *any)
func assertI2E2(typ *byte, iface any, ret *any) bool
func assertI2I(typ *byte, iface any, ret *any)
func assertI2I2(typ *byte, iface any, ret *any) bool
func assertI2T(typ *byte, iface any, ret *any)
func assertI2T2(typ *byte, iface any, ret *any) bool
func assertE2I(typ *byte, iface any) (ret any)
func assertE2I2(typ *byte, iface any) (ret any, b bool)
func assertI2I(typ *byte, iface any) (ret any)
func assertI2I2(typ *byte, iface any) (ret any, b bool)
func panicdottype(have, want, iface *byte)
func panicnildottype(want *byte)

func ifaceeq(i1 any, i2 any) (ret bool)
func efaceeq(i1 any, i2 any) (ret bool)
Expand Down
30 changes: 15 additions & 15 deletions src/cmd/compile/internal/gc/go.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,18 +363,18 @@ var pcloc int32

var Thearch Arch

var Newproc *Node

var Deferproc *Node

var Deferreturn *Node

var panicindex *Node

var panicslice *Node

var panicdivide *Node

var growslice *Node

var panicdottype *Node
var (
Newproc,
Deferproc,
Deferreturn,
panicindex,
panicslice,
panicdivide,
growslice,
panicdottype,
panicnildottype,
assertE2I,
assertE2I2,
assertI2I,
assertI2I2 *Node
)
5 changes: 5 additions & 0 deletions src/cmd/compile/internal/gc/pgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,11 @@ func compile(fn *Node) {
panicdivide = Sysfunc("panicdivide")
growslice = Sysfunc("growslice")
panicdottype = Sysfunc("panicdottype")
panicnildottype = Sysfunc("panicnildottype")
assertE2I = Sysfunc("assertE2I")
assertE2I2 = Sysfunc("assertE2I2")
assertI2I = Sysfunc("assertI2I")
assertI2I2 = Sysfunc("assertI2I2")
}

defer func(lno int32) {
Expand Down
12 changes: 9 additions & 3 deletions src/cmd/compile/internal/gc/racewalk.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,15 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) {
instrumentnode(&n.Left, init, 0, 0)
goto ret

case OAS2DOTTYPE:
instrumentnode(&n.Left, init, 1, 0)
instrumentnode(&n.Right, init, 0, 0)
goto ret

case ODOTTYPE, ODOTTYPE2:
instrumentnode(&n.Left, init, 0, 0)
goto ret

// should not appear in AST by now
case OSEND,
ORECV,
Expand Down Expand Up @@ -345,9 +354,6 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) {
// lowered to call
OCMPSTR,
OADDSTR,
ODOTTYPE,
ODOTTYPE2,
OAS2DOTTYPE,
OCALLPART,
// lowered to PTRLIT
OCLOSURE, // lowered to PTRLIT
Expand Down
Loading

0 comments on commit 688995d

Please sign in to comment.