Skip to content

Commit 7c61b98

Browse files
EgorBojkotas
andauthored
Optimize GDV checks for objects with known type (#84661)
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
1 parent a3e0d47 commit 7c61b98

File tree

1 file changed

+37
-12
lines changed

1 file changed

+37
-12
lines changed

src/coreclr/jit/valuenum.cpp

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10638,23 +10638,48 @@ void Compiler::fgValueNumberTree(GenTree* tree)
1063810638
{
1063910639
assert(!isVolatile); // We don't expect both volatile and invariant
1064010640

10641-
// Are we dereferencing the method table slot of some newly allocated object?
10642-
//
10643-
bool wasNewobj = false;
10644-
if ((oper == GT_IND) && (addr->TypeGet() == TYP_REF) && (tree->TypeGet() == TYP_I_IMPL))
10641+
bool returnsTypeHandle = false;
10642+
if ((oper == GT_IND) && addr->TypeIs(TYP_REF) && tree->TypeIs(TYP_I_IMPL))
1064510643
{
10646-
VNFuncApp funcApp;
10647-
const bool addrIsVNFunc = vnStore->GetVNFunc(addrNvnp.GetLiberal(), &funcApp);
10648-
10649-
if (addrIsVNFunc && (funcApp.m_func == VNF_JitNew) && addrNvnp.BothEqual())
10644+
// We try to access GC object's type, let's see if we know the exact type already
10645+
// First, we're trying to do that via gtGetClassHandle.
10646+
//
10647+
bool isExact = false;
10648+
bool isNonNull = false;
10649+
CORINFO_CLASS_HANDLE handle = gtGetClassHandle(addr, &isExact, &isNonNull);
10650+
if (isExact && (handle != NO_CLASS_HANDLE))
1065010651
{
10651-
tree->gtVNPair =
10652-
vnStore->VNPWithExc(ValueNumPair(funcApp.m_args[0], funcApp.m_args[0]), addrXvnp);
10653-
wasNewobj = true;
10652+
JITDUMP("IND(obj) is actually a class handle for %s\n", eeGetClassName(handle));
10653+
// Filter out all shared generic instantiations
10654+
if ((info.compCompHnd->getClassAttribs(handle) & CORINFO_FLG_SHAREDINST) == 0)
10655+
{
10656+
void* pEmbedClsHnd;
10657+
void* embedClsHnd = (void*)info.compCompHnd->embedClassHandle(handle, &pEmbedClsHnd);
10658+
if (pEmbedClsHnd == nullptr)
10659+
{
10660+
// Skip indirect handles for now since this path is mostly for PGO scenarios
10661+
assert(embedClsHnd != nullptr);
10662+
ValueNum handleVN = vnStore->VNForHandle((ssize_t)embedClsHnd, GTF_ICON_CLASS_HDL);
10663+
tree->gtVNPair = vnStore->VNPWithExc(ValueNumPair(handleVN, handleVN), addrXvnp);
10664+
returnsTypeHandle = true;
10665+
}
10666+
}
10667+
}
10668+
else
10669+
{
10670+
// Then, let's see if we can find JitNew at least
10671+
VNFuncApp funcApp;
10672+
const bool addrIsVNFunc = vnStore->GetVNFunc(addrNvnp.GetLiberal(), &funcApp);
10673+
if (addrIsVNFunc && (funcApp.m_func == VNF_JitNew) && addrNvnp.BothEqual())
10674+
{
10675+
tree->gtVNPair =
10676+
vnStore->VNPWithExc(ValueNumPair(funcApp.m_args[0], funcApp.m_args[0]), addrXvnp);
10677+
returnsTypeHandle = true;
10678+
}
1065410679
}
1065510680
}
1065610681

10657-
if (!wasNewobj)
10682+
if (!returnsTypeHandle)
1065810683
{
1065910684
// Indirections off of addresses for boxed statics represent bases for
1066010685
// the address of the static itself. Here we will use "nullptr" for the

0 commit comments

Comments
 (0)