Skip to content

Commit 58d830d

Browse files
committed
Keep importer for now
1 parent 013ddc0 commit 58d830d

File tree

2 files changed

+64
-47
lines changed

2 files changed

+64
-47
lines changed

src/coreclr/jit/helperexpansion.cpp

Lines changed: 62 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,31 +1797,12 @@ bool Compiler::fgVNBasedIntrinsicExpansionForCall_ReadUtf8(BasicBlock** pBlock,
17971797
//
17981798
PhaseStatus Compiler::fgLateCastExpansion()
17991799
{
1800-
if (!doesMethodHaveExpandableCasts())
1800+
if (!doesMethodHaveExpandableCasts() || opts.OptimizationDisabled())
18011801
{
18021802
// Nothing to expand in the current method
18031803
return PhaseStatus::MODIFIED_NOTHING;
18041804
}
18051805

1806-
if (!opts.IsOptimizedWithProfile())
1807-
{
1808-
// Currently, we're only interested in expanding cast helpers using profile data
1809-
return PhaseStatus::MODIFIED_NOTHING;
1810-
}
1811-
1812-
if (JitConfig.JitConsumeProfileForCasts() == 0)
1813-
{
1814-
return PhaseStatus::MODIFIED_NOTHING;
1815-
}
1816-
1817-
const bool preferSize = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_SIZE_OPT);
1818-
if (preferSize)
1819-
{
1820-
// The optimization comes with a codegen size increase
1821-
JITDUMP("Optimized for size - bail out.\n");
1822-
return PhaseStatus::MODIFIED_NOTHING;
1823-
}
1824-
18251806
// TODO-InlineCast: should we still inline some trivial cases even in cold blocks?
18261807
const bool skipForRarelyRunBlocks = true;
18271808
return fgExpandHelper<&Compiler::fgLateCastExpansionForCall>(skipForRarelyRunBlocks);
@@ -1831,6 +1812,7 @@ enum class TypeCheckFailedAction
18311812
{
18321813
ReturnNull,
18331814
CallHelper,
1815+
CallHelper_Specialized,
18341816
CallHelper_AlwaysThrows
18351817
};
18361818

@@ -1947,14 +1929,25 @@ static CORINFO_CLASS_HANDLE PickCandidateForTypeCheck(Compiler* com
19471929
const bool isCastToExact = comp->info.compCompHnd->isExactType(castToCls);
19481930
if (isCastToExact && ((helper == CORINFO_HELP_CHKCASTCLASS) || (helper == CORINFO_HELP_CHKCASTARRAY)))
19491931
{
1950-
// (string)obj
1951-
// (string[])obj
1932+
result = castToCls;
1933+
1934+
// obj is string
1935+
// obj is string[]
19521936
//
1953-
// Fallbacks for these expansions always throw InvalidCastException
1954-
*typeCheckFailed = TypeCheckFailedAction::CallHelper_AlwaysThrows;
1937+
if ((helper == CORINFO_HELP_CHKCASTCLASS))
1938+
{
1939+
// (string)obj
1940+
//
1941+
// Fallback for this expansion always throws InvalidCastException
1942+
// TODO: can we do the same for string[]? (importer did not)
1943+
*typeCheckFailed = TypeCheckFailedAction::CallHelper_AlwaysThrows;
1944+
1945+
// Assume that exceptions are rare
1946+
*likelihood = 100;
19551947

1956-
// Assume that exceptions are rare
1957-
*likelihood = 100;
1948+
// Update the common denominator class to be more exact
1949+
*commonCls = result;
1950+
}
19581951

19591952
// We're done, there is no need in consulting with PGO data
19601953
}
@@ -1965,39 +1958,55 @@ static CORINFO_CLASS_HANDLE PickCandidateForTypeCheck(Compiler* com
19651958
// obj is string[]
19661959
//
19671960
// Fallbacks for these expansions simply return null
1961+
// TODO: should we keep the helper call for ISINSTANCEOFARRAY like we do for CHKCASTARRAY above?
1962+
// The logic is copied from the importer.
19681963
*typeCheckFailed = TypeCheckFailedAction::ReturnNull;
1964+
1965+
// We're done, there is no need in consulting with PGO data
1966+
result = castToCls;
19691967
}
19701968
else
19711969
{
1970+
CORINFO_CLASS_HANDLE exactClass = NO_CLASS_HANDLE;
19721971
// 2) If VM can tell us the exact class for this "cast to" class - use it.
19731972
// Just make sure the class is truly exact.
1974-
if ((comp->info.compCompHnd->getExactClasses(castToCls, 1, &result) == 1) &&
1975-
comp->info.compCompHnd->isExactType(result))
1973+
if ((comp->info.compCompHnd->getExactClasses(castToCls, 1, &exactClass) == 1) &&
1974+
comp->info.compCompHnd->isExactType(exactClass))
19761975
{
1977-
if (isCastClass)
1976+
result = exactClass;
1977+
1978+
if ((helper == CORINFO_HELP_CHKCASTINTERFACE) || (helper == CORINFO_HELP_CHKCASTCLASS))
19781979
{
19791980
// Fallback call is only needed for castclass and only to throw InvalidCastException
19801981
*typeCheckFailed = TypeCheckFailedAction::CallHelper_AlwaysThrows;
19811982

19821983
// Assume that exceptions are rare
19831984
*likelihood = 100;
1985+
1986+
// Update the common denominator class to be more exact
1987+
*commonCls = result;
19841988
}
1985-
else
1989+
else if ((helper == CORINFO_HELP_ISINSTANCEOFINTERFACE) || (helper == CORINFO_HELP_ISINSTANCEOFCLASS))
19861990
{
19871991
// Fallback for isinst simply returns null here
19881992
*typeCheckFailed = TypeCheckFailedAction::ReturnNull;
1989-
}
19901993

1991-
// Update the common denominator class to be more exact
1992-
*commonCls = result;
1994+
// Update the common denominator class to be more exact
1995+
*commonCls = result;
1996+
}
19931997
}
19941998
else
19951999
{
19962000
// 3) Consult with PGO data
19972001
LikelyClassMethodRecord likelyClasses[MAX_GDV_TYPE_CHECKS];
1998-
unsigned likelyClassCount =
1999-
getLikelyClasses(likelyClasses, MAX_GDV_TYPE_CHECKS, comp->fgPgoSchema, comp->fgPgoSchemaCount,
2000-
comp->fgPgoData, (int)castHelper->gtCastHelperILOffset);
2002+
unsigned likelyClassCount = 0;
2003+
2004+
if (comp->opts.IsOptimizedWithProfile() && (JitConfig.JitConsumeProfileForCasts() != 0))
2005+
{
2006+
const int ilOffset = (int)castHelper->gtCastHelperILOffset;
2007+
likelyClassCount = getLikelyClasses(likelyClasses, MAX_GDV_TYPE_CHECKS, comp->fgPgoSchema,
2008+
comp->fgPgoSchemaCount, comp->fgPgoData, ilOffset);
2009+
}
20012010

20022011
if (likelyClassCount != 0)
20032012
{
@@ -2152,10 +2161,12 @@ static CORINFO_CLASS_HANDLE PickCandidateForTypeCheck(Compiler* com
21522161
unreached();
21532162
}
21542163

2155-
if (isCastClass && (result == castToCls) && (*typeCheckFailed == TypeCheckFailedAction::CallHelper))
2164+
if ((helper == CORINFO_HELP_CHKCASTCLASS) && (result == castToCls) &&
2165+
(*typeCheckFailed == TypeCheckFailedAction::CallHelper))
21562166
{
2157-
// TODO-InlineCast: Change helper to faster CORINFO_HELP_CHKCASTCLASS_SPECIAL
2158-
// it won't check for null and castToCls assuming we've already done it inline.
2167+
// A small optimization - use a slightly faster fallback which assumes that we've already checked
2168+
// for null and for castToCls itself so it won't do it again.
2169+
*typeCheckFailed = TypeCheckFailedAction::CallHelper_Specialized;
21592170
}
21602171

21612172
assert(result != NO_CLASS_HANDLE);
@@ -2268,7 +2279,18 @@ bool Compiler::fgLateCastExpansionForCall(BasicBlock** pBlock, Statement* stmt,
22682279
}
22692280
else
22702281
{
2271-
GenTree* fallbackTree = gtNewTempStore(tmpNum, call);
2282+
GenTreeCall* helperCall = call;
2283+
if (typeCheckFailedAction == TypeCheckFailedAction::CallHelper_Specialized)
2284+
{
2285+
// Re-create the call with a specialized helper
2286+
// For JIT we probably can just change the gtCallMethHnd in the existing call, but let's unify with AOT
2287+
helperCall = gtNewHelperCallNode(CORINFO_HELP_CHKCASTCLASS_SPECIAL, call->TypeGet(),
2288+
helperCall->gtArgs.GetUserArgByIndex(0)->GetNode(),
2289+
helperCall->gtArgs.GetUserArgByIndex(1)->GetNode());
2290+
fgMorphCall(helperCall);
2291+
gtSetEvalOrder(helperCall);
2292+
}
2293+
GenTree* fallbackTree = gtNewTempStore(tmpNum, helperCall);
22722294
fallbackBb = fgNewBBFromTreeAfter(BBJ_ALWAYS, typeCheckBb, fallbackTree, debugInfo, lastBb, true);
22732295
}
22742296

src/coreclr/jit/importer.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5462,7 +5462,6 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
54625462

54635463
// Pessimistically assume the jit cannot expand this as an inline test
54645464
bool canExpandInline = false;
5465-
bool partialExpand = false;
54665465
bool reversedMTCheck = false;
54675466
const CorInfoHelpFunc helper = info.compCompHnd->getCastingHelper(pResolvedToken, isCastClass);
54685467

@@ -5559,7 +5558,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
55595558
//
55605559

55615560
GenTree* op2Var = op2;
5562-
if (isCastClass && !partialExpand && (exactCls == NO_CLASS_HANDLE))
5561+
if (isCastClass && (exactCls == NO_CLASS_HANDLE))
55635562
{
55645563
// if exactCls is not null we won't have to clone op2 (it will be used only for the fallback)
55655564
op2Var = fgInsertCommaFormTemp(&op2);
@@ -5597,11 +5596,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
55975596
// use the special helper that skips the cases checked by our inlined cast
55985597
specialHelper = CORINFO_HELP_CHKCASTCLASS_SPECIAL;
55995598
}
5600-
condTrue = gtNewHelperCallNode(specialHelper, TYP_REF, partialExpand ? op2 : op2Var, gtClone(op1));
5601-
}
5602-
else if (partialExpand)
5603-
{
5604-
condTrue = gtNewHelperCallNode(helper, TYP_REF, op2, gtClone(op1));
5599+
condTrue = gtNewHelperCallNode(specialHelper, TYP_REF, op2Var, gtClone(op1));
56055600
}
56065601
else
56075602
{

0 commit comments

Comments
 (0)