From 4fe8873869f03c9c5602eccfe929b9b18133040d Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 15 Feb 2020 14:55:36 +0300 Subject: [PATCH 1/2] Optimize `array.Length / cns` and `array.Length % cns` if cns is positive --- src/coreclr/src/jit/morph.cpp | 21 +++ .../ArrayLengthArithmetic.cs | 139 ++++++++++++++++++ .../ArrayLengthArithmetic.csproj | 12 ++ 3 files changed, 172 insertions(+) create mode 100644 src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.cs create mode 100644 src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.csproj diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 84b3051b5baed4..9e21a184821810 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -11110,6 +11110,17 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) op2->AsDblCon()->gtDconVal = 1.0 / divisor; } } + + // array.Length is always positive so GT_DIV can be changed to GT_UDIV + // if op2 is a positive cns + if (!optValnumCSE_phase && op1->OperIs(GT_ARR_LENGTH) && op2->IsIntegralConst() && + op2->AsIntCon()->IconValue() >= 2) // for 0 and 1 it doesn't matter if it's UDIV or DIV + { + assert(tree->OperIs(GT_DIV)); + tree->ChangeOper(GT_UDIV); + return fgMorphSmpOp(tree, mac); + } + #ifndef TARGET_64BIT if (typ == TYP_LONG) { @@ -11174,6 +11185,16 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) goto USE_HELPER_FOR_ARITH; } + // array.Length is always positive so GT_DIV can be changed to GT_UDIV + // if op2 is a positive cns + if (!optValnumCSE_phase && op1->OperIs(GT_ARR_LENGTH) && op2->IsIntegralConst() && + op2->AsIntCon()->IconValue() >= 2) // for 0 and 1 it doesn't matter if it's UMOD or MOD + { + assert(tree->OperIs(GT_MOD)); + tree->ChangeOper(GT_UMOD); + return fgMorphSmpOp(tree, mac); + } + // Do not use optimizations (unlike UMOD's idiv optimizing during codegen) for signed mod. // A similar optimization for signed mod will not work for a negative perfectly divisible // HI-word. To make it correct, we would need to divide without the sign and then flip the diff --git a/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.cs b/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.cs new file mode 100644 index 00000000000000..9e6d3d53501659 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.cs @@ -0,0 +1,139 @@ +using System; +using System.Runtime.CompilerServices; + +public class ArrayLengthArithmeticTests +{ + static int returnCode = 100; + + static int Main(string[] args) + { + for (int arrayLength = 0; arrayLength < 100; arrayLength++) + { + int[] array = new int[arrayLength]; + + if (arrayLength == 0) + { + Expect(() => ArrayLengthDiv_cns0(array)); + Expect(() => ArrayLengthDiv_var0(array)); + Expect(() => ArrayLengthMod_cns0(array)); + Expect(() => ArrayLengthMod_var0(array)); + } + + // Array.Length / cns == Array.Length / ToVar(cns) + CompareResults(ArrayLengthDiv_cns1(array), ArrayLengthDiv_var1(array)); + CompareResults(ArrayLengthDiv_cns2(array), ArrayLengthDiv_var2(array)); + CompareResults(ArrayLengthDiv_cns3(array), ArrayLengthDiv_var3(array)); + CompareResults(ArrayLengthDiv_cns4(array), ArrayLengthDiv_var4(array)); + CompareResults(ArrayLengthDiv_cns5(array), ArrayLengthDiv_var5(array)); + CompareResults(ArrayLengthDiv_cns8(array), ArrayLengthDiv_var8(array)); + CompareResults(ArrayLengthDiv_cns10(array), ArrayLengthDiv_var10(array)); + CompareResults(ArrayLengthDiv_cnsMaxValuen1(array), ArrayLengthDiv_varMaxValuen1(array)); + CompareResults(ArrayLengthDiv_cnsMaxValue(array), ArrayLengthDiv_varMaxValue(array)); + CompareResults(ArrayLengthDiv_cnsn1(array), ArrayLengthDiv_varn1(array)); + CompareResults(ArrayLengthDiv_cnsn2(array), ArrayLengthDiv_varn2(array)); + CompareResults(ArrayLengthDiv_cnsMinValue(array), ArrayLengthDiv_varMinValue(array)); + + // Array.Length % cns == Array.Length % ToVar(cns) + CompareResults(ArrayLengthMod_cns1(array), ArrayLengthMod_var1(array)); + CompareResults(ArrayLengthMod_cns2(array), ArrayLengthMod_var2(array)); + CompareResults(ArrayLengthMod_cns3(array), ArrayLengthMod_var3(array)); + CompareResults(ArrayLengthMod_cns4(array), ArrayLengthMod_var4(array)); + CompareResults(ArrayLengthMod_cns5(array), ArrayLengthMod_var5(array)); + CompareResults(ArrayLengthMod_cns8(array), ArrayLengthMod_var8(array)); + CompareResults(ArrayLengthMod_cns10(array), ArrayLengthMod_var10(array)); + CompareResults(ArrayLengthMod_cnsMaxValuen1(array), ArrayLengthMod_varMaxValuen1(array)); + CompareResults(ArrayLengthMod_cnsMaxValue(array), ArrayLengthMod_varMaxValue(array)); + CompareResults(ArrayLengthMod_cnsn1(array), ArrayLengthMod_varn1(array)); + CompareResults(ArrayLengthMod_cnsn2(array), ArrayLengthMod_varn2(array)); + CompareResults(ArrayLengthMod_cnsMinValue(array), ArrayLengthMod_varMinValue(array)); + } + + return returnCode; + } + + // Array.Length / cns + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns0(int[] array) => array.Length / 0; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns1(int[] array) => array.Length / 1; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns2(int[] array) => array.Length / 2; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns3(int[] array) => array.Length / 3; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns4(int[] array) => array.Length / 4; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns5(int[] array) => array.Length / 5; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns8(int[] array) => array.Length / 8; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns10(int[] array) => array.Length / 10; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cnsMaxValuen1(int[] array) => array.Length / (int.MaxValue - 1); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cnsMaxValue(int[] array) => array.Length / int.MaxValue; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cnsn1(int[] array) => array.Length / -1; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cnsn2(int[] array) => array.Length / -2; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cnsMinValue(int[] array) => array.Length / int.MinValue; + + // Array.Length / variable + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var0(int[] array) => array.Length / ToVar(0); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var1(int[] array) => array.Length / ToVar(1); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var2(int[] array) => array.Length / ToVar(2); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var3(int[] array) => array.Length / ToVar(3); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var4(int[] array) => array.Length / ToVar(4); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var5(int[] array) => array.Length / ToVar(5); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var8(int[] array) => array.Length / ToVar(8); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var10(int[] array) => array.Length / ToVar(10); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_varMaxValuen1(int[] array) => array.Length / ToVar(int.MaxValue - 1); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_varMaxValue(int[] array) => array.Length / ToVar(int.MaxValue); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_varn1(int[] array) => array.Length / ToVar(-1); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_varn2(int[] array) => array.Length / ToVar(-2); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_varMinValue(int[] array) => array.Length / ToVar(int.MinValue); + + // Array.Length % cns + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns0(int[] array) => array.Length % 0; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns1(int[] array) => array.Length % 1; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns2(int[] array) => array.Length % 2; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns3(int[] array) => array.Length % 3; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns4(int[] array) => array.Length % 4; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns5(int[] array) => array.Length % 5; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns8(int[] array) => array.Length % 8; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns10(int[] array) => array.Length % 10; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cnsMaxValuen1(int[] array) => array.Length % (int.MaxValue - 1); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cnsMaxValue(int[] array) => array.Length % int.MaxValue; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cnsn1(int[] array) => array.Length % -1; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cnsn2(int[] array) => array.Length % -2; + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cnsMinValue(int[] array) => array.Length % int.MinValue; + + // Array.Length % variable + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var0(int[] array) => array.Length % ToVar(0); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var1(int[] array) => array.Length % ToVar(1); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var2(int[] array) => array.Length % ToVar(2); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var3(int[] array) => array.Length % ToVar(3); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var4(int[] array) => array.Length % ToVar(4); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var5(int[] array) => array.Length % ToVar(5); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var8(int[] array) => array.Length % ToVar(8); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var10(int[] array) => array.Length % ToVar(10); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_varMaxValuen1(int[] array) => array.Length % ToVar(int.MaxValue - 1); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_varMaxValue(int[] array) => array.Length % ToVar(int.MaxValue); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_varn1(int[] array) => array.Length % ToVar(-1); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_varn2(int[] array) => array.Length % ToVar(-2); + [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_varMinValue(int[] array) => array.Length % ToVar(int.MinValue); + + static void Expect(Action action, [CallerLineNumber] int line = 0) where T : Exception + { + try + { + action(); + } + catch (T) + { + return; + } + Console.WriteLine($"{typeof(T).Name} was expected, L{line}"); + returnCode++; + } + + static void CompareResults(int a, int b, [CallerLineNumber] int line = 0) + { + if (a != b) + { + Console.WriteLine($"{a} != {b}, L{line}"); + returnCode++; + } + } + + // cns to var + [MethodImpl(MethodImplOptions.NoInlining)] static T ToVar(T t) => t; +} \ No newline at end of file diff --git a/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.csproj b/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.csproj new file mode 100644 index 00000000000000..10e5a51b6a3381 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.csproj @@ -0,0 +1,12 @@ + + + Exe + + + None + True + + + + + From 1ccec8933404120f996d307ebd8134654105c8e4 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 21 Feb 2020 01:48:06 +0300 Subject: [PATCH 2/2] Address feedback --- .../ArrayLengthArithmetic.cs | 120 +++++++++--------- 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.cs b/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.cs index 9e6d3d53501659..4ac6ef069a3dd4 100644 --- a/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.cs +++ b/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.cs @@ -1,15 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System; using System.Runtime.CompilerServices; public class ArrayLengthArithmeticTests { - static int returnCode = 100; + private static int returnCode = 100; - static int Main(string[] args) + public static int Main(string[] args) { for (int arrayLength = 0; arrayLength < 100; arrayLength++) { - int[] array = new int[arrayLength]; + var array = new int[arrayLength]; if (arrayLength == 0) { @@ -52,66 +56,66 @@ static int Main(string[] args) } // Array.Length / cns - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns0(int[] array) => array.Length / 0; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns1(int[] array) => array.Length / 1; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns2(int[] array) => array.Length / 2; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns3(int[] array) => array.Length / 3; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns4(int[] array) => array.Length / 4; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns5(int[] array) => array.Length / 5; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns8(int[] array) => array.Length / 8; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cns10(int[] array) => array.Length / 10; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cnsMaxValuen1(int[] array) => array.Length / (int.MaxValue - 1); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cnsMaxValue(int[] array) => array.Length / int.MaxValue; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cnsn1(int[] array) => array.Length / -1; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cnsn2(int[] array) => array.Length / -2; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_cnsMinValue(int[] array) => array.Length / int.MinValue; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns0(int[] array) => array.Length / 0; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns1(int[] array) => array.Length / 1; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns2(int[] array) => array.Length / 2; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns3(int[] array) => array.Length / 3; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns4(int[] array) => array.Length / 4; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns5(int[] array) => array.Length / 5; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns8(int[] array) => array.Length / 8; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns10(int[] array) => array.Length / 10; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cnsMaxValuen1(int[] array) => array.Length / (int.MaxValue - 1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cnsMaxValue(int[] array) => array.Length / int.MaxValue; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cnsn1(int[] array) => array.Length / -1; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cnsn2(int[] array) => array.Length / -2; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cnsMinValue(int[] array) => array.Length / int.MinValue; // Array.Length / variable - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var0(int[] array) => array.Length / ToVar(0); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var1(int[] array) => array.Length / ToVar(1); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var2(int[] array) => array.Length / ToVar(2); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var3(int[] array) => array.Length / ToVar(3); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var4(int[] array) => array.Length / ToVar(4); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var5(int[] array) => array.Length / ToVar(5); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var8(int[] array) => array.Length / ToVar(8); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_var10(int[] array) => array.Length / ToVar(10); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_varMaxValuen1(int[] array) => array.Length / ToVar(int.MaxValue - 1); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_varMaxValue(int[] array) => array.Length / ToVar(int.MaxValue); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_varn1(int[] array) => array.Length / ToVar(-1); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_varn2(int[] array) => array.Length / ToVar(-2); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthDiv_varMinValue(int[] array) => array.Length / ToVar(int.MinValue); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var0(int[] array) => array.Length / ToVar(0); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var1(int[] array) => array.Length / ToVar(1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var2(int[] array) => array.Length / ToVar(2); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var3(int[] array) => array.Length / ToVar(3); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var4(int[] array) => array.Length / ToVar(4); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var5(int[] array) => array.Length / ToVar(5); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var8(int[] array) => array.Length / ToVar(8); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var10(int[] array) => array.Length / ToVar(10); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_varMaxValuen1(int[] array) => array.Length / ToVar(int.MaxValue - 1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_varMaxValue(int[] array) => array.Length / ToVar(int.MaxValue); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_varn1(int[] array) => array.Length / ToVar(-1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_varn2(int[] array) => array.Length / ToVar(-2); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_varMinValue(int[] array) => array.Length / ToVar(int.MinValue); // Array.Length % cns - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns0(int[] array) => array.Length % 0; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns1(int[] array) => array.Length % 1; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns2(int[] array) => array.Length % 2; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns3(int[] array) => array.Length % 3; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns4(int[] array) => array.Length % 4; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns5(int[] array) => array.Length % 5; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns8(int[] array) => array.Length % 8; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cns10(int[] array) => array.Length % 10; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cnsMaxValuen1(int[] array) => array.Length % (int.MaxValue - 1); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cnsMaxValue(int[] array) => array.Length % int.MaxValue; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cnsn1(int[] array) => array.Length % -1; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cnsn2(int[] array) => array.Length % -2; - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_cnsMinValue(int[] array) => array.Length % int.MinValue; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns0(int[] array) => array.Length % 0; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns1(int[] array) => array.Length % 1; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns2(int[] array) => array.Length % 2; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns3(int[] array) => array.Length % 3; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns4(int[] array) => array.Length % 4; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns5(int[] array) => array.Length % 5; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns8(int[] array) => array.Length % 8; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns10(int[] array) => array.Length % 10; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cnsMaxValuen1(int[] array) => array.Length % (int.MaxValue - 1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cnsMaxValue(int[] array) => array.Length % int.MaxValue; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cnsn1(int[] array) => array.Length % -1; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cnsn2(int[] array) => array.Length % -2; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cnsMinValue(int[] array) => array.Length % int.MinValue; // Array.Length % variable - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var0(int[] array) => array.Length % ToVar(0); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var1(int[] array) => array.Length % ToVar(1); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var2(int[] array) => array.Length % ToVar(2); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var3(int[] array) => array.Length % ToVar(3); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var4(int[] array) => array.Length % ToVar(4); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var5(int[] array) => array.Length % ToVar(5); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var8(int[] array) => array.Length % ToVar(8); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_var10(int[] array) => array.Length % ToVar(10); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_varMaxValuen1(int[] array) => array.Length % ToVar(int.MaxValue - 1); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_varMaxValue(int[] array) => array.Length % ToVar(int.MaxValue); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_varn1(int[] array) => array.Length % ToVar(-1); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_varn2(int[] array) => array.Length % ToVar(-2); - [MethodImpl(MethodImplOptions.NoInlining)] static int ArrayLengthMod_varMinValue(int[] array) => array.Length % ToVar(int.MinValue); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var0(int[] array) => array.Length % ToVar(0); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var1(int[] array) => array.Length % ToVar(1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var2(int[] array) => array.Length % ToVar(2); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var3(int[] array) => array.Length % ToVar(3); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var4(int[] array) => array.Length % ToVar(4); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var5(int[] array) => array.Length % ToVar(5); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var8(int[] array) => array.Length % ToVar(8); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var10(int[] array) => array.Length % ToVar(10); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_varMaxValuen1(int[] array) => array.Length % ToVar(int.MaxValue - 1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_varMaxValue(int[] array) => array.Length % ToVar(int.MaxValue); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_varn1(int[] array) => array.Length % ToVar(-1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_varn2(int[] array) => array.Length % ToVar(-2); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_varMinValue(int[] array) => array.Length % ToVar(int.MinValue); - static void Expect(Action action, [CallerLineNumber] int line = 0) where T : Exception + private static void Expect(Action action, [CallerLineNumber] int line = 0) where T : Exception { try { @@ -125,7 +129,7 @@ static void Expect(Action action, [CallerLineNumber] int line = 0) where T : returnCode++; } - static void CompareResults(int a, int b, [CallerLineNumber] int line = 0) + private static void CompareResults(int a, int b, [CallerLineNumber] int line = 0) { if (a != b) { @@ -135,5 +139,5 @@ static void CompareResults(int a, int b, [CallerLineNumber] int line = 0) } // cns to var - [MethodImpl(MethodImplOptions.NoInlining)] static T ToVar(T t) => t; + [MethodImpl(MethodImplOptions.NoInlining)] private static T ToVar(T t) => t; } \ No newline at end of file