From 55e1ac7c07df62c4108d4acedf78f77574470ce5 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Mon, 9 Jan 2023 11:41:51 +0100 Subject: [PATCH] Use PackedIndexOfIsSupported checks in more places (#80254) * 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 * Update src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.cs Co-authored-by: Miha Zupan * Feedback Co-authored-by: Miha Zupan --- .../System/IndexOfAnyValues/IndexOfAny1CharValue.cs | 4 ++-- .../System/IndexOfAnyValues/IndexOfAny2CharValues.cs | 4 ++-- .../System/IndexOfAnyValues/IndexOfAny3CharValues.cs | 4 ++-- .../IndexOfAnyValues/IndexOfAnyCharValuesInRange.cs | 4 ++-- .../src/System/IndexOfAnyValues/IndexOfAnyValues.cs | 8 ++++---- .../System.Private.CoreLib/src/System/SpanHelpers.T.cs | 10 +++++----- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny1CharValue.cs b/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny1CharValue.cs index 762f1872cb64c..de7a8968b2d26 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny1CharValue.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny1CharValue.cs @@ -22,7 +22,7 @@ internal override bool ContainsCore(char value) => [MethodImpl(MethodImplOptions.AggressiveInlining)] internal override int IndexOfAny(ReadOnlySpan span) => - TShouldUsePacked.Value + (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value) ? PackedSpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), _e0, span.Length) : SpanHelpers.NonPackedIndexOfValueType>( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -31,7 +31,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), [MethodImpl(MethodImplOptions.AggressiveInlining)] internal override int IndexOfAnyExcept(ReadOnlySpan span) => - TShouldUsePacked.Value + (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value) ? PackedSpanHelpers.IndexOfAnyExcept(ref MemoryMarshal.GetReference(span), _e0, span.Length) : SpanHelpers.NonPackedIndexOfValueType>( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny2CharValues.cs b/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny2CharValues.cs index f649ffc752657..8f5c0c2645623 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny2CharValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny2CharValues.cs @@ -22,7 +22,7 @@ internal override bool ContainsCore(char value) => [MethodImpl(MethodImplOptions.AggressiveInlining)] internal override int IndexOfAny(ReadOnlySpan span) => - TShouldUsePacked.Value + (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value) ? PackedSpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), _e0, _e1, span.Length) : SpanHelpers.NonPackedIndexOfAnyValueType>( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -32,7 +32,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), [MethodImpl(MethodImplOptions.AggressiveInlining)] internal override int IndexOfAnyExcept(ReadOnlySpan span) => - TShouldUsePacked.Value + (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value) ? PackedSpanHelpers.IndexOfAnyExcept(ref MemoryMarshal.GetReference(span), _e0, _e1, span.Length) : SpanHelpers.NonPackedIndexOfAnyValueType>( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny3CharValues.cs b/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny3CharValues.cs index 5ae583b0f174b..b1f6cb048eda4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny3CharValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAny3CharValues.cs @@ -22,7 +22,7 @@ internal override bool ContainsCore(char value) => [MethodImpl(MethodImplOptions.AggressiveInlining)] internal override int IndexOfAny(ReadOnlySpan span) => - TShouldUsePacked.Value + (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value) ? PackedSpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), _e0, _e1, _e2, span.Length) : SpanHelpers.NonPackedIndexOfAnyValueType>( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -33,7 +33,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), [MethodImpl(MethodImplOptions.AggressiveInlining)] internal override int IndexOfAnyExcept(ReadOnlySpan span) => - TShouldUsePacked.Value + (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value) ? PackedSpanHelpers.IndexOfAnyExcept(ref MemoryMarshal.GetReference(span), _e0, _e1, _e2, span.Length) : SpanHelpers.NonPackedIndexOfAnyValueType>( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyCharValuesInRange.cs b/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyCharValuesInRange.cs index 018ef273b4839..0cde365d4e3a1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyCharValuesInRange.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyCharValuesInRange.cs @@ -38,7 +38,7 @@ internal override bool ContainsCore(char value) => [MethodImpl(MethodImplOptions.AggressiveInlining)] internal override int IndexOfAny(ReadOnlySpan span) => - TShouldUsePacked.Value + (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value) ? PackedSpanHelpers.IndexOfAnyInRange(ref MemoryMarshal.GetReference(span), _lowInclusive, _rangeInclusive, span.Length) : SpanHelpers.NonPackedIndexOfAnyInRangeUnsignedNumber>( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -48,7 +48,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), [MethodImpl(MethodImplOptions.AggressiveInlining)] internal override int IndexOfAnyExcept(ReadOnlySpan span) => - TShouldUsePacked.Value + (PackedSpanHelpers.PackedIndexOfIsSupported && TShouldUsePacked.Value) ? PackedSpanHelpers.IndexOfAnyExceptInRange(ref MemoryMarshal.GetReference(span), _lowInclusive, _rangeInclusive, span.Length) : SpanHelpers.NonPackedIndexOfAnyInRangeUnsignedNumber>( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.cs b/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.cs index 24c62bd92b969..136e345747897 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyValues.cs @@ -80,7 +80,7 @@ public static IndexOfAnyValues Create(ReadOnlySpan values) if (values.Length == 1) { char value = values[0]; - return PackedSpanHelpers.CanUsePackedIndexOf(value) + return PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value) ? new IndexOfAny1CharValue(value) : new IndexOfAny1CharValue(value); } @@ -95,7 +95,7 @@ public static IndexOfAnyValues Create(ReadOnlySpan values) { 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(value0, value1) : new IndexOfAny2CharValue(value0, value1); } @@ -105,7 +105,7 @@ public static IndexOfAnyValues Create(ReadOnlySpan values) 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(value0, value1, value2) : new IndexOfAny3CharValue(value0, value1, value2); } @@ -185,7 +185,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(values)), } Debug.Assert(typeof(T) == typeof(char)); - return (IndexOfAnyValues)(object)(PackedSpanHelpers.CanUsePackedIndexOf(min) && PackedSpanHelpers.CanUsePackedIndexOf(max) + return (IndexOfAnyValues)(object)(PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(min) && PackedSpanHelpers.CanUsePackedIndexOf(max) ? new IndexOfAnyCharValuesInRange(*(char*)&min, *(char*)&max) : new IndexOfAnyCharValuesInRange(*(char*)&min, *(char*)&max)); } diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs index d3d643f13ee64..9e0fc123ffc8c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs @@ -1306,7 +1306,7 @@ public static int SequenceCompareTo(ref T first, int firstLength, ref T secon [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static unsafe bool ContainsValueType(ref T searchSpace, T value, int length) where T : struct, INumber { - if (PackedSpanHelpers.CanUsePackedIndexOf(value)) + if (PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value)) { return PackedSpanHelpers.Contains(ref Unsafe.As(ref searchSpace), *(short*)&value, length); } @@ -1448,7 +1448,7 @@ private static unsafe int IndexOfValueType(ref TValue searchSp where TValue : struct, INumber where TNegator : struct, INegator { - if (PackedSpanHelpers.CanUsePackedIndexOf(value)) + if (PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value)) { return typeof(TNegator) == typeof(DontNegate) ? PackedSpanHelpers.IndexOf(ref Unsafe.As(ref searchSpace), *(char*)&value, length) @@ -1605,7 +1605,7 @@ private static unsafe int IndexOfAnyValueType(ref TValue searc where TValue : struct, INumber where TNegator : struct, INegator { - if (PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1)) + if (PackedSpanHelpers.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1)) { return typeof(TNegator) == typeof(DontNegate) ? PackedSpanHelpers.IndexOfAny(ref Unsafe.As(ref searchSpace), *(char*)&value0, *(char*)&value1, length) @@ -1782,7 +1782,7 @@ private static unsafe int IndexOfAnyValueType(ref TValue searc where TValue : struct, INumber where TNegator : struct, INegator { - 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) ? PackedSpanHelpers.IndexOfAny(ref Unsafe.As(ref searchSpace), *(char*)&value0, *(char*)&value1, *(char*)&value2, length) @@ -3085,7 +3085,7 @@ private static unsafe int IndexOfAnyInRangeUnsignedNumber(ref T sea where T : struct, IUnsignedNumber, IComparisonOperators where TNegator : struct, INegator { - 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(ref searchSpace); char charLowInclusive = *(char*)&lowInclusive;