Skip to content

Commit fe2c588

Browse files
committed
cmd/compile: simplify walk OCONVIFACE
n.Type and n.Left.Type are used heavily. Give them useful names. We generate the type word frequently. Make it a closure. (We don't want to generate it up front, since there are some code paths that don't need it, and generating it has side-effects.) Simplify and document the final call construction. Follow-up to address feedback on CL 147360. Change-Id: I251134a55cf80d8b1676280a345d150f2288c09a Reviewed-on: https://go-review.googlesource.com/c/147538 Run-TryBot: Josh Bleecher Snyder <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Martin Möhrmann <[email protected]>
1 parent 6dd70fc commit fe2c588

File tree

1 file changed

+38
-50
lines changed

1 file changed

+38
-50
lines changed

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

Lines changed: 38 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -815,16 +815,21 @@ opswitch:
815815
case OCONVIFACE:
816816
n.Left = walkexpr(n.Left, init)
817817

818-
// Optimize convT2E or convT2I as a two-word copy when T is pointer-shaped.
819-
if isdirectiface(n.Left.Type) {
820-
var t *Node
821-
if n.Type.IsEmptyInterface() {
822-
t = typename(n.Left.Type)
823-
} else {
824-
t = itabname(n.Left.Type, n.Type)
818+
fromType := n.Left.Type
819+
toType := n.Type
820+
821+
// typeword generates the type word of the interface value.
822+
typeword := func() *Node {
823+
if toType.IsEmptyInterface() {
824+
return typename(fromType)
825825
}
826-
l := nod(OEFACE, t, n.Left)
827-
l.Type = n.Type
826+
return itabname(fromType, toType)
827+
}
828+
829+
// Optimize convT2E or convT2I as a two-word copy when T is pointer-shaped.
830+
if isdirectiface(fromType) {
831+
l := nod(OEFACE, typeword(), n.Left)
832+
l.Type = toType
828833
l.SetTypecheck(n.Typecheck())
829834
n = l
830835
break
@@ -844,35 +849,29 @@ opswitch:
844849
// or creating one on the stack.
845850
var value *Node
846851
switch {
847-
case n.Left.Type.Size() == 0:
852+
case fromType.Size() == 0:
848853
// n.Left is zero-sized. Use zerobase.
849854
cheapexpr(n.Left, init) // Evaluate n.Left for side-effects. See issue 19246.
850855
value = zerobase
851-
case n.Left.Type.IsBoolean() || (n.Left.Type.Size() == 1 && n.Left.Type.IsInteger()):
856+
case fromType.IsBoolean() || (fromType.Size() == 1 && fromType.IsInteger()):
852857
// n.Left is a bool/byte. Use staticbytes[n.Left].
853858
n.Left = cheapexpr(n.Left, init)
854859
value = nod(OINDEX, staticbytes, byteindex(n.Left))
855860
value.SetBounded(true)
856861
case n.Left.Class() == PEXTERN && n.Left.Name != nil && n.Left.Name.Readonly():
857862
// n.Left is a readonly global; use it directly.
858863
value = n.Left
859-
case !n.Left.Type.IsInterface() && n.Esc == EscNone && n.Left.Type.Width <= 1024:
864+
case !fromType.IsInterface() && n.Esc == EscNone && fromType.Width <= 1024:
860865
// n.Left does not escape. Use a stack temporary initialized to n.Left.
861-
value = temp(n.Left.Type)
866+
value = temp(fromType)
862867
init.Append(typecheck(nod(OAS, value, n.Left), Etop))
863868
}
864869

865870
if value != nil {
866871
// Value is identical to n.Left.
867872
// Construct the interface directly: {type/itab, &value}.
868-
var t *Node
869-
if n.Type.IsEmptyInterface() {
870-
t = typename(n.Left.Type)
871-
} else {
872-
t = itabname(n.Left.Type, n.Type)
873-
}
874-
l := nod(OEFACE, t, typecheck(nod(OADDR, value, nil), Erv))
875-
l.Type = n.Type
873+
l := nod(OEFACE, typeword(), typecheck(nod(OADDR, value, nil), Erv))
874+
l.Type = toType
876875
l.SetTypecheck(n.Typecheck())
877876
n = l
878877
break
@@ -884,9 +883,9 @@ opswitch:
884883
// tmp = tmp.type
885884
// }
886885
// e = iface{tmp, i.data}
887-
if n.Type.IsEmptyInterface() && n.Left.Type.IsInterface() && !n.Left.Type.IsEmptyInterface() {
886+
if toType.IsEmptyInterface() && fromType.IsInterface() && !fromType.IsEmptyInterface() {
888887
// Evaluate the input interface.
889-
c := temp(n.Left.Type)
888+
c := temp(fromType)
890889
init.Append(nod(OAS, c, n.Left))
891890

892891
// Get the itab out of the interface.
@@ -900,51 +899,41 @@ opswitch:
900899

901900
// Build the result.
902901
e := nod(OEFACE, tmp, ifaceData(c, types.NewPtr(types.Types[TUINT8])))
903-
e.Type = n.Type // assign type manually, typecheck doesn't understand OEFACE.
902+
e.Type = toType // assign type manually, typecheck doesn't understand OEFACE.
904903
e.SetTypecheck(1)
905904
n = e
906905
break
907906
}
908907

909-
fnname, needsaddr := convFuncName(n.Left.Type, n.Type)
908+
fnname, needsaddr := convFuncName(fromType, toType)
910909

911-
if !needsaddr && !n.Left.Type.IsInterface() {
910+
if !needsaddr && !fromType.IsInterface() {
912911
// Use a specialized conversion routine that only returns a data pointer.
913912
// ptr = convT2X(val)
914913
// e = iface{typ/tab, ptr}
915914
fn := syslook(fnname)
916-
dowidth(n.Left.Type)
917-
fn = substArgTypes(fn, n.Left.Type)
915+
dowidth(fromType)
916+
fn = substArgTypes(fn, fromType)
918917
dowidth(fn.Type)
919918
call := nod(OCALL, fn, nil)
920919
call.List.Set1(n.Left)
921920
call = typecheck(call, Erv)
922921
call = walkexpr(call, init)
923922
call = safeexpr(call, init)
924-
var tab *Node
925-
if n.Type.IsEmptyInterface() {
926-
tab = typename(n.Left.Type)
927-
} else {
928-
tab = itabname(n.Left.Type, n.Type)
929-
}
930-
e := nod(OEFACE, tab, call)
931-
e.Type = n.Type
923+
e := nod(OEFACE, typeword(), call)
924+
e.Type = toType
932925
e.SetTypecheck(1)
933926
n = e
934927
break
935928
}
936929

937-
var ll []*Node
938-
if n.Type.IsEmptyInterface() {
939-
if !n.Left.Type.IsInterface() {
940-
ll = append(ll, typename(n.Left.Type))
941-
}
930+
var tab *Node
931+
if fromType.IsInterface() {
932+
// convI2I
933+
tab = typename(toType)
942934
} else {
943-
if n.Left.Type.IsInterface() {
944-
ll = append(ll, typename(n.Type))
945-
} else {
946-
ll = append(ll, itabname(n.Left.Type, n.Type))
947-
}
935+
// convT2x
936+
tab = typeword()
948937
}
949938

950939
v := n.Left
@@ -960,14 +949,13 @@ opswitch:
960949
}
961950
v = nod(OADDR, v, nil)
962951
}
963-
ll = append(ll, v)
964952

965-
dowidth(n.Left.Type)
953+
dowidth(fromType)
966954
fn := syslook(fnname)
967-
fn = substArgTypes(fn, n.Left.Type, n.Type)
955+
fn = substArgTypes(fn, fromType, toType)
968956
dowidth(fn.Type)
969957
n = nod(OCALL, fn, nil)
970-
n.List.Set(ll)
958+
n.List.Set2(tab, v)
971959
n = typecheck(n, Erv)
972960
n = walkexpr(n, init)
973961

0 commit comments

Comments
 (0)