Use PackedIndexOfIsSupported checks in more places (#80254)
authorRadek Doulik <radek.doulik@gmail.com>
Mon, 9 Jan 2023 10:41:51 +0000 (11:41 +0100)
committerGitHub <noreply@github.com>
Mon, 9 Jan 2023 10:41:51 +0000 (11:41 +0100)
* Use PackedIndexOfIsSupported checks in more places

This should avoids the size regression on WebAssembly and possibly other
platforms without Sse2.

The regression is side effect of https://github.com/dotnet/runtime/pull/78861
which uses `PackedSpanHelpers.CanUsePackedIndexOf (!!T)` and TShouldUsePacked.Value
to guard the usage of PackedSpanHelpers.

Because these involve generics, illinker is unable to link
the PackedSpanHelpers type away and that pulls other parts in, like
System.Runtime.Intrinsics.X86.* types. See https://gist.github.com/radekdoulik/c0b52247d472f69bcf983ade78a924ea
for more complete list.

This change gets us back 9,216 bytes in the case of app used to repro
the regression.

    ...
      -             Type System.PackedSpanHelpers
      -             Type System.Runtime.Intrinsics.X86.X86Base
      -             Type System.Runtime.Intrinsics.X86.Sse
      -             Type System.Runtime.Intrinsics.X86.Sse2
    Summary:
      -       9,216 File size -0.76% (of 1,215,488)
      -       2,744 Metadata size -0.43% (of 636,264)
      -           4 Types count

* Update src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
* Update src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.cs

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
* Feedback

Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny1CharValue.cs
src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny2CharValues.cs
src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny3CharValues.cs
src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyCharValuesInRange.cs
src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.cs
src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs

index 762f1872cb64c182127a24fa093dcd2b85c885b6..de7a8968b2d2691f0a85a0181ad95345f905d72d 100644 (file)
@@ -22,7 +22,7 @@ namespace System.Buffers
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal override int IndexOfAny(ReadOnlySpan<char> span) =>
-            TShouldUsePacked.Value
+            (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value)
                 ? PackedSpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), _e0, span.Length)
                 : SpanHelpers.NonPackedIndexOfValueType<short, SpanHelpers.DontNegate<short>>(
                     ref Unsafe.As<char, short>(ref MemoryMarshal.GetReference(span)),
@@ -31,7 +31,7 @@ namespace System.Buffers
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal override int IndexOfAnyExcept(ReadOnlySpan<char> span) =>
-            TShouldUsePacked.Value
+            (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value)
                 ? PackedSpanHelpers.IndexOfAnyExcept(ref MemoryMarshal.GetReference(span), _e0, span.Length)
                 : SpanHelpers.NonPackedIndexOfValueType<short, SpanHelpers.Negate<short>>(
                     ref Unsafe.As<char, short>(ref MemoryMarshal.GetReference(span)),
index f649ffc752657e3ad13ec0682de4566fef711ab6..8f5c0c2645623018300fdc74361df3fb1177cf66 100644 (file)
@@ -22,7 +22,7 @@ namespace System.Buffers
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal override int IndexOfAny(ReadOnlySpan<char> span) =>
-            TShouldUsePacked.Value
+            (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value)
                 ? PackedSpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), _e0, _e1, span.Length)
                 : SpanHelpers.NonPackedIndexOfAnyValueType<short, SpanHelpers.DontNegate<short>>(
                     ref Unsafe.As<char, short>(ref MemoryMarshal.GetReference(span)),
@@ -32,7 +32,7 @@ namespace System.Buffers
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal override int IndexOfAnyExcept(ReadOnlySpan<char> span) =>
-            TShouldUsePacked.Value
+            (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value)
                 ? PackedSpanHelpers.IndexOfAnyExcept(ref MemoryMarshal.GetReference(span), _e0, _e1, span.Length)
                 : SpanHelpers.NonPackedIndexOfAnyValueType<short, SpanHelpers.Negate<short>>(
                     ref Unsafe.As<char, short>(ref MemoryMarshal.GetReference(span)),
index 5ae583b0f174b399ee1eaf9097b5349e72a79d41..b1f6cb048eda427427a470624cd31350d5215cac 100644 (file)
@@ -22,7 +22,7 @@ namespace System.Buffers
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal override int IndexOfAny(ReadOnlySpan<char> span) =>
-            TShouldUsePacked.Value
+            (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value)
                 ? PackedSpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), _e0, _e1, _e2, span.Length)
                 : SpanHelpers.NonPackedIndexOfAnyValueType<short, SpanHelpers.DontNegate<short>>(
                     ref Unsafe.As<char, short>(ref MemoryMarshal.GetReference(span)),
@@ -33,7 +33,7 @@ namespace System.Buffers
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal override int IndexOfAnyExcept(ReadOnlySpan<char> span) =>
-            TShouldUsePacked.Value
+            (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value)
                 ? PackedSpanHelpers.IndexOfAnyExcept(ref MemoryMarshal.GetReference(span), _e0, _e1, _e2, span.Length)
                 : SpanHelpers.NonPackedIndexOfAnyValueType<short, SpanHelpers.Negate<short>>(
                     ref Unsafe.As<char, short>(ref MemoryMarshal.GetReference(span)),
index 018ef273b4839dae57c37e6ad26d00316c8dffe7..0cde365d4e3a1e8e8f12d661099ddce0f6fbe0b4 100644 (file)
@@ -38,7 +38,7 @@ namespace System.Buffers
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal override int IndexOfAny(ReadOnlySpan<char> span) =>
-            TShouldUsePacked.Value
+            (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value)
                 ? PackedSpanHelpers.IndexOfAnyInRange(ref MemoryMarshal.GetReference(span), _lowInclusive, _rangeInclusive, span.Length)
                 : SpanHelpers.NonPackedIndexOfAnyInRangeUnsignedNumber<ushort, SpanHelpers.DontNegate<ushort>>(
                     ref Unsafe.As<char, ushort>(ref MemoryMarshal.GetReference(span)),
@@ -48,7 +48,7 @@ namespace System.Buffers
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal override int IndexOfAnyExcept(ReadOnlySpan<char> span) =>
-            TShouldUsePacked.Value
+            (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value)
                 ? PackedSpanHelpers.IndexOfAnyExceptInRange(ref MemoryMarshal.GetReference(span), _lowInclusive, _rangeInclusive, span.Length)
                 : SpanHelpers.NonPackedIndexOfAnyInRangeUnsignedNumber<ushort, SpanHelpers.Negate<ushort>>(
                     ref Unsafe.As<char, ushort>(ref MemoryMarshal.GetReference(span)),
index 24c62bd92b9695e3d4a155939c56553a8e2e6b78..136e345747897bcbd79055688d14d7ea9fc1f78a 100644 (file)
@@ -80,7 +80,7 @@ namespace System.Buffers
             if (values.Length == 1)
             {
                 char value = values[0];
-                return PackedSpanHelpers.CanUsePackedIndexOf(value)
+                return PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value)
                     ? new IndexOfAny1CharValue<TrueConst>(value)
                     : new IndexOfAny1CharValue<FalseConst>(value);
             }
@@ -95,7 +95,7 @@ namespace System.Buffers
             {
                 char value0 = values[0];
                 char value1 = values[1];
-                return PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1)
+                return PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1)
                     ? new IndexOfAny2CharValue<TrueConst>(value0, value1)
                     : new IndexOfAny2CharValue<FalseConst>(value0, value1);
             }
@@ -105,7 +105,7 @@ namespace System.Buffers
                 char value0 = values[0];
                 char value1 = values[1];
                 char value2 = values[2];
-                return PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1) && PackedSpanHelpers.CanUsePackedIndexOf(value2)
+                return PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1) && PackedSpanHelpers.CanUsePackedIndexOf(value2)
                     ? new IndexOfAny3CharValue<TrueConst>(value0, value1, value2)
                     : new IndexOfAny3CharValue<FalseConst>(value0, value1, value2);
             }
@@ -185,7 +185,7 @@ namespace System.Buffers
             }
 
             Debug.Assert(typeof(T) == typeof(char));
-            return (IndexOfAnyValues<T>)(object)(PackedSpanHelpers.CanUsePackedIndexOf(min) && PackedSpanHelpers.CanUsePackedIndexOf(max)
+            return (IndexOfAnyValues<T>)(object)(PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(min) && PackedSpanHelpers.CanUsePackedIndexOf(max)
                 ? new IndexOfAnyCharValuesInRange<TrueConst>(*(char*)&min, *(char*)&max)
                 : new IndexOfAnyCharValuesInRange<FalseConst>(*(char*)&min, *(char*)&max));
         }
index d3d643f13ee64e9e69444509eba79cb33dfc49b8..9e0fc123ffc8c7e52a2ca493b688e83cb67d7f72 100644 (file)
@@ -1306,7 +1306,7 @@ namespace System
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal static unsafe bool ContainsValueType<T>(ref T searchSpace, T value, int length) where T : struct, INumber<T>
         {
-            if (PackedSpanHelpers.CanUsePackedIndexOf(value))
+            if (PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value))
             {
                 return PackedSpanHelpers.Contains(ref Unsafe.As<T, short>(ref searchSpace), *(short*)&value, length);
             }
@@ -1448,7 +1448,7 @@ namespace System
             where TValue : struct, INumber<TValue>
             where TNegator : struct, INegator<TValue>
         {
-            if (PackedSpanHelpers.CanUsePackedIndexOf(value))
+            if (PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value))
             {
                 return typeof(TNegator) == typeof(DontNegate<short>)
                     ? PackedSpanHelpers.IndexOf(ref Unsafe.As<TValue, char>(ref searchSpace), *(char*)&value, length)
@@ -1605,7 +1605,7 @@ namespace System
             where TValue : struct, INumber<TValue>
             where TNegator : struct, INegator<TValue>
         {
-            if (PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1))
+            if (PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1))
             {
                 return typeof(TNegator) == typeof(DontNegate<short>)
                     ? PackedSpanHelpers.IndexOfAny(ref Unsafe.As<TValue, char>(ref searchSpace), *(char*)&value0, *(char*)&value1, length)
@@ -1782,7 +1782,7 @@ namespace System
             where TValue : struct, INumber<TValue>
             where TNegator : struct, INegator<TValue>
         {
-            if (PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1) && PackedSpanHelpers.CanUsePackedIndexOf(value2))
+            if (PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1) && PackedSpanHelpers.CanUsePackedIndexOf(value2))
             {
                 return typeof(TNegator) == typeof(DontNegate<short>)
                     ? PackedSpanHelpers.IndexOfAny(ref Unsafe.As<TValue, char>(ref searchSpace), *(char*)&value0, *(char*)&value1, *(char*)&value2, length)
@@ -3085,7 +3085,7 @@ namespace System
             where T : struct, IUnsignedNumber<T>, IComparisonOperators<T, T, bool>
             where TNegator : struct, INegator<T>
         {
-            if (PackedSpanHelpers.CanUsePackedIndexOf(lowInclusive) && PackedSpanHelpers.CanUsePackedIndexOf(highInclusive) && highInclusive >= lowInclusive)
+            if (PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(lowInclusive) && PackedSpanHelpers.CanUsePackedIndexOf(highInclusive) && highInclusive >= lowInclusive)
             {
                 ref char charSearchSpace = ref Unsafe.As<T, char>(ref searchSpace);
                 char charLowInclusive = *(char*)&lowInclusive;