-
Notifications
You must be signed in to change notification settings - Fork 18.6k
Open
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.
Milestone
Description
I notice that the code generated for a comparison of rtypes is surprisingly poor, involving a ton of spills and a call to an intrinsic:
func sameType(x, y any) bool {
return reflect.TypeOf(x) != reflect.TypeOf(y)
}golang.org/x/tools/gopls/internal/golang.sameType STEXT size=176 args=0x20 locals=0x48 funcid=0x0 align=0x0
0x0000 00000 L0505 TEXT golang.org/x/tools/gopls/internal/golang.sameType(SB), ABIInternal, $80-32
0x0000 00000 L0505 MOVD 16(g), R16
0x0004 00004 L0505 PCDATA $0, $-2
0x0004 00004 L0505 CMP R16, RSP
0x0008 00008 L0505 BLS 144
0x000c 00012 L0505 PCDATA $0, $-1
0x000c 00012 L0505 MOVD.W R30, -80(RSP)
0x0010 00016 L0505 MOVD R29, -8(RSP)
0x0014 00020 L0505 SUB $8, RSP, R29
0x0018 00024 L0505 MOVD R0, golang.org/x/tools/gopls/internal/golang.x(FP)
0x001c 00028 L0505 MOVD R1, golang.org/x/tools/gopls/internal/golang.x+8(FP)
0x0020 00032 L0505 MOVD R2, golang.org/x/tools/gopls/internal/golang.y+16(FP)
0x0024 00036 L0505 MOVD R3, golang.org/x/tools/gopls/internal/golang.y+24(FP)
0x0028 00040 L0505 FUNCDATA $0, gclocals·emgMVsd5mo9g0HGy8lQYQA==(SB)
0x0028 00040 L0505 FUNCDATA $1, gclocals·lV4l69IdnTMCVxlqSaJ25Q==(SB)
0x0028 00040 L0505 FUNCDATA $2, golang.org/x/tools/gopls/internal/golang.sameType.stkobj(SB)
0x0028 00040 L0505 FUNCDATA $5, golang.org/x/tools/gopls/internal/golang.sameType.arginfo1(SB)
0x0028 00040 L0505 FUNCDATA $6, golang.org/x/tools/gopls/internal/golang.sameType.argliveinfo(SB)
0x0028 00040 L0505 PCDATA $3, $1
0x0028 00040 NOP
0x0028 00040 L1303 MOVD R0, internal/abi.a-16(SP)
0x002c 00044 L1303 MOVD R1, internal/abi.a-8(SP)
0x0030 00048 L0179 MOVD internal/abi.a-16(SP), R4
0x0034 00052 NOP
0x0034 00052 NOP
0x0034 00052 NOP
0x0034 00052 L1303 MOVD R2, internal/abi.a-32(SP)
0x0038 00056 L1303 MOVD R3, internal/abi.a-24(SP)
0x003c 00060 L0179 MOVD internal/abi.a-32(SP), R3
0x0040 00064 NOP
0x0040 00064 NOP
0x0040 00064 L2719 CMP $0, R4
0x0044 00068 L0510 MOVD $go:itab.*reflect.rtype,reflect.Type(SB), R5
0x004c 00076 L0510 CSEL NE, R5, ZR, R0
0x0050 00080 L2719 CMP $0, R3
0x0054 00084 L0510 CSEL NE, R5, ZR, R5
0x0058 00088 L0510 CMP R5, R0
0x005c 00092 L2719 BEQ 104
0x0060 00096 L2719 MOVD $1, R3
0x0064 00100 L2719 JMP 128
0x0068 00104 L2719 CMP $0, R4
0x006c 00108 L0510 CSEL NE, R4, ZR, R1
0x0070 00112 L2719 CMP $0, R3
0x0074 00116 L0510 CSEL NE, R3, ZR, R2
0x0078 00120 L0510 PCDATA $1, $1
0x0078 00120 L0510 CALL runtime.ifaceeq(SB)
0x007c 00124 L0510 EOR $1, R0, R3
0x0080 00128 L0510 MOVD R3, R0
0x0084 00132 L0510 MOVD -8(RSP), R29
0x0088 00136 L0510 MOVD.P 80(RSP), R30
0x008c 00140 L0510 RET (R30)
0x0090 00144 L0510 NOP
0x0090 00144 L0505 PCDATA $1, $-1
0x0090 00144 L0505 PCDATA $0, $-2
0x0090 00144 L0505 STP (R0, R1), 8(RSP)
0x0094 00148 L0505 STP (R2, R3), 24(RSP)
0x0098 00152 L0505 MOVD R30, R3
0x009c 00156 L0505 CALL runtime.morestack_noctxt(SB)
0x00a0 00160 L0505 PCDATA $0, $-1
0x00a0 00160 L0505 LDP 8(RSP), (R0, R1)
0x00a4 00164 L0505 LDP 24(RSP), (R2, R3)
0x00a8 00168 L0505 JMP 0
Is there any reason it couldn't be recognized as a special case and compiled as if written using unsafe Go code like this:
func sameType(x, y any) bool {
type eface struct {
t, v unsafe.Pointer
}
return ((*eface)(unsafe.Pointer(&x))).t == ((*eface)(unsafe.Pointer(&y))).t
}which boils down to a pair of loads and a comparison:
golang.org/x/tools/gopls/internal/golang.sameType STEXT size=48 args=0x20 locals=0x0 funcid=0x0 align=0x0 leaf
0x0000 00000 L0505 TEXT golang.org/x/tools/gopls/internal/golang.sameType(SB), LEAF|NOFRAME|ABIInternal, $0-32
0x0000 00000 L0505 FUNCDATA $0, gclocals·emgMVsd5mo9g0HGy8lQYQA==(SB)
0x0000 00000 L0505 FUNCDATA $1, gclocals·acF1O9X4FQHZUTLQivBEZA==(SB)
0x0000 00000 L0505 FUNCDATA $2, golang.org/x/tools/gopls/internal/golang.sameType.stkobj(SB)
0x0000 00000 L0505 FUNCDATA $5, golang.org/x/tools/gopls/internal/golang.sameType.arginfo1(SB)
0x0000 00000 L0505 MOVD R0, golang.org/x/tools/gopls/internal/golang.x(FP)
0x0004 00004 L0505 MOVD R1, golang.org/x/tools/gopls/internal/golang.x+8(FP)
0x0008 00008 L0505 MOVD R2, golang.org/x/tools/gopls/internal/golang.y+16(FP)
0x000c 00012 L0505 MOVD R3, golang.org/x/tools/gopls/internal/golang.y+24(FP)
0x0010 00016 L0509 MOVD golang.org/x/tools/gopls/internal/golang.x(FP), R1
0x0014 00020 L0509 MOVD golang.org/x/tools/gopls/internal/golang.y+16(FP), R2
0x0018 00024 L0509 CMP R1, R2
0x001c 00028 L0509 CSET EQ, R0
0x0020 00032 L0509 RET (R30)
nussjustin, dsnet, Jorropo, mvdan, zigo101 and 2 more
Metadata
Metadata
Assignees
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.
Type
Projects
Status
In Progress