-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
The (ReadOnlySpan<T> span, ReadOnlySpan<T> values) overloads of different IndexOfAny helpers have inconsistent inlining hints:
runtime/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs
Lines 1297 to 1298 in 6811cc4
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
| public static int IndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>? |
runtime/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs
Lines 1566 to 1567 in 6811cc4
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
| public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>? |
vs.
runtime/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs
Lines 681 to 682 in 6811cc4
| /// </returns> | |
| public static int IndexOfAnyExcept<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>? |
runtime/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs
Lines 924 to 925 in 6811cc4
| /// </returns> | |
| public static int LastIndexOfAnyExcept<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>? |
From @stephentoub in #76740 (comment):
a) we should make these consistent, and b) we should seriously reconsider the aggressive inlining that's on there (or consider how IsKnownConstant could be used here). If the values passed is a constant, then the JIT can do a good job of trimming away all of these branches. But if it's not, it results in significant code bloat to the call site, e.g. this:
private static bool Contains(string text, string values) =>
text.AsSpan().IndexOfAny(values) >= 0;results in this:
; Assembly listing for method ConsoleApp15.Program:Contains(System.String,System.String):bool
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; optimized code
; rsp based frame
; partially interruptible
; No PGO data
; 2 inlinees with PGO data; 23 single block inlinees; 1 inlinees without PGO data
G_M000_IG01: ;; offset=0000H
4883EC48 sub rsp, 72
G_M000_IG02: ;; offset=0004H
4885C9 test rcx, rcx
7475 je SHORT G_M000_IG10
G_M000_IG03: ;; offset=0009H
4C8D410C lea r8, bword ptr [rcx+0CH]
8B4908 mov ecx, dword ptr [rcx+08H]
G_M000_IG04: ;; offset=0010H
8BC1 mov eax, ecx
4885D2 test rdx, rdx
7442 je SHORT G_M000_IG08
G_M000_IG05: ;; offset=0017H
488D4A0C lea rcx, bword ptr [rdx+0CH]
448B4A08 mov r9d, dword ptr [rdx+08H]
G_M000_IG06: ;; offset=001FH
8BD0 mov edx, eax
89542444 mov dword ptr [rsp+44H], edx
48894C2438 mov bword ptr [rsp+38H], rcx
4183F905 cmp r9d, 5
0F871B010000 ja G_M000_IG15
418BC1 mov eax, r9d
4C8D0D2A010000 lea r9, [reloc @RWD00]
458B0C81 mov r9d, dword ptr [r9+4*rax]
4C8D15BBFFFFFF lea r10, G_M000_IG02
4D03CA add r9, r10
41FFE1 jmp r9
G_M000_IG07: ;; offset=004FH
B8FFFFFFFF mov eax, -1
E904010000 jmp G_M000_IG16
G_M000_IG08: ;; offset=0059H
33C9 xor rcx, rcx
4533C9 xor r9d, r9d
EBBF jmp SHORT G_M000_IG06
G_M000_IG09: ;; offset=0060H
488B4C2438 mov rcx, bword ptr [rsp+38H]
480FBF01 movsx rax, word ptr [rcx]
498BC8 mov rcx, r8
8BD0 mov edx, eax
448B442444 mov r8d, dword ptr [rsp+44H]
FF1587A32000 call [System.SpanHelpers:IndexOfValueType[short,DontNegate`1[short]](byref,short,int):int]
E9DF000000 jmp G_M000_IG16
G_M000_IG10: ;; offset=007EH
33C9 xor rcx, rcx
4533C0 xor r8d, r8d
4987C8 xchg rcx, r8
EB88 jmp SHORT G_M000_IG04
G_M000_IG11: ;; offset=0088H
488B4C2438 mov rcx, bword ptr [rsp+38H]
4C0FBF09 movsx r9, word ptr [rcx]
480FBF4102 movsx rax, word ptr [rcx+02H]
498BC8 mov rcx, r8
418BD1 mov edx, r9d
448BC0 mov r8d, eax
448B4C2444 mov r9d, dword ptr [rsp+44H]
FF15BEBE2000 call [System.SpanHelpers:IndexOfAnyValueType[short,DontNegate`1[short]](byref,short,short,int):int]
E9AE000000 jmp G_M000_IG16
G_M000_IG12: ;; offset=00AFH
488B4C2438 mov rcx, bword ptr [rsp+38H]
4C0FBF09 movsx r9, word ptr [rcx]
480FBF4102 movsx rax, word ptr [rcx+02H]
4C0FBF5104 movsx r10, word ptr [rcx+04H]
89542420 mov dword ptr [rsp+20H], edx
498BC8 mov rcx, r8
418BD1 mov edx, r9d
448BC0 mov r8d, eax
458BCA mov r9d, r10d
FF1570C62000 call [System.SpanHelpers:IndexOfAnyValueType[short,DontNegate`1[short]](byref,short,short,short,int):int]
E980000000 jmp G_M000_IG16
G_M000_IG13: ;; offset=00DDH
488B4C2438 mov rcx, bword ptr [rsp+38H]
4C0FBF09 movsx r9, word ptr [rcx]
480FBF4102 movsx rax, word ptr [rcx+02H]
4C0FBF5104 movsx r10, word ptr [rcx+04H]
480FBF4906 movsx rcx, word ptr [rcx+06H]
894C2420 mov dword ptr [rsp+20H], ecx
89542428 mov dword ptr [rsp+28H], edx
498BC8 mov rcx, r8
418BD1 mov edx, r9d
448BC0 mov r8d, eax
458BCA mov r9d, r10d
FF1559DE2000 call [System.SpanHelpers:IndexOfAnyValueType[short,DontNegate`1[short]](byref,short,short,short,short,int):int]
EB4C jmp SHORT G_M000_IG16
G_M000_IG14: ;; offset=0111H
488B4C2438 mov rcx, bword ptr [rsp+38H]
4C0FBF09 movsx r9, word ptr [rcx]
480FBF4102 movsx rax, word ptr [rcx+02H]
4C0FBF5104 movsx r10, word ptr [rcx+04H]
4C0FBF5906 movsx r11, word ptr [rcx+06H]
480FBF4908 movsx rcx, word ptr [rcx+08H]
44895C2420 mov dword ptr [rsp+20H], r11d
894C2428 mov dword ptr [rsp+28H], ecx
89542430 mov dword ptr [rsp+30H], edx
498BC8 mov rcx, r8
418BD1 mov edx, r9d
448BC0 mov r8d, eax
458BCA mov r9d, r10d
FF154B842000 call [System.SpanHelpers:IndexOfAnyValueType[short](byref,short,short,short,short,short,int):int]
EB0E jmp SHORT G_M000_IG16
G_M000_IG15: ;; offset=014FH
498BC8 mov rcx, r8
4C8B442438 mov r8, bword ptr [rsp+38H]
FF15A3222000 call [System.MemoryExtensions:IndexOfAnyProbabilistic(byref,int,byref,int):int]
G_M000_IG16: ;; offset=015DH
F7D0 not eax
C1E81F shr eax, 31
G_M000_IG17: ;; offset=0162H
4883C448 add rsp, 72
C3 ret
RWD00 dd 0000004Bh ; case G_M000_IG07
dd 0000005Ch ; case G_M000_IG09
dd 00000084h ; case G_M000_IG11
dd 000000ABh ; case G_M000_IG12
dd 000000D9h ; case G_M000_IG13
dd 0000010Dh ; case G_M000_IG14
; Total bytes of code 359
cc: @EgorBo