Skip to content

Commit

Permalink
Handle MustNot for profiled casts (#90594)
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorBo committed Aug 15, 2023
1 parent 6f0377a commit 4e166f2
Showing 1 changed file with 16 additions and 5 deletions.
21 changes: 16 additions & 5 deletions src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5394,6 +5394,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
// Pessimistically assume the jit cannot expand this as an inline test
bool canExpandInline = false;
bool partialExpand = false;
bool reversedMTCheck = false;
const CorInfoHelpFunc helper = info.compCompHnd->getCastingHelper(pResolvedToken, isCastClass);

CORINFO_CLASS_HANDLE exactCls = NO_CLASS_HANDLE;
Expand Down Expand Up @@ -5478,8 +5479,17 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
if ((likelyCls != NO_CLASS_HANDLE) &&
(likelyClass.likelihood > (UINT32)JitConfig.JitGuardedDevirtualizationChainLikelihood()))
{
if ((info.compCompHnd->compareTypesForCast(likelyCls, pResolvedToken->hClass) ==
TypeCompareState::Must))
TypeCompareState castResult =
info.compCompHnd->compareTypesForCast(likelyCls, pResolvedToken->hClass);

// If case of MustNot we still can optimize isinst (only), e.g.:
//
// bool objIsDisposable = obj is IDisposable;
//
// when the profile tells us that obj is mostly Int32, hence, never implements that interface.
// for castclass it makes little sense as it will always throw a cast exception anyway.
if ((castResult == TypeCompareState::Must) ||
(castResult == TypeCompareState::MustNot && !isCastClass))
{
bool isAbstract = (info.compCompHnd->getClassAttribs(likelyCls) &
(CORINFO_FLG_INTERFACE | CORINFO_FLG_ABSTRACT)) != 0;
Expand All @@ -5489,6 +5499,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
JITDUMP("Adding \"is %s (%X)\" check as a fast path for %s using PGO data.\n",
eeGetClassName(likelyCls), likelyCls, isCastClass ? "castclass" : "isinst");

reversedMTCheck = castResult == TypeCompareState::MustNot;
canExpandInline = true;
partialExpand = true;
exactCls = likelyCls;
Expand Down Expand Up @@ -5567,12 +5578,12 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
// op1Copy CNS_INT
// null
//
condNull = gtNewOperNode(GT_EQ, TYP_INT, gtClone(op1), gtNewIconNode(0, TYP_REF));
condNull = gtNewOperNode(GT_EQ, TYP_INT, gtClone(op1), gtNewNull());

//
// expand the true and false trees for the condMT
//
GenTree* condFalse = gtClone(op1);
GenTree* condFalse = reversedMTCheck ? gtNewNull() : gtClone(op1);
GenTree* condTrue;
if (isCastClass)
{
Expand Down Expand Up @@ -5629,7 +5640,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
// / \.
// qmarkMT op1Copy
//
temp = new (this, GT_COLON) GenTreeColon(TYP_REF, gtClone(op1), qmarkMT);
temp = new (this, GT_COLON) GenTreeColon(TYP_REF, reversedMTCheck ? gtNewNull() : gtClone(op1), qmarkMT);
qmarkNull = gtNewQmarkNode(TYP_REF, condNull, temp->AsColon());
qmarkNull->gtFlags |= GTF_QMARK_CAST_INSTOF;

Expand Down

0 comments on commit 4e166f2

Please sign in to comment.