Skip to content

Commit 47eb0eb

Browse files
committed
JIT: Boost inlining if we can unroll memmove/memcmp
1 parent 1e52763 commit 47eb0eb

File tree

7 files changed

+39
-5
lines changed

7 files changed

+39
-5
lines changed

src/coreclr/jit/fgbasic.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,20 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
11251125
break;
11261126
}
11271127

1128+
case NI_System_SpanHelpers_SequenceEqual:
1129+
case NI_System_Buffer_Memmove:
1130+
{
1131+
if (FgStack::IsConstArgument(pushedStack.Top(), impInlineInfo))
1132+
{
1133+
// Constant (at its call-site) argument feeds the Memmove/Memcmp length argument.
1134+
// We most likely will be able to unroll it.
1135+
// It is important to only raise this hint for constant arguments, if it's just a
1136+
// constant in the inlinee itself then we don't need to inline it for unrolling.
1137+
compInlineResult->Note(InlineObservation::CALLSITE_UNROLLABLE_MEMOP);
1138+
}
1139+
break;
1140+
}
1141+
11281142
case NI_System_Span_get_Item:
11291143
case NI_System_ReadOnlySpan_get_Item:
11301144
{

src/coreclr/jit/importercalls.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3795,8 +3795,12 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
37953795
case NI_System_SpanHelpers_SequenceEqual:
37963796
case NI_System_Buffer_Memmove:
37973797
{
3798-
// We'll try to unroll this in lower for constant input.
3799-
isSpecial = true;
3798+
if (sig->sigInst.methInstCount == 0)
3799+
{
3800+
// We'll try to unroll this in lower for constant input.
3801+
isSpecial = true;
3802+
}
3803+
// The generic version is also marked as [Intrinsic] just as a hint for the inliner
38003804
break;
38013805
}
38023806

src/coreclr/jit/inline.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ INLINE_OBSERVATION(FOLDABLE_EXPR, int, "foldable binary expressio
180180
INLINE_OBSERVATION(FOLDABLE_EXPR_UN, int, "foldable unary expression", INFORMATION, CALLSITE)
181181
INLINE_OBSERVATION(FOLDABLE_BRANCH, int, "foldable branch", INFORMATION, CALLSITE)
182182
INLINE_OBSERVATION(FOLDABLE_SWITCH, int, "foldable switch", INFORMATION, CALLSITE)
183+
INLINE_OBSERVATION(UNROLLABLE_MEMOP, int, "unrollable memmove/memcmp", INFORMATION, CALLSITE)
183184
INLINE_OBSERVATION(DIV_BY_CNS, int, "dividy by const", INFORMATION, CALLSITE)
184185
INLINE_OBSERVATION(CONSTANT_ARG_FEEDS_TEST, bool, "constant argument feeds test", INFORMATION, CALLSITE)
185186
INLINE_OBSERVATION(DEPTH, int, "depth", INFORMATION, CALLSITE)

src/coreclr/jit/inlinepolicy.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,10 @@ void ExtendedDefaultPolicy::NoteBool(InlineObservation obs, bool value)
13171317
m_FoldableSwitch++;
13181318
break;
13191319

1320+
case InlineObservation::CALLSITE_UNROLLABLE_MEMOP:
1321+
m_UnrollableMemop++;
1322+
break;
1323+
13201324
case InlineObservation::CALLEE_HAS_SWITCH:
13211325
m_Switch++;
13221326
break;
@@ -1409,7 +1413,7 @@ void ExtendedDefaultPolicy::NoteInt(InlineObservation obs, int value)
14091413
// in prejit-root mode.
14101414
bbLimit += 5 + m_Switch * 10;
14111415
}
1412-
bbLimit += m_FoldableBranch + m_FoldableSwitch * 10;
1416+
bbLimit += m_FoldableBranch + m_FoldableSwitch * 10 + m_UnrollableMemop * 2;
14131417

14141418
if ((unsigned)value > bbLimit)
14151419
{
@@ -1715,6 +1719,13 @@ double ExtendedDefaultPolicy::DetermineMultiplier()
17151719
break;
17161720
}
17171721

1722+
if (m_UnrollableMemop > 0)
1723+
{
1724+
multiplier += m_UnrollableMemop;
1725+
JITDUMP("\nInline candidate has %d unrollable memory operations. Multiplier increased to %g.",
1726+
m_UnrollableMemop, multiplier);
1727+
}
1728+
17181729
if (m_FoldableSwitch > 0)
17191730
{
17201731
multiplier += 6.0;
@@ -1841,6 +1852,7 @@ void ExtendedDefaultPolicy::OnDumpXml(FILE* file, unsigned indent) const
18411852
XATTR_I4(m_FoldableExprUn)
18421853
XATTR_I4(m_FoldableBranch)
18431854
XATTR_I4(m_FoldableSwitch)
1855+
XATTR_I4(m_UnrollableMemop)
18441856
XATTR_I4(m_Switch)
18451857
XATTR_I4(m_DivByCns)
18461858
XATTR_B(m_ReturnsStructByValue)

src/coreclr/jit/inlinepolicy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ class ExtendedDefaultPolicy : public DefaultPolicy
216216
, m_FoldableExprUn(0)
217217
, m_FoldableBranch(0)
218218
, m_FoldableSwitch(0)
219+
, m_UnrollableMemop(0)
219220
, m_Switch(0)
220221
, m_DivByCns(0)
221222
, m_ReturnsStructByValue(false)
@@ -268,6 +269,7 @@ class ExtendedDefaultPolicy : public DefaultPolicy
268269
unsigned m_FoldableExprUn;
269270
unsigned m_FoldableBranch;
270271
unsigned m_FoldableSwitch;
272+
unsigned m_UnrollableMemop;
271273
unsigned m_Switch;
272274
unsigned m_DivByCns;
273275
bool m_ReturnsStructByValue : 1;

src/libraries/System.Private.CoreLib/src/System/Buffer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ internal static unsafe void _ZeroMemory(ref byte b, nuint byteLength)
345345

346346
#if !MONO // Mono BulkMoveWithWriteBarrier is in terms of elements (not bytes) and takes a type handle.
347347

348+
[Intrinsic]
348349
[MethodImpl(MethodImplOptions.AggressiveInlining)]
349350
internal static unsafe void Memmove<T>(ref T destination, ref T source, nuint elementCount)
350351
{

src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -728,9 +728,9 @@ public StringBuilder Append(char[]? value, int startIndex, int charCount)
728728
/// <param name="value">The string to append.</param>
729729
public StringBuilder Append(string? value)
730730
{
731-
if (value is not null)
731+
if (value != null)
732732
{
733-
Append(valueCount: value.Length, value: ref value.GetRawStringData());
733+
Append(ref value.GetRawStringData(), value.Length);
734734
}
735735

736736
return this;

0 commit comments

Comments
 (0)