cmd/compile: inline convT2{I,E} when result doesn't escape

No point in calling a function when we can build the interface
using a known type (or itab) and the address of a local.

Get rid of third arg (preallocated stack space) to convT2{I,E}.

Makes go binary smaller by 0.2%

benchmark                   old ns/op     new ns/op     delta
BenchmarkEfaceInteger-8     16.7          10.1          -39.52%

Update #17118
Update #15375

Change-Id: I9724a1f802bfa1e3957bf1856b55558278e198a2
Reviewed-on: https://go-review.googlesource.com/29373
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Keith Randall 2016-09-17 15:04:36 -07:00
parent 892d146a7a
commit 6129f37367
7 changed files with 235 additions and 106 deletions

View file

@ -28,82 +28,81 @@ const runtimeimport = "" +
"\x00\x00:\tfr·3\x00\x00\x16\vwid·4\x00\x1bunsafe-uintptr\x01\x02\x00\t\x1d" +
"slicestringcopy\x00\x04:X\x00\x00:Z\x00\x00\x01\x02\x00\t\rconvI2E\x00\x02:" +
"\relem·2\x00\x00\x02:\vret·1\x00\x00\t\rconvI2I\x00\x04\x17\"\x06\x00\x00:\re" +
"lem·3\x00\x00\x02:f\x00\x00\t\rconvT2E\x00\x06\x17\"\x06\x00\x00\x17:j\x00\x00\x17:\vbuf" +
"·4\x00\x00\x02:f\x00\x00\t\rconvT2I\x00\x06\x17\"\vtab·2\x00\x00\x17:j\x00\x00\x17:n" +
"\x00\x00\x02:f\x00\x00\t\x11assertE2E\x00\x06\x17\"\vtyp·1\x00\x00:\x0fiface·" +
"2\x00\x00\x17:\vret·3\x00\x00\x00\t\x13assertE2E2\x00\x06\x17\"\x06\x00\x00:\x0fifac" +
"e·3\x00\x00\x17:\vret·4\x00\x00\x01\x00\x00\t\x11assertE2I\x00\x06\x17\"v\x00\x00:x" +
"\x00\x00\x17:z\x00\x00\x00\t\x13assertE2I2\x00\x06\x17\"\x06\x00\x00:~\x00\x00\x17:\x80\x01\x00\x00\x01\x00\x00" +
"\t\x11assertE2T\x00\x06\x17\"v\x00\x00:x\x00\x00\x17:z\x00\x00\x00\t\x13assertE2T2" +
"\x00\x06\x17\"\x06\x00\x00:~\x00\x00\x17:\x80\x01\x00\x00\x01\x00\x00\t\x11assertI2E\x00\x06\x17\"v\x00\x00:x" +
"\x00\x00\x17:z\x00\x00\x00\t\x13assertI2E2\x00\x06\x17\"\x06\x00\x00:~\x00\x00\x17:\x80\x01\x00\x00\x01\x00\x00" +
"\t\x11assertI2I\x00\x06\x17\"v\x00\x00:x\x00\x00\x17:z\x00\x00\x00\t\x13assertI2I2" +
"\x00\x06\x17\"\x06\x00\x00:~\x00\x00\x17:\x80\x01\x00\x00\x01\x00\x00\t\x11assertI2T\x00\x06\x17\"v\x00\x00:x" +
"\x00\x00\x17:z\x00\x00\x00\t\x13assertI2T2\x00\x06\x17\"\x06\x00\x00:~\x00\x00\x17:\x80\x01\x00\x00\x01\x00\x00" +
"\t\x17panicdottype\x00\x06\x17\"\rhave·1\x00\x00\x17\"\rwant·2\x00\x00" +
"\x17\"~\x00\x00\x00\t\rifaceeq\x00\x04:\ti1·2\x00\x00:\ti2·3\x00\x00\x02\x00f\x00\x00" +
"\t\refaceeq\x00\x04:\x9e\x01\x00\x00:\xa0\x01\x00\x00\x02\x00f\x00\x00\t\rmakemap\x00\b\x17\"\x13" +
"mapType·2\x00\x00\n\rhint·3\x00\x00\x17:\x11mapbuf·4\x00\x00\x17:\x17" +
"bucketbuf·5\x00\x00\x02\x1d::\rhmap·1\x00\x00\t\x13mapaccess1" +
"\x00\x06\x17\"\xa6\x01\x00\x00\x1d::\rhmap·3\x00\x00\x17:\vkey·4\x00\x00\x02\x17:\vval\xc2" +
"\xb71\x00\x00\t!mapaccess1_fast32\x00\x06\x17\"\xa6\x01\x00\x00\x1d::\xb2\x01\x00\x00:\xb4" +
"\x01\x00\x00\x02\x17:\xb6\x01\x00\x00\t!mapaccess1_fast64\x00\x06\x17\"\xa6\x01\x00\x00\x1d::" +
"\xb2\x01\x00\x00:\xb4\x01\x00\x00\x02\x17:\xb6\x01\x00\x00\t#mapaccess1_faststr\x00\x06\x17\"" +
"\xa6\x01\x00\x00\x1d::\xb2\x01\x00\x00:\xb4\x01\x00\x00\x02\x17:\xb6\x01\x00\x00\t\x1bmapaccess1_fat\x00" +
"\b\x17\"\xa6\x01\x00\x00\x1d::\xb2\x01\x00\x00\x17:\xb4\x01\x00\x00\x17\"\rzero·5\x00\x00\x02\x17:\xb6\x01\x00\x00\t" +
"\x13mapaccess2\x00\x06\x17\"\x13mapType·3\x00\x00\x1d::\rhmap·4\x00" +
"\x00\x17:\vkey·5\x00\x00\x04\x17:\xb6\x01\x00\x00\x00\rpres·2\x00\x00\t!mapacces" +
"s2_fast32\x00\x06\x17\"\xc4\x01\x00\x00\x1d::\xc6\x01\x00\x00:\xc8\x01\x00\x00\x04\x17:\xb6\x01\x00\x00\x00\xca\x01\x00" +
"\x00\t!mapaccess2_fast64\x00\x06\x17\"\xc4\x01\x00\x00\x1d::\xc6\x01\x00\x00:\xc8\x01\x00\x00" +
"\x04\x17:\xb6\x01\x00\x00\x00\xca\x01\x00\x00\t#mapaccess2_faststr\x00\x06\x17\"\xc4\x01\x00\x00" +
"\x1d::\xc6\x01\x00\x00:\xc8\x01\x00\x00\x04\x17:\xb6\x01\x00\x00\x00\xca\x01\x00\x00\t\x1bmapaccess2_fat" +
"\x00\b\x17\"\xc4\x01\x00\x00\x1d::\xc6\x01\x00\x00\x17:\xc8\x01\x00\x00\x17\"\rzero·6\x00\x00\x04\x17:\xb6\x01\x00\x00" +
"\x00\xca\x01\x00\x00\t\x13mapassign1\x00\b\x17\"\x13mapType·1\x00\x00\x1d::\rhm" +
"ap·2\x00\x00\x17:\vkey·3\x00\x00\x17:\vval·4\x00\x00\x00\t\x15mapiteri" +
"nit\x00\x06\x17\"\xd8\x01\x00\x00\x1d::\xda\x01\x00\x00\x17:\x0fhiter·3\x00\x00\x00\t\x11mapdel" +
"ete\x00\x06\x17\"\xd8\x01\x00\x00\x1d::\xda\x01\x00\x00\x17:\xdc\x01\x00\x00\x00\t\x15mapiternext\x00\x02" +
"\x17:\x0fhiter·1\x00\x00\x00\t\x0fmakechan\x00\x04\x17\"\x15chanType·2" +
"\x00\x00\n\xa8\x01\x00\x00\x02\x1f\x06:\x0fhchan·1\x00\x00\t\x11chanrecv1\x00\x06\x17\"\x15ch" +
"anType·1\x00\x00\x1f\x02:\x0fhchan·2\x00\x00\x17:j\x00\x00\x00\t\x11chanrec" +
"v2\x00\x06\x17\"\xec\x01\x00\x00\x1f\x02:\x0fhchan·3\x00\x00\x17:\relem·4\x00\x00\x01\x00\x00\t" +
"\x11chansend1\x00\x06\x17\"\xf2\x01\x00\x00\x1f\x04:\xf4\x01\x00\x00\x17:j\x00\x00\x00\t\x11closech" +
"an\x00\x02:\xee\x01\x00\x00\x00\a\x17writeBarrier\x00\x15\x06\renabled\x00\x00\x00\vn" +
"eeded\x00\x00\x00\x05cgo\x00\x00\x00\t\x1dwritebarrierptr\x00\x04\x17:\vdst" +
"·1\x00\x00:\vsrc·2\x00\x00\x00\t\x17typedmemmove\x00\x06\x17\"v\x00\x00\x17:\v" +
"dst·2\x00\x00\x17:\vsrc·3\x00\x00\x00\t\x1btypedslicecopy\x00\x06\x17\"" +
"\x06\x00\x00:\vdst·3\x00\x00:\vsrc·4\x00\x00\x01\x02\x00\t\x17selectnbsend" +
"\x00\x06\x17\"\xec\x01\x00\x00\x1f\x04:\xf8\x01\x00\x00\x17:\xfa\x01\x00\x00\x01\x00\x00\t\x17selectnbrecv\x00\x06" +
"\x17\"\xec\x01\x00\x00\x17:j\x00\x00\x1f\x02:\x0fhchan·4\x00\x00\x01\x00\x00\t\x19selectnbre" +
"cv2\x00\b\x17\"\xec\x01\x00\x00\x17:j\x00\x00\x17\x00\x15received·4\x00\x00\x1f\x02:\x0fhcha" +
"n·5\x00\x00\x01\x00\x00\t\x11newselect\x00\x06\x17\"\vsel·1\x00\x00\n\x13selsi" +
"ze·2\x00\x00\b\rsize·3\x00\x00\x00\t\x13selectsend\x00\x06\x17\"\vsel\xc2" +
"\xb72\x00\x00\x1f\x04:\xf8\x01\x00\x00\x17:\xfa\x01\x00\x00\x02\x00\x15selected·1\x00\x00\t\x13selec" +
"trecv\x00\x06\x17\"\xb0\x02\x00\x00\x1f\x02:\xf8\x01\x00\x00\x17:\xfa\x01\x00\x00\x02\x00\xb2\x02\x00\x00\t\x15select" +
"recv2\x00\b\x17\"\xb0\x02\x00\x00\x1f\x02:\xf8\x01\x00\x00\x17:\xfa\x01\x00\x00\x17\x00\x15received·5" +
"\x00\x00\x02\x00\xb2\x02\x00\x00\t\x19selectdefault\x00\x02\x17\"\xb0\x02\x00\x00\x02\x00\xb2\x02\x00\x00\t\x0fs" +
"electgo\x00\x02\x17\"\xa8\x02\x00\x00\x00\t\tblock\x00\x00\x00\t\x11makeslice\x00\x06\x17" +
"\"\x06\x00\x00\x02\vlen·3\x00\x00\x02\vcap·4\x00\x00\x02\x11:\vary·1\x00\x00\t\x15ma" +
"keslice64\x00\x06\x17\"\x06\x00\x00\n\xc2\x02\x00\x00\n\xc4\x02\x00\x00\x02\x11:\xc6\x02\x00\x00\t\x11grows" +
"lice\x00\x06\x17\"\x06\x00\x00\x11:\vold·3\x00\x00\x02\xc4\x02\x00\x00\x02\x11:\xc6\x02\x00\x00\t\rmemm" +
"ove\x00\x06\x17:\tto·1\x00\x00\x17:\vfrm·2\x00\x00\x16\x11length·3\x00^\x00" +
"\t\vmemclr\x00\x04\x17\"\vptr·1\x00\x00\x16\x11length·2\x00^\x00\t\x0fmem" +
"equal\x00\x06\x17:\ax·2\x00\x00\x17:\ay·3\x00\x00\x16\rsize·4\x00^\x01\x00\x00\t" +
"\x11memequal8\x00\x04\x17:\xde\x02\x00\x00\x17:\xe0\x02\x00\x00\x01\x00\x00\t\x13memequal16\x00" +
"\x04\x17:\xde\x02\x00\x00\x17:\xe0\x02\x00\x00\x01\x00\x00\t\x13memequal32\x00\x04\x17:\xde\x02\x00\x00\x17:\xe0\x02" +
"\x00\x00\x01\x00\x00\t\x13memequal64\x00\x04\x17:\xde\x02\x00\x00\x17:\xe0\x02\x00\x00\x01\x00\x00\t\x15meme" +
"qual128\x00\x04\x17:\xde\x02\x00\x00\x17:\xe0\x02\x00\x00\x01\x00\x00\t\x0fint64div\x00\x03\n\x00\n\x00" +
"\x01\n\x00\t\x11uint64div\x00\x03\x14\x00\x14\x00\x01\x14\x00\t\x0fint64mod\x00\x03\n\x00\n\x00\x01" +
"\n\x00\t\x11uint64mod\x00\x03\x14\x00\x14\x00\x01\x14\x00\t\x1bfloat64toint64\x00\x01" +
"\x1a\x00\x01\n\x00\t\x1dfloat64touint64\x00\x01\x1a\x00\x01\x14\x00\t\x1dfloat64to" +
"uint32\x00\x01\x1a\x00\x01\x12\x00\t\x1bint64tofloat64\x00\x01\n\x00\x01\x1a\x00\t\x1dui" +
"nt64tofloat64\x00\x01\x14\x00\x01\x1a\x00\t\x1duint32tofloat64\x00\x01\x12" +
"\x00\x01\x1a\x00\t\x19complex128div\x00\x04\x1e\vnum·2\x00\x00\x1e\vden·3\x00" +
"\x00\x02\x1e\vquo·1\x00\x00\t\x19racefuncenter\x00\x01\x16^\x00\t\x17racefu" +
"ncexit\x00\x00\x00\t\x0fraceread\x00\x01\x16^\x00\t\x11racewrite\x00\x01\x16^\x00" +
"\t\x19racereadrange\x00\x04\x16\raddr·1\x00^\x16\rsize·2\x00^\x00" +
"\t\x1bracewriterange\x00\x04\x16\x94\x03\x00^\x16\x96\x03\x00^\x00\t\x0fmsanread\x00" +
"\x04\x16\x94\x03\x00^\x16\x96\x03\x00^\x00\t\x11msanwrite\x00\x04\x16\x94\x03\x00^\x16\x96\x03\x00^\x00\v\xf6\x01\v" +
"\x00\x01\x00\n$$\n"
"lem·3\x00\x00\x02:f\x00\x00\t\rconvT2E\x00\x04\x17\"\x06\x00\x00\x17:j\x00\x00\x02:f\x00\x00\t" +
"\rconvT2I\x00\x04\x17\"\vtab·2\x00\x00\x17:j\x00\x00\x02:f\x00\x00\t\x11assertE" +
"2E\x00\x06\x17\"\vtyp·1\x00\x00:\x0fiface·2\x00\x00\x17:\vret·3\x00\x00\x00\t" +
"\x13assertE2E2\x00\x06\x17\"\x06\x00\x00:\x0fiface·3\x00\x00\x17:\vret·4\x00" +
"\x00\x01\x00\x00\t\x11assertE2I\x00\x06\x17\"t\x00\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assert" +
"E2I2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00\x00\x01\x00\x00\t\x11assertE2T\x00\x06\x17\"t" +
"\x00\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assertE2T2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00" +
"\x00\x01\x00\x00\t\x11assertI2E\x00\x06\x17\"t\x00\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assert" +
"I2E2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00\x00\x01\x00\x00\t\x11assertI2I\x00\x06\x17\"t" +
"\x00\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assertI2I2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00" +
"\x00\x01\x00\x00\t\x11assertI2T\x00\x06\x17\"t\x00\x00:v\x00\x00\x17:x\x00\x00\x00\t\x13assert" +
"I2T2\x00\x06\x17\"\x06\x00\x00:||\x00\x00\x17:~\x00\x00\x01\x00\x00\t\x17panicdottype\x00\x06" +
"\x17\"\rhave·1\x00\x00\x17\"\rwant·2\x00\x00\x17\"||\x00\x00\x00\t\rifaceeq" +
"\x00\x04:\ti1·2\x00\x00:\ti2·3\x00\x00\x02\x00f\x00\x00\t\refaceeq\x00\x04:\x9c\x01\x00" +
"\x00:\x9e\x01\x00\x00\x02\x00f\x00\x00\t\rmakemap\x00\b\x17\"\x13mapType·2\x00\x00\n\rh" +
"int·3\x00\x00\x17:\x11mapbuf·4\x00\x00\x17:\x17bucketbuf·5\x00\x00\x02" +
"\x1d::\rhmap·1\x00\x00\t\x13mapaccess1\x00\x06\x17\"\xa4\x01\x00\x00\x1d::\rhma" +
"p·3\x00\x00\x17:\vkey·4\x00\x00\x02\x17:\vval·1\x00\x00\t!mapaccess" +
"1_fast32\x00\x06\x17\"\xa4\x01\x00\x00\x1d::\xb0\x01\x00\x00:\xb2\x01\x00\x00\x02\x17:\xb4\x01\x00\x00\t!map" +
"access1_fast64\x00\x06\x17\"\xa4\x01\x00\x00\x1d::\xb0\x01\x00\x00:\xb2\x01\x00\x00\x02\x17:\xb4\x01\x00" +
"\x00\t#mapaccess1_faststr\x00\x06\x17\"\xa4\x01\x00\x00\x1d::\xb0\x01\x00\x00:\xb2\x01\x00" +
"\x00\x02\x17:\xb4\x01\x00\x00\t\x1bmapaccess1_fat\x00\b\x17\"\xa4\x01\x00\x00\x1d::\xb0\x01\x00\x00\x17" +
":\xb2\x01\x00\x00\x17\"\rzero·5\x00\x00\x02\x17:\xb4\x01\x00\x00\t\x13mapaccess2\x00\x06\x17\"" +
"\x13mapType·3\x00\x00\x1d::\rhmap·4\x00\x00\x17:\vkey·5\x00\x00\x04\x17:" +
"\xb4\x01\x00\x00\x00\rpres·2\x00\x00\t!mapaccess2_fast32\x00\x06\x17\"\xc2\x01" +
"\x00\x00\x1d::\xc4\x01\x00\x00:\xc6\x01\x00\x00\x04\x17:\xb4\x01\x00\x00\x00\xc8\x01\x00\x00\t!mapaccess2_f" +
"ast64\x00\x06\x17\"\xc2\x01\x00\x00\x1d::\xc4\x01\x00\x00:\xc6\x01\x00\x00\x04\x17:\xb4\x01\x00\x00\x00\xc8\x01\x00\x00\t#m" +
"apaccess2_faststr\x00\x06\x17\"\xc2\x01\x00\x00\x1d::\xc4\x01\x00\x00:\xc6\x01\x00\x00\x04\x17:" +
"\xb4\x01\x00\x00\x00\xc8\x01\x00\x00\t\x1bmapaccess2_fat\x00\b\x17\"\xc2\x01\x00\x00\x1d::\xc4\x01\x00\x00" +
"\x17:\xc6\x01\x00\x00\x17\"\rzero·6\x00\x00\x04\x17:\xb4\x01\x00\x00\x00\xc8\x01\x00\x00\t\x13mapassig" +
"n1\x00\b\x17\"\x13mapType·1\x00\x00\x1d::\rhmap·2\x00\x00\x17:\vkey·" +
"3\x00\x00\x17:\vval·4\x00\x00\x00\t\x15mapiterinit\x00\x06\x17\"\xd6\x01\x00\x00\x1d::\xd8" +
"\x01\x00\x00\x17:\x0fhiter·3\x00\x00\x00\t\x11mapdelete\x00\x06\x17\"\xd6\x01\x00\x00\x1d::\xd8" +
"\x01\x00\x00\x17:\xda\x01\x00\x00\x00\t\x15mapiternext\x00\x02\x17:\x0fhiter·1\x00\x00\x00\t" +
"\x0fmakechan\x00\x04\x17\"\x15chanType·2\x00\x00\n\xa6\x01\x00\x00\x02\x1f\x06:\x0fhch" +
"an·1\x00\x00\t\x11chanrecv1\x00\x06\x17\"\x15chanType·1\x00\x00\x1f\x02:\x0f" +
"hchan·2\x00\x00\x17:j\x00\x00\x00\t\x11chanrecv2\x00\x06\x17\"\xea\x01\x00\x00\x1f\x02:\x0fh" +
"chan·3\x00\x00\x17:\relem·4\x00\x00\x01\x00\x00\t\x11chansend1\x00\x06\x17\"\xf0" +
"\x01\x00\x00\x1f\x04:\xf2\x01\x00\x00\x17:j\x00\x00\x00\t\x11closechan\x00\x02:\xec\x01\x00\x00\x00\a\x17wri" +
"teBarrier\x00\x15\x06\renabled\x00\x00\x00\vneeded\x00\x00\x00\x05cgo\x00\x00\x00" +
"\t\x1dwritebarrierptr\x00\x04\x17:\vdst·1\x00\x00:\vsrc·2\x00\x00" +
"\x00\t\x17typedmemmove\x00\x06\x17\"t\x00\x00\x17:\vdst·2\x00\x00\x17:\vsrc\xc2" +
"\xb73\x00\x00\x00\t\x1btypedslicecopy\x00\x06\x17\"\x06\x00\x00:\vdst·3\x00\x00:\v" +
"src·4\x00\x00\x01\x02\x00\t\x17selectnbsend\x00\x06\x17\"\xea\x01\x00\x00\x1f\x04:\xf6\x01\x00\x00" +
"\x17:\xf8\x01\x00\x00\x01\x00\x00\t\x17selectnbrecv\x00\x06\x17\"\xea\x01\x00\x00\x17:j\x00\x00\x1f\x02:\x0f" +
"hchan·4\x00\x00\x01\x00\x00\t\x19selectnbrecv2\x00\b\x17\"\xea\x01\x00\x00\x17:j\x00" +
"\x00\x17\x00\x15received·4\x00\x00\x1f\x02:\x0fhchan·5\x00\x00\x01\x00\x00\t\x11news" +
"elect\x00\x06\x17\"\vsel·1\x00\x00\n\x13selsize·2\x00\x00\b\rsize·" +
"3\x00\x00\x00\t\x13selectsend\x00\x06\x17\"\vsel·2\x00\x00\x1f\x04:\xf6\x01\x00\x00\x17:\xf8\x01" +
"\x00\x00\x02\x00\x15selected·1\x00\x00\t\x13selectrecv\x00\x06\x17\"\xae\x02\x00\x00\x1f\x02" +
":\xf6\x01\x00\x00\x17:\xf8\x01\x00\x00\x02\x00\xb0\x02\x00\x00\t\x15selectrecv2\x00\b\x17\"\xae\x02\x00\x00\x1f\x02" +
":\xf6\x01\x00\x00\x17:\xf8\x01\x00\x00\x17\x00\x15received·5\x00\x00\x02\x00\xb0\x02\x00\x00\t\x19selec" +
"tdefault\x00\x02\x17\"\xae\x02\x00\x00\x02\x00\xb0\x02\x00\x00\t\x0fselectgo\x00\x02\x17\"\xa6\x02\x00\x00" +
"\x00\t\tblock\x00\x00\x00\t\x11makeslice\x00\x06\x17\"\x06\x00\x00\x02\vlen·3\x00\x00\x02" +
"\vcap·4\x00\x00\x02\x11:\vary·1\x00\x00\t\x15makeslice64\x00\x06\x17\"\x06\x00" +
"\x00\n\xc0\x02\x00\x00\n\xc2\x02\x00\x00\x02\x11:\xc4\x02\x00\x00\t\x11growslice\x00\x06\x17\"\x06\x00\x00\x11:\vo" +
"ld·3\x00\x00\x02\xc2\x02\x00\x00\x02\x11:\xc4\x02\x00\x00\t\rmemmove\x00\x06\x17:\tto·1\x00\x00" +
"\x17:\vfrm·2\x00\x00\x16\x11length·3\x00^\x00\t\vmemclr\x00\x04\x17\"\vpt" +
"r·1\x00\x00\x16\x11length·2\x00^\x00\t\x0fmemequal\x00\x06\x17:\ax·2\x00" +
"\x00\x17:\ay·3\x00\x00\x16\rsize·4\x00^\x01\x00\x00\t\x11memequal8\x00\x04\x17:\xdc" +
"\x02\x00\x00\x17:\xde\x02\x00\x00\x01\x00\x00\t\x13memequal16\x00\x04\x17:\xdc\x02\x00\x00\x17:\xde\x02\x00\x00\x01\x00" +
"\x00\t\x13memequal32\x00\x04\x17:\xdc\x02\x00\x00\x17:\xde\x02\x00\x00\x01\x00\x00\t\x13memequal" +
"64\x00\x04\x17:\xdc\x02\x00\x00\x17:\xde\x02\x00\x00\x01\x00\x00\t\x15memequal128\x00\x04\x17:\xdc\x02\x00\x00" +
"\x17:\xde\x02\x00\x00\x01\x00\x00\t\x0fint64div\x00\x03\n\x00\n\x00\x01\n\x00\t\x11uint64div\x00" +
"\x03\x14\x00\x14\x00\x01\x14\x00\t\x0fint64mod\x00\x03\n\x00\n\x00\x01\n\x00\t\x11uint64mod\x00\x03" +
"\x14\x00\x14\x00\x01\x14\x00\t\x1bfloat64toint64\x00\x01\x1a\x00\x01\n\x00\t\x1dfloat64t" +
"ouint64\x00\x01\x1a\x00\x01\x14\x00\t\x1dfloat64touint32\x00\x01\x1a\x00\x01\x12\x00\t\x1b" +
"int64tofloat64\x00\x01\n\x00\x01\x1a\x00\t\x1duint64tofloat64\x00\x01" +
"\x14\x00\x01\x1a\x00\t\x1duint32tofloat64\x00\x01\x12\x00\x01\x1a\x00\t\x19complex12" +
"8div\x00\x04\x1e\vnum·2\x00\x00\x1e\vden·3\x00\x00\x02\x1e\vquo·1\x00\x00\t\x19r" +
"acefuncenter\x00\x01\x16^\x00\t\x17racefuncexit\x00\x00\x00\t\x0frace" +
"read\x00\x01\x16^\x00\t\x11racewrite\x00\x01\x16^\x00\t\x19racereadrange" +
"\x00\x04\x16\raddr·1\x00^\x16\rsize·2\x00^\x00\t\x1bracewriterang" +
"e\x00\x04\x16\x92\x03\x00^\x16\x94\x03\x00^\x00\t\x0fmsanread\x00\x04\x16\x92\x03\x00^\x16\x94\x03\x00^\x00\t\x11m" +
"sanwrite\x00\x04\x16\x92\x03\x00^\x16\x94\x03\x00^\x00\v\xf6\x01\v\x00\x01\x00\n$$\n"
const unsafeimport = "" +
"version 2\n\n\x00\x00\x01\vunsafe\x00\t\x0fOffsetof\x00\x01:\x00\x01\x16\x00\t" +

View file

@ -60,8 +60,8 @@ func slicestringcopy(to any, fr any) int
// interface conversions
func convI2E(elem any) (ret any)
func convI2I(typ *byte, elem any) (ret any)
func convT2E(typ *byte, elem, buf *any) (ret any)
func convT2I(tab *byte, elem, buf *any) (ret any)
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)

View file

@ -18,7 +18,7 @@ func makeT() T {
var g T
var sink []byte
var sink interface{}
func TestIssue15854(t *testing.T) {
for i := 0; i < 10000; i++ {

View file

@ -0,0 +1,128 @@
// Copyright 2016 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
// Test to make sure we make copies of the values we
// put in interfaces.
import (
"testing"
)
var x int
func TestEfaceConv1(t *testing.T) {
a := 5
i := interface{}(a)
a += 2
if got := i.(int); got != 5 {
t.Errorf("wanted 5, got %d\n", got)
}
}
func TestEfaceConv2(t *testing.T) {
a := 5
sink = &a
i := interface{}(a)
a += 2
if got := i.(int); got != 5 {
t.Errorf("wanted 5, got %d\n", got)
}
}
func TestEfaceConv3(t *testing.T) {
x = 5
if got := e2int3(x); got != 5 {
t.Errorf("wanted 5, got %d\n", got)
}
}
//go:noinline
func e2int3(i interface{}) int {
x = 7
return i.(int)
}
func TestEfaceConv4(t *testing.T) {
a := 5
if got := e2int4(a, &a); got != 5 {
t.Errorf("wanted 5, got %d\n", got)
}
}
//go:noinline
func e2int4(i interface{}, p *int) int {
*p = 7
return i.(int)
}
type Int int
var y Int
type I interface {
foo()
}
func (i Int) foo() {
}
func TestIfaceConv1(t *testing.T) {
a := Int(5)
i := interface{}(a)
a += 2
if got := i.(Int); got != 5 {
t.Errorf("wanted 5, got %d\n", int(got))
}
}
func TestIfaceConv2(t *testing.T) {
a := Int(5)
sink = &a
i := interface{}(a)
a += 2
if got := i.(Int); got != 5 {
t.Errorf("wanted 5, got %d\n", int(got))
}
}
func TestIfaceConv3(t *testing.T) {
y = 5
if got := i2Int3(y); got != 5 {
t.Errorf("wanted 5, got %d\n", int(got))
}
}
//go:noinline
func i2Int3(i I) Int {
y = 7
return i.(Int)
}
func TestIfaceConv4(t *testing.T) {
a := Int(5)
if got := i2Int4(a, &a); got != 5 {
t.Errorf("wanted 5, got %d\n", int(got))
}
}
//go:noinline
func i2Int4(i I, p *Int) Int {
*p = 7
return i.(Int)
}
func BenchmarkEfaceInteger(b *testing.B) {
sum := 0
for i := 0; i < b.N; i++ {
sum += i2int(i)
}
sink = sum
}
//go:noinline
func i2int(i interface{}) int {
return i.(int)
}

View file

@ -1058,6 +1058,25 @@ opswitch:
n = l
break
}
// Optimize convT2{E,I} when T is not pointer-shaped.
// We make the interface by initializing a stack temporary to
// the value we want to put in the interface, then using the address of
// that stack temporary for the interface data word.
if !n.Left.Type.IsInterface() && n.Esc == EscNone && n.Left.Type.Width <= 1024 {
tmp := temp(n.Left.Type)
init.Append(typecheck(nod(OAS, tmp, n.Left), Etop))
var t *Node
if n.Type.IsEmptyInterface() {
t = typename(n.Left.Type)
} else {
t = itabname(n.Left.Type, n.Type)
}
l := nod(OEFACE, t, typecheck(nod(OADDR, tmp, nil), Erv))
l.Type = n.Type
l.Typecheck = n.Typecheck
n = l
break
}
var ll []*Node
if n.Type.IsEmptyInterface() {
@ -1087,25 +1106,10 @@ opswitch:
ll = append(ll, nod(OADDR, copyexpr(n.Left, n.Left.Type, init), nil))
}
dowidth(n.Left.Type)
r := nodnil()
if n.Esc == EscNone && n.Left.Type.Width <= 1024 {
// Allocate stack buffer for value stored in interface.
r = temp(n.Left.Type)
r = nod(OAS, r, nil) // zero temp
r = typecheck(r, Etop)
init.Append(r)
r = nod(OADDR, r.Left, nil)
r = typecheck(r, Erv)
}
ll = append(ll, r)
}
fn := syslook(convFuncName(n.Left.Type, n.Type))
if !n.Left.Type.IsInterface() {
fn = substArgTypes(fn, n.Left.Type, n.Left.Type, n.Type)
} else {
fn = substArgTypes(fn, n.Left.Type, n.Type)
}
fn = substArgTypes(fn, n.Left.Type, n.Type)
dowidth(fn.Type)
n = nod(OCALL, fn, nil)
n.List.Set(ll)

View file

@ -152,7 +152,7 @@ func itabsinit() {
unlock(&ifaceLock)
}
func convT2E(t *_type, elem unsafe.Pointer, x unsafe.Pointer) (e eface) {
func convT2E(t *_type, elem unsafe.Pointer) (e eface) {
if raceenabled {
raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2E))
}
@ -162,18 +162,16 @@ func convT2E(t *_type, elem unsafe.Pointer, x unsafe.Pointer) (e eface) {
if isDirectIface(t) {
throw("direct convT2E")
}
if x == nil {
x = newobject(t)
// TODO: We allocate a zeroed object only to overwrite it with
// actual data. Figure out how to avoid zeroing. Also below in convT2I.
}
x := newobject(t)
// TODO: We allocate a zeroed object only to overwrite it with
// actual data. Figure out how to avoid zeroing. Also below in convT2I.
typedmemmove(t, x, elem)
e._type = t
e.data = x
return
}
func convT2I(tab *itab, elem unsafe.Pointer, x unsafe.Pointer) (i iface) {
func convT2I(tab *itab, elem unsafe.Pointer) (i iface) {
t := tab._type
if raceenabled {
raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&tab)), funcPC(convT2I))
@ -184,9 +182,7 @@ func convT2I(tab *itab, elem unsafe.Pointer, x unsafe.Pointer) (i iface) {
if isDirectIface(t) {
throw("direct convT2I")
}
if x == nil {
x = newobject(t)
}
x := newobject(t)
typedmemmove(t, x, elem)
i.tab = tab
i.data = x

View file

@ -139,7 +139,9 @@ var i9 interface{}
func f9() bool {
g8()
x := i9
return x != interface{}(99.0i) // ERROR "live at call to convT2E: x.data x.type$"
y := interface{}(99.0i) // ERROR "live at call to convT2E: x.data x.type$"
i9 = y // make y escape so the line above has to call convT2E
return x != y
}
// liveness formerly confused by UNDEF followed by RET,