mirror of
https://github.com/golang/go
synced 2024-11-23 18:30:06 -07:00
cmd/compile: skip convT2E for empty structs
Fixes #18402 Change-Id: I5af800857fb2e365ce4224eece9171277106ec7d Reviewed-on: https://go-review.googlesource.com/35562 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
3d5eb4a6be
commit
8958d8ce37
@ -365,6 +365,7 @@ var Thearch Arch
|
||||
|
||||
var (
|
||||
staticbytes,
|
||||
zerobase,
|
||||
Newproc,
|
||||
Deferproc,
|
||||
Deferreturn,
|
||||
|
@ -894,26 +894,35 @@ opswitch:
|
||||
staticbytes = newname(Pkglookup("staticbytes", Runtimepkg))
|
||||
staticbytes.Class = PEXTERN
|
||||
staticbytes.Type = typArray(Types[TUINT8], 256)
|
||||
zerobase = newname(Pkglookup("zerobase", Runtimepkg))
|
||||
zerobase.Class = PEXTERN
|
||||
zerobase.Type = Types[TUINTPTR]
|
||||
}
|
||||
|
||||
// Optimize convT2{E,I} when T is not pointer-shaped,
|
||||
// but the value does not escape or is a readonly global or is a bool/byte.
|
||||
// Optimize convT2{E,I} for many cases in which T is not pointer-shaped,
|
||||
// by using an existing addressable value identical to n.Left
|
||||
// or creating one on the stack.
|
||||
var value *Node
|
||||
switch {
|
||||
case !n.Left.Type.IsInterface() && n.Esc == EscNone && n.Left.Type.Width <= 1024:
|
||||
// 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.
|
||||
value = temp(n.Left.Type)
|
||||
init.Append(typecheck(nod(OAS, value, n.Left), Etop))
|
||||
case n.Left.Class == PEXTERN && n.Left.Name != nil && n.Left.Name.Readonly:
|
||||
// readonly global; use directly.
|
||||
value = n.Left
|
||||
case n.Left.Type.Size() == 0:
|
||||
// n.Left is zero-sized. Use zerobase.
|
||||
value = zerobase
|
||||
case n.Left.Type.IsBoolean() || (n.Left.Type.Size() == 1 && n.Left.Type.IsInteger()):
|
||||
// n.Left is a bool/byte. Use staticbytes[n.Left].
|
||||
value = nod(OINDEX, staticbytes, byteindex(n.Left))
|
||||
value.Bounded = true
|
||||
case n.Left.Class == PEXTERN && n.Left.Name != nil && n.Left.Name.Readonly:
|
||||
// n.Left is a readonly global; use it directly.
|
||||
value = n.Left
|
||||
case !n.Left.Type.IsInterface() && n.Esc == EscNone && n.Left.Type.Width <= 1024:
|
||||
// n.Left does not escape. Use a stack temporary initialized to n.Left.
|
||||
value = temp(n.Left.Type)
|
||||
init.Append(typecheck(nod(OAS, value, n.Left), Etop))
|
||||
}
|
||||
|
||||
if value != nil {
|
||||
// Value is identical to n.Left.
|
||||
// Construct the interface directly: {type/itab, &value}.
|
||||
var t *Node
|
||||
if n.Type.IsEmptyInterface() {
|
||||
t = typename(n.Left.Type)
|
||||
|
Loading…
Reference in New Issue
Block a user