Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -7526,7 +7526,8 @@ class Compiler
CORINFO_CLASS_HANDLE* classGuesses,
CORINFO_METHOD_HANDLE* methodGuesses,
int* candidatesCount,
unsigned* likelihoods);
unsigned* likelihoods,
bool verboseLogging = true);

void considerGuardedDevirtualization(GenTreeCall* call,
IL_OFFSET ilOffset,
Expand Down
14 changes: 14 additions & 0 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12995,6 +12995,20 @@ void Compiler::gtDispTree(GenTree* tree,
}
}

// Dump profile if any
if (call->IsHelperCall() && impIsCastHelperMayHaveProfileData(eeGetHelperNum(call->gtCallMethHnd)))
{
CORINFO_CLASS_HANDLE likelyClasses[MAX_GDV_TYPE_CHECKS] = {};
unsigned likelyLikelihoods[MAX_GDV_TYPE_CHECKS] = {};
int likelyClassCount = 0;
pickGDV(call, call->gtCastHelperILOffset, false, likelyClasses, nullptr, &likelyClassCount,
likelyLikelihoods, false);
if (likelyClassCount > 0)
{
printf(" (%d%% likely '%s')", likelyLikelihoods[0], eeGetClassName(likelyClasses[0]));
}
}

gtDispCommonEndLine(tree);

if (!topOnly)
Expand Down
24 changes: 10 additions & 14 deletions src/coreclr/jit/helperexpansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1942,10 +1942,6 @@ enum class TypeCheckPassedAction
CallHelper_AlwaysThrows,
};

// Some arbitrary limit on the number of guesses we can make
// The actual number of guesses is usually much smaller
#define MAX_CAST_GUESSES 8

//------------------------------------------------------------------------------
// PickCandidatesForTypeCheck: picks classes to use as fast type checks against
// the object being casted. The function also defines the strategy to follow
Expand All @@ -1954,7 +1950,7 @@ enum class TypeCheckPassedAction
// Arguments:
// comp - Compiler instance
// castHelper - Cast helper call to expand
// candidates - [out] Classes (guesses) to use in the fast path (up to MAX_CAST_GUESSES)
// candidates - [out] Classes (guesses) to use in the fast path (up to MAX_GDV_TYPE_CHECKS)
// commonCls - [out] Common denominator class for the fast and the fallback paths.
// likelihoods - [out] Likelihoods of successful type checks [0..100]
// typeCheckFailed - [out] Action to perform if the type check fails
Expand Down Expand Up @@ -2160,9 +2156,9 @@ static int PickCandidatesForTypeCheck(Compiler* comp,
/////////////////////////////////////////////////////////////////////////////////////////////////////

// Let's re-use GDV's threshold on how many guesses we can make (can be 3 by default).
const int maxTypeChecks = min(comp->getGDVMaxTypeChecks(), MAX_CAST_GUESSES);
const int maxTypeChecks = min(comp->getGDVMaxTypeChecks(), MAX_GDV_TYPE_CHECKS);

CORINFO_CLASS_HANDLE exactClasses[MAX_CAST_GUESSES] = {};
CORINFO_CLASS_HANDLE exactClasses[MAX_GDV_TYPE_CHECKS] = {};
const int numExactClasses = comp->info.compCompHnd->getExactClasses(castToCls, maxTypeChecks, exactClasses);
bool allTrulyExact = true;
for (int i = 0; i < numExactClasses; i++)
Expand Down Expand Up @@ -2234,9 +2230,9 @@ static int PickCandidatesForTypeCheck(Compiler* comp,
// 3) Consult with PGO data
/////////////////////////////////////////////////////////////////////////////////////////////////////

CORINFO_CLASS_HANDLE likelyClasses[MAX_CAST_GUESSES] = {};
unsigned likelyLikelihoods[MAX_CAST_GUESSES] = {};
int likelyClassCount = 0;
CORINFO_CLASS_HANDLE likelyClasses[MAX_GDV_TYPE_CHECKS] = {};
unsigned likelyLikelihoods[MAX_GDV_TYPE_CHECKS] = {};
int likelyClassCount = 0;
comp->pickGDV(castHelper, castHelper->gtCastHelperILOffset, false, likelyClasses, nullptr, &likelyClassCount,
likelyLikelihoods);

Expand Down Expand Up @@ -2364,8 +2360,8 @@ bool Compiler::fgLateCastExpansionForCall(BasicBlock** pBlock, Statement* stmt,
TypeCheckFailedAction typeCheckFailedAction;
TypeCheckPassedAction typeCheckPassedAction;
CORINFO_CLASS_HANDLE commonCls;
CORINFO_CLASS_HANDLE expectedExactClasses[MAX_CAST_GUESSES] = {};
unsigned likelihoods[MAX_CAST_GUESSES] = {};
CORINFO_CLASS_HANDLE expectedExactClasses[MAX_GDV_TYPE_CHECKS] = {};
unsigned likelihoods[MAX_GDV_TYPE_CHECKS] = {};

const int numOfCandidates = PickCandidatesForTypeCheck(this, call, expectedExactClasses, &commonCls, likelihoods,
&typeCheckFailedAction, &typeCheckPassedAction);
Expand Down Expand Up @@ -2450,8 +2446,8 @@ bool Compiler::fgLateCastExpansionForCall(BasicBlock** pBlock, Statement* stmt,
// Block 2: typeCheckBb(s)
// TODO-InlineCast: if likelyCls == expectedCls we can consider saving to a local to re-use.

BasicBlock* typeChecksBbs[MAX_CAST_GUESSES] = {};
BasicBlock* lastTypeCheckBb = nullcheckBb;
BasicBlock* typeChecksBbs[MAX_GDV_TYPE_CHECKS] = {};
BasicBlock* lastTypeCheckBb = nullcheckBb;
for (int candidateId = 0; candidateId < numOfCandidates; candidateId++)
{
const CORINFO_CLASS_HANDLE expectedCls = expectedExactClasses[candidateId];
Expand Down
26 changes: 19 additions & 7 deletions src/coreclr/jit/importercalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6750,14 +6750,16 @@ void Compiler::addFatPointerCandidate(GenTreeCall* call)
// methodGuesses - [out] the methods to guess for (mutually exclusive with classGuess)
// candidatesCount - [out] number of guesses
// likelihoods - [out] estimates of the likelihoods that the guesses will succeed
// verboseLogging - whether or not to do verbose logging
//
void Compiler::pickGDV(GenTreeCall* call,
IL_OFFSET ilOffset,
bool isInterface,
CORINFO_CLASS_HANDLE* classGuesses,
CORINFO_METHOD_HANDLE* methodGuesses,
int* candidatesCount,
unsigned* likelihoods)
unsigned* likelihoods,
bool verboseLogging)
{
*candidatesCount = 0;

Expand Down Expand Up @@ -6789,12 +6791,15 @@ void Compiler::pickGDV(GenTreeCall* call,

if ((numberOfClasses < 1) && (numberOfMethods < 1))
{
JITDUMP("No likely class or method, sorry\n");
if (verboseLogging)
{
JITDUMP("No likely class or method, sorry\n");
}
return;
}

#ifdef DEBUG
if ((verbose || JitConfig.EnableExtraSuperPmiQueries()) && (numberOfClasses > 0))
if ((verbose || JitConfig.EnableExtraSuperPmiQueries()) && (numberOfClasses > 0) && verboseLogging)
{
JITDUMP("Likely classes for call [%06u]", dspTreeID(call));
if (!call->IsHelperCall())
Expand Down Expand Up @@ -6964,8 +6969,12 @@ void Compiler::pickGDV(GenTreeCall* call,
classGuesses[guessIdx] = (CORINFO_CLASS_HANDLE)likelyClasses[guessIdx].handle;
likelihoods[guessIdx] = likelyClasses[guessIdx].likelihood;
*candidatesCount = *candidatesCount + 1;
JITDUMP("Accepting type %s with likelihood %u as a candidate\n", eeGetClassName(classGuesses[guessIdx]),
likelihoods[guessIdx])

if (verboseLogging)
{
JITDUMP("Accepting type %s with likelihood %u as a candidate\n",
eeGetClassName(classGuesses[guessIdx]), likelihoods[guessIdx])
}
}
else
{
Expand All @@ -6988,8 +6997,11 @@ void Compiler::pickGDV(GenTreeCall* call,
return;
}

JITDUMP("Not guessing for method; likelihood is below %s call threshold %u\n",
call->IsDelegateInvoke() ? "delegate" : "virtual", likelihoodThreshold);
if (verboseLogging)
{
JITDUMP("Not guessing for method; likelihood is below %s call threshold %u\n",
call->IsDelegateInvoke() ? "delegate" : "virtual", likelihoodThreshold);
}
}
}

Expand Down
Loading