From 7f93bd695aab2157332d22641c499fcd2fc58958 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 5 Jan 2023 20:17:56 +0100 Subject: [PATCH] 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 --- .../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 +++++----- .../build/ILLink.Substitutions.NoWasmIntrinsics.xml | 9 +++++++++ 7 files changed, 26 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 762f1872cb64..de7a8968b2d2 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 sealed class IndexOfAny1CharValue : IndexOfAnyValues< [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 @@ internal sealed class IndexOfAny1CharValue : IndexOfAnyValues< [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 f649ffc75265..8f5c0c264562 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 sealed class IndexOfAny2CharValue : IndexOfAnyValues< [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 @@ internal sealed class IndexOfAny2CharValue : IndexOfAnyValues< [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 5ae583b0f174..b1f6cb048eda 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 sealed class IndexOfAny3CharValue : IndexOfAnyValues< [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 @@ internal sealed class IndexOfAny3CharValue : IndexOfAnyValues< [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 018ef273b483..0cde365d4e3a 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 char[] GetValues() [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 @@ internal override char[] GetValues() [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 24c62bd92b96..cf39598f2e84 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.PackedIndexOfIsSupported && PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1) && PackedSpanHelpers.CanUsePackedIndexOf(value2) ? new IndexOfAny3CharValue(value0, value1, value2) : new IndexOfAny3CharValue(value0, value1, value2); } @@ -185,7 +185,7 @@ public static IndexOfAnyValues Create(ReadOnlySpan values) } Debug.Assert(typeof(T) == typeof(char)); - return (IndexOfAnyValues)(object)(PackedSpanHelpers.CanUsePackedIndexOf(min) && PackedSpanHelpers.CanUsePackedIndexOf(max) + return (IndexOfAnyValues)(object)(PackedSpanHelpers.PackedIndexOfIsSupported && 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 d3d643f13ee6..9e0fc123ffc8 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 @@ internal static int IndexOfChar(ref char searchSpace, char value, int length) 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 @@ internal static int IndexOfAnyChar(ref char searchSpace, char value0, char value 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 @@ internal static int IndexOfAnyChar(ref char searchSpace, char value0, char value 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 @@ internal static int IndexOfAnyExceptInRangeUnsignedNumber(ref T searchSpace, 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; diff --git a/src/mono/wasm/build/ILLink.Substitutions.NoWasmIntrinsics.xml b/src/mono/wasm/build/ILLink.Substitutions.NoWasmIntrinsics.xml index 5e2282cae353..98b58c5bb490 100644 --- a/src/mono/wasm/build/ILLink.Substitutions.NoWasmIntrinsics.xml +++ b/src/mono/wasm/build/ILLink.Substitutions.NoWasmIntrinsics.xml @@ -9,5 +9,14 @@ + + + + + + + + +