Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Revert Allow some intrinsics in Tier0" #82354

Merged
merged 5 commits into from
Feb 20, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7827,6 +7827,12 @@ void Compiler::impImportBlockCode(BasicBlock* block)
op1->gtFlags |= GTF_RELOP_NAN_UN | GTF_UNSIGNED;
}

// See if we can optimize type comparisons, IsCall() checks for better TP
if (op1->gtGetOp1()->IsCall() && op1->gtGetOp2()->IsCall())
{
op1 = gtFoldTypeCompare(op1);
}
EgorBo marked this conversation as resolved.
Show resolved Hide resolved

// Fold result, if possible.
op1 = gtFoldExpr(op1);

Expand Down
47 changes: 46 additions & 1 deletion src/coreclr/jit/importercalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2597,14 +2597,53 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
break;
}

// Allow some lighweight intrinsics in Tier0 which can improve throughput
// we introduced betterToExpand here because we're fine if intrinsic decides to not expand itself
// in this case unlike mustExpand.
bool betterToExpand = false;

// NOTE: MinOpts() is always true for Tier0 so we have to check explicit flags instead.
// To be fixed in https://github.com/dotnet/runtime/pull/77465
const bool tier0opts = !opts.compDbgCode && !opts.jitFlags->IsSet(JitFlags::JIT_FLAG_MIN_OPT);

if (!mustExpand && tier0opts)
{
switch (ni)
{
// This one is just `return true/false`
case NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant:

// We need these to be able to fold "typeof(...) == typeof(...)"
case NI_System_RuntimeTypeHandle_GetValueInternal:
case NI_System_Type_GetTypeFromHandle:
case NI_System_Type_op_Equality:
case NI_System_Type_op_Inequality:

// Simple cases
case NI_System_String_get_Chars:
case NI_System_String_get_Length:
case NI_System_Span_get_Item:
case NI_System_Span_get_Length:
case NI_System_ReadOnlySpan_get_Item:
case NI_System_ReadOnlySpan_get_Length:
betterToExpand = true;
break;

default:
// Unsafe.* are all small enough to prefer expansions.
betterToExpand = ni >= NI_SRCS_UNSAFE_START && ni <= NI_SRCS_UNSAFE_END;
break;
}
}

GenTree* retNode = nullptr;

// Under debug and minopts, only expand what is required.
// NextCallReturnAddress intrinsic returns the return address of the next call.
// If that call is an intrinsic and is expanded, codegen for NextCallReturnAddress will fail.
// To avoid that we conservatively expand only required intrinsics in methods that call
// the NextCallReturnAddress intrinsic.
if (!mustExpand && (opts.OptimizationDisabled() || info.compHasNextCallRetAddr))
if (!mustExpand && ((opts.OptimizationDisabled() && !betterToExpand) || info.compHasNextCallRetAddr))
{
*pIntrinsicName = NI_Illegal;
return retNode;
Expand Down Expand Up @@ -2715,6 +2754,12 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
JITDUMP("\nExpanding RuntimeHelpers.IsKnownConstant to true early\n");
// We can also consider FTN_ADDR here
}
else if (opts.OptimizationDisabled())
{
// It doesn't make sense to carry it as GT_INTRINSIC till Morph in Tier0
retNode = gtNewIconNode(0);
JITDUMP("\nExpanding RuntimeHelpers.IsKnownConstant to false early\n");
}
else
{
// op1 is not a known constant, we'll do the expansion in morph
Expand Down
10 changes: 6 additions & 4 deletions src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9014,11 +9014,13 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA
case GT_EQ:
case GT_NE:
{
GenTree* optimizedTree = gtFoldTypeCompare(tree);

if (optimizedTree != tree)
if (opts.OptimizationEnabled())
{
return fgMorphTree(optimizedTree);
GenTree* optimizedTree = gtFoldTypeCompare(tree);
if (optimizedTree != tree)
{
return fgMorphTree(optimizedTree);
}
}

// Pattern-matching optimization:
Expand Down