@@ -5518,79 +5518,6 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
55185518 // If the class is exact, the jit can expand the IsInst check inline.
55195519 canExpandInline = isClassExact;
55205520 }
5521-
5522- // Check if this cast helper have some profile data
5523- // "isinst" with profile data is moved to a late phase.
5524- // The long-term plan is to move all non-trivial expansions there.
5525- if (impIsCastHelperMayHaveProfileData(helper) && isCastClass)
5526- {
5527- const int maxLikelyClasses = 32;
5528- LikelyClassMethodRecord likelyClasses[maxLikelyClasses];
5529- unsigned likelyClassCount =
5530- getLikelyClasses(likelyClasses, maxLikelyClasses, fgPgoSchema, fgPgoSchemaCount, fgPgoData, ilOffset);
5531-
5532- if (likelyClassCount > 0)
5533- {
5534- #ifdef DEBUG
5535- for (UINT32 i = 0; i < likelyClassCount; i++)
5536- {
5537- const char* className = eeGetClassName((CORINFO_CLASS_HANDLE)likelyClasses[i].handle);
5538- JITDUMP(" %u) %p (%s) [likelihood:%u%%]\n", i + 1, likelyClasses[i].handle, className,
5539- likelyClasses[i].likelihood);
5540- }
5541-
5542- // Optional stress mode to pick a random known class, rather than
5543- // the most likely known class.
5544- if (JitConfig.JitRandomGuardedDevirtualization() != 0)
5545- {
5546- // Reuse the random inliner's random state.
5547- CLRRandom* const random =
5548- impInlineRoot()->m_inlineStrategy->GetRandom(JitConfig.JitRandomGuardedDevirtualization());
5549-
5550- unsigned index = static_cast<unsigned>(random->Next(static_cast<int>(likelyClassCount)));
5551- likelyClasses[0].handle = likelyClasses[index].handle;
5552- likelyClasses[0].likelihood = 100;
5553- likelyClassCount = 1;
5554- }
5555- #endif
5556-
5557- LikelyClassMethodRecord likelyClass = likelyClasses[0];
5558- CORINFO_CLASS_HANDLE likelyCls = (CORINFO_CLASS_HANDLE)likelyClass.handle;
5559-
5560- // if there is a dominating candidate with >= 40% likelihood, use it
5561- const unsigned likelihoodMinThreshold = 40;
5562- if ((likelyCls != NO_CLASS_HANDLE) && (likelyClass.likelihood > likelihoodMinThreshold))
5563- {
5564- TypeCompareState castResult =
5565- info.compCompHnd->compareTypesForCast(likelyCls, pResolvedToken->hClass);
5566-
5567- // If case of MustNot we still can optimize isinst (only), e.g.:
5568- //
5569- // bool objIsDisposable = obj is IDisposable;
5570- //
5571- // when the profile tells us that obj is mostly Int32, hence, never implements that interface.
5572- // for castclass it makes little sense as it will always throw a cast exception anyway.
5573- if ((castResult == TypeCompareState::Must) ||
5574- (castResult == TypeCompareState::MustNot && !isCastClass))
5575- {
5576- bool isAbstract = (info.compCompHnd->getClassAttribs(likelyCls) &
5577- (CORINFO_FLG_INTERFACE | CORINFO_FLG_ABSTRACT)) != 0;
5578- // If it's abstract it means we most likely deal with a stale PGO data so bail out.
5579- if (!isAbstract)
5580- {
5581- JITDUMP("Adding \"is %s (%X)\" check as a fast path for %s using PGO data.\n",
5582- eeGetClassName(likelyCls), likelyCls, isCastClass ? "castclass" : "isinst");
5583-
5584- reversedMTCheck = castResult == TypeCompareState::MustNot;
5585- canExpandInline = true;
5586- partialExpand = true;
5587- exactCls = likelyCls;
5588- fastPathLikelihood = likelyClass.likelihood;
5589- }
5590- }
5591- }
5592- }
5593- }
55945521 }
55955522
55965523 const bool expandInline = canExpandInline && shouldExpandInline;
@@ -5621,10 +5548,9 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
56215548 compCurBB->SetFlags(BBF_HAS_HISTOGRAM_PROFILE);
56225549 }
56235550 }
5624- else if (!isCastClass && impIsCastHelperMayHaveProfileData(helper))
5551+ else if (impIsCastHelperMayHaveProfileData(helper))
56255552 {
5626- // Maybe the late-cast-expand phase will have a better luck expanding this cast.
5627- // TODO: enable for cast-class as well.
5553+ // Leave a note for fgLateCastExpand to expand this helper call
56285554 call->gtCallMoreFlags |= GTF_CALL_M_CAST_CAN_BE_EXPANDED;
56295555 call->gtCastHelperILOffset = ilOffset;
56305556 }
0 commit comments