Skip to content

Commit

Permalink
JIT: Boost inlining if we can unroll memmove/memcmp
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorBo committed May 8, 2023
1 parent 1e52763 commit 47eb0eb
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 5 deletions.
14 changes: 14 additions & 0 deletions src/coreclr/jit/fgbasic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1125,6 +1125,20 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
break;
}

case NI_System_SpanHelpers_SequenceEqual:
case NI_System_Buffer_Memmove:
{
if (FgStack::IsConstArgument(pushedStack.Top(), impInlineInfo))
{
// Constant (at its call-site) argument feeds the Memmove/Memcmp length argument.
// We most likely will be able to unroll it.
// It is important to only raise this hint for constant arguments, if it's just a
// constant in the inlinee itself then we don't need to inline it for unrolling.
compInlineResult->Note(InlineObservation::CALLSITE_UNROLLABLE_MEMOP);
}
break;
}

case NI_System_Span_get_Item:
case NI_System_ReadOnlySpan_get_Item:
{
Expand Down
8 changes: 6 additions & 2 deletions src/coreclr/jit/importercalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3795,8 +3795,12 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
case NI_System_SpanHelpers_SequenceEqual:
case NI_System_Buffer_Memmove:
{
// We'll try to unroll this in lower for constant input.
isSpecial = true;
if (sig->sigInst.methInstCount == 0)
{
// We'll try to unroll this in lower for constant input.
isSpecial = true;
}
// The generic version is also marked as [Intrinsic] just as a hint for the inliner
break;
}

Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/inline.def
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ INLINE_OBSERVATION(FOLDABLE_EXPR, int, "foldable binary expressio
INLINE_OBSERVATION(FOLDABLE_EXPR_UN, int, "foldable unary expression", INFORMATION, CALLSITE)
INLINE_OBSERVATION(FOLDABLE_BRANCH, int, "foldable branch", INFORMATION, CALLSITE)
INLINE_OBSERVATION(FOLDABLE_SWITCH, int, "foldable switch", INFORMATION, CALLSITE)
INLINE_OBSERVATION(UNROLLABLE_MEMOP, int, "unrollable memmove/memcmp", INFORMATION, CALLSITE)
INLINE_OBSERVATION(DIV_BY_CNS, int, "dividy by const", INFORMATION, CALLSITE)
INLINE_OBSERVATION(CONSTANT_ARG_FEEDS_TEST, bool, "constant argument feeds test", INFORMATION, CALLSITE)
INLINE_OBSERVATION(DEPTH, int, "depth", INFORMATION, CALLSITE)
Expand Down
14 changes: 13 additions & 1 deletion src/coreclr/jit/inlinepolicy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1317,6 +1317,10 @@ void ExtendedDefaultPolicy::NoteBool(InlineObservation obs, bool value)
m_FoldableSwitch++;
break;

case InlineObservation::CALLSITE_UNROLLABLE_MEMOP:
m_UnrollableMemop++;
break;

case InlineObservation::CALLEE_HAS_SWITCH:
m_Switch++;
break;
Expand Down Expand Up @@ -1409,7 +1413,7 @@ void ExtendedDefaultPolicy::NoteInt(InlineObservation obs, int value)
// in prejit-root mode.
bbLimit += 5 + m_Switch * 10;
}
bbLimit += m_FoldableBranch + m_FoldableSwitch * 10;
bbLimit += m_FoldableBranch + m_FoldableSwitch * 10 + m_UnrollableMemop * 2;

if ((unsigned)value > bbLimit)
{
Expand Down Expand Up @@ -1715,6 +1719,13 @@ double ExtendedDefaultPolicy::DetermineMultiplier()
break;
}

if (m_UnrollableMemop > 0)
{
multiplier += m_UnrollableMemop;
JITDUMP("\nInline candidate has %d unrollable memory operations. Multiplier increased to %g.",
m_UnrollableMemop, multiplier);
}

if (m_FoldableSwitch > 0)
{
multiplier += 6.0;
Expand Down Expand Up @@ -1841,6 +1852,7 @@ void ExtendedDefaultPolicy::OnDumpXml(FILE* file, unsigned indent) const
XATTR_I4(m_FoldableExprUn)
XATTR_I4(m_FoldableBranch)
XATTR_I4(m_FoldableSwitch)
XATTR_I4(m_UnrollableMemop)
XATTR_I4(m_Switch)
XATTR_I4(m_DivByCns)
XATTR_B(m_ReturnsStructByValue)
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/inlinepolicy.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ class ExtendedDefaultPolicy : public DefaultPolicy
, m_FoldableExprUn(0)
, m_FoldableBranch(0)
, m_FoldableSwitch(0)
, m_UnrollableMemop(0)
, m_Switch(0)
, m_DivByCns(0)
, m_ReturnsStructByValue(false)
Expand Down Expand Up @@ -268,6 +269,7 @@ class ExtendedDefaultPolicy : public DefaultPolicy
unsigned m_FoldableExprUn;
unsigned m_FoldableBranch;
unsigned m_FoldableSwitch;
unsigned m_UnrollableMemop;
unsigned m_Switch;
unsigned m_DivByCns;
bool m_ReturnsStructByValue : 1;
Expand Down
1 change: 1 addition & 0 deletions src/libraries/System.Private.CoreLib/src/System/Buffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ internal static unsafe void _ZeroMemory(ref byte b, nuint byteLength)

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

[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe void Memmove<T>(ref T destination, ref T source, nuint elementCount)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -728,9 +728,9 @@ public StringBuilder Append(char[]? value, int startIndex, int charCount)
/// <param name="value">The string to append.</param>
public StringBuilder Append(string? value)
{
if (value is not null)
if (value != null)
{
Append(valueCount: value.Length, value: ref value.GetRawStringData());
Append(ref value.GetRawStringData(), value.Length);
}

return this;
Expand Down

0 comments on commit 47eb0eb

Please sign in to comment.