Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Inline generics #31833

Closed
wants to merge 2 commits into from
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
Original file line number Diff line number Diff line change
Expand Up @@ -1512,6 +1512,7 @@ void MethodContext::repGetCallInfoFromMethodHandle(CORINFO_METHOD_HANDLE methodH
CORINFO_RESOLVED_TOKEN resolvedToken;
DWORD exceptionCode;

resolvedToken.tokenInexactContext = (CORINFO_INEXACT_CONTEXT_HANDLE)key.ResolvedToken.inValue.tokenInexactContext;
resolvedToken.tokenContext = (CORINFO_CONTEXT_HANDLE)key.ResolvedToken.inValue.tokenContext;
resolvedToken.tokenScope = (CORINFO_MODULE_HANDLE)key.ResolvedToken.inValue.tokenScope;
resolvedToken.token = (mdToken)key.ResolvedToken.inValue.token;
Expand All @@ -1529,6 +1530,7 @@ void MethodContext::repGetCallInfoFromMethodHandle(CORINFO_METHOD_HANDLE methodH
if (key.ConstrainedResolvedToken.inValue.tokenContext != 0 &&
key.ConstrainedResolvedToken.inValue.tokenScope != 0)
{
constrainedResolvedToken.tokenInexactContext = (CORINFO_INEXACT_CONTEXT_HANDLE)key.ConstrainedResolvedToken.inValue.tokenInexactContext;
constrainedResolvedToken.tokenContext =
(CORINFO_CONTEXT_HANDLE)key.ConstrainedResolvedToken.inValue.tokenContext;
constrainedResolvedToken.tokenScope =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class MethodContext
};
struct Agnostic_CORINFO_RESOLVED_TOKENin
{
DWORDLONG tokenInexactContext;
DWORDLONG tokenContext;
DWORDLONG tokenScope;
DWORD token;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ std::string SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKENin(
const MethodContext::Agnostic_CORINFO_RESOLVED_TOKENin& tokenIn)
{
char buffer[MAX_BUFFER_SIZE];
sprintf_s(buffer, MAX_BUFFER_SIZE, "tc-%016llX ts-%016llX tok-%08X tt-%u", tokenIn.tokenContext, tokenIn.tokenScope,
sprintf_s(buffer, MAX_BUFFER_SIZE, "tic-%016llX tc-%016llX ts-%016llX tok-%08X tt-%u", tokenIn.tokenInexactContext, tokenIn.tokenContext, tokenIn.tokenScope,
tokenIn.token, tokenIn.tokenType);
return std::string(buffer);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ inline MethodContext::Agnostic_CORINFO_RESOLVED_TOKENin SpmiRecordsHelper::Creat
{
MethodContext::Agnostic_CORINFO_RESOLVED_TOKENin tokenIn;
ZeroMemory(&tokenIn, sizeof(tokenIn));
tokenIn.tokenInexactContext = (DWORDLONG)pResolvedToken->tokenInexactContext;
tokenIn.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
tokenIn.tokenScope = (DWORDLONG)pResolvedToken->tokenScope;
tokenIn.token = (DWORD)pResolvedToken->token;
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/src/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1611,12 +1611,15 @@ enum CorInfoTokenKind
CORINFO_TOKENKIND_Ldvirtftn = 0x400 | CORINFO_TOKENKIND_Method,
};

typedef void* CORINFO_INEXACT_CONTEXT_HANDLE;

struct CORINFO_RESOLVED_TOKEN
{
//
// [In] arguments of resolveToken
//
CORINFO_CONTEXT_HANDLE tokenContext; //Context for resolution of generic arguments
CORINFO_INEXACT_CONTEXT_HANDLE tokenInexactContext; // Context for resolution of generic arguments in generic dictionaries
CORINFO_MODULE_HANDLE tokenScope;
mdToken token; //The source token
CorInfoTokenKind tokenType;
Expand Down Expand Up @@ -1689,6 +1692,8 @@ struct CORINFO_CALL_INFO
CORINFO_CONST_LOOKUP instParamLookup; // Used by Ready-to-Run

BOOL wrapperDelegateInvoke;

CORINFO_INEXACT_CONTEXT_HANDLE inexactContextHandle; // Inexact context information for generic dictionary handling
};

//----------------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/src/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1744,9 +1744,11 @@ void Compiler::compInit(ArenaAllocator* pAlloc, InlineInfo* inlineInfo)
{
m_inlineStrategy = nullptr;
compInlineResult = inlineInfo->inlineResult;
info.compInexactContext = inlineInfo->iciCall->inexactContext;
}
else
{
info.compInexactContext = NULL;
m_inlineStrategy = new (this, CMK_Inlining) InlineStrategy(this);
compInlineResult = nullptr;
}
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/src/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -8742,6 +8742,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
{
COMP_HANDLE compCompHnd;
CORINFO_MODULE_HANDLE compScopeHnd;
CORINFO_INEXACT_CONTEXT_HANDLE compInexactContext;
CORINFO_CLASS_HANDLE compClassHnd;
CORINFO_METHOD_HANDLE compMethodHnd;
CORINFO_METHOD_INFO* compMethodInfo;
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/src/jit/flowgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ void Compiler::fgInstrumentMethod()
mdMethodDef currentMethodToken = info.compCompHnd->getMethodDefFromMethod(info.compMethodHnd);

CORINFO_RESOLVED_TOKEN resolvedToken;
resolvedToken.tokenInexactContext = NULL;
resolvedToken.tokenContext = MAKE_METHODCONTEXT(info.compMethodHnd);
resolvedToken.tokenScope = info.compScopeHnd;
resolvedToken.token = currentMethodToken;
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/src/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6055,6 +6055,7 @@ GenTreeCall* Compiler::gtNewCallNode(
node->gtRetClsHnd = nullptr;
node->gtControlExpr = nullptr;
node->gtCallMoreFlags = 0;
node->inexactContext = nullptr;

if (callType == CT_INDIRECT)
{
Expand Down Expand Up @@ -7772,6 +7773,8 @@ GenTreeCall* Compiler::gtCloneExprCallHelper(GenTreeCall* tree, unsigned addFlag
copy->gtRawILOffset = tree->AsCall()->gtRawILOffset;
#endif

copy->inexactContext = tree->inexactContext;

copy->CopyOtherRegFlags(tree);

return copy;
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/src/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -4199,6 +4199,8 @@ struct GenTreeCall final : public GenTree
CORINFO_CONST_LOOKUP gtEntryPoint;
#endif

CORINFO_INEXACT_CONTEXT_HANDLE inexactContext;

#if defined(DEBUG) || defined(INLINE_DATA)
// For non-inline candidates, track the first observation
// that blocks candidacy.
Expand Down
72 changes: 53 additions & 19 deletions src/coreclr/src/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ bool Compiler::impILConsumesAddr(const BYTE* codeAddr, CORINFO_METHOD_HANDLE fnc

void Compiler::impResolveToken(const BYTE* addr, CORINFO_RESOLVED_TOKEN* pResolvedToken, CorInfoTokenKind kind)
{
pResolvedToken->tokenInexactContext = info.compInexactContext;
pResolvedToken->tokenContext = impTokenLookupContextHandle;
pResolvedToken->tokenScope = info.compScopeHnd;
pResolvedToken->token = getU4LittleEndian(addr);
Expand Down Expand Up @@ -1864,9 +1865,9 @@ GenTree* Compiler::impLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
}
return gtNewIconEmbHndNode(handle, pIndirection, handleFlags, compileTimeHandle);
}
else if (compIsForInlining())
else if (compIsForInlining() && info.compInexactContext == NULL)
{
// Don't import runtime lookups when inlining
// Don't import runtime lookups when inlining without an inexact context
// Inlining has to be aborted in such a case
compInlineResult->NoteFatal(InlineObservation::CALLSITE_GENERIC_DICTIONARY_LOOKUP);
return nullptr;
Expand All @@ -1876,6 +1877,13 @@ GenTree* Compiler::impLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
// Need to use dictionary-based access which depends on the typeContext
// which is only available at runtime, not at compile-time.

if (compIsForInlining())
{
compInlineResult->Note(InlineObservation::CALLSITE_INLINED_GENERIC_DICTIONARY_LOOKUP);
if (compInlineResult->IsFailure())
return nullptr;
}

return impRuntimeLookupToTree(pResolvedToken, pLookup, compileTimeHandle);
}
}
Expand Down Expand Up @@ -1946,10 +1954,21 @@ GenTree* Compiler::impMethodPointer(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI
case CORINFO_CALL_CODE_POINTER:
if (compIsForInlining())
{
// Don't import runtime lookups when inlining
// Inlining has to be aborted in such a case
compInlineResult->NoteFatal(InlineObservation::CALLSITE_GENERIC_DICTIONARY_LOOKUP);
return nullptr;
if (info.compInexactContext == NULL)
{
// Don't import runtime lookups when inlining without inexact context
// Inlining has to be aborted in such a case
compInlineResult->NoteFatal(InlineObservation::CALLSITE_GENERIC_DICTIONARY_LOOKUP);
return nullptr;
}
else
{
// Use of inexact context in inlining
compInlineResult->Note(InlineObservation::CALLSITE_INLINED_GENERIC_DICTIONARY_LOOKUP);
if (compInlineResult->IsFailure())
return nullptr;
}

}

op1 = impLookupToTree(pResolvedToken, &pCallInfo->codePointerLookup, GTF_ICON_FTN_ADDR, pCallInfo->hMethod);
Expand Down Expand Up @@ -3915,6 +3934,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
{
noway_assert(IsTargetAbi(CORINFO_CORERT_ABI)); // Only CoreRT supports it.
CORINFO_RESOLVED_TOKEN resolvedToken;
resolvedToken.tokenInexactContext = NULL;
resolvedToken.tokenContext = MAKE_METHODCONTEXT(info.compMethodHnd);
resolvedToken.tokenScope = info.compScopeHnd;
resolvedToken.token = memberRef;
Expand Down Expand Up @@ -5316,6 +5336,7 @@ void Compiler::verVerifyCall(OPCODE opcode,
"must create delegates with certain IL");

CORINFO_RESOLVED_TOKEN delegateResolvedToken;
delegateResolvedToken.tokenInexactContext = NULL;
delegateResolvedToken.tokenContext = impTokenLookupContextHandle;
delegateResolvedToken.tokenScope = info.compScopeHnd;
delegateResolvedToken.token = delegateMethodRef;
Expand Down Expand Up @@ -7745,19 +7766,29 @@ var_types Compiler::impImportCall(OPCODE opcode,

if (compIsForInlining())
{
// Don't import runtime lookups when inlining
// Inlining has to be aborted in such a case
/* XXX Fri 3/20/2009
* By the way, this would never succeed. If the handle lookup is into the generic
* dictionary for a candidate, you'll generate different dictionary offsets and the
* inlined code will crash.
*
* To anyone code reviewing this, when could this ever succeed in the future? It'll
* always have a handle lookup. These lookups are safe intra-module, but we're just
* failing here.
*/
compInlineResult->NoteFatal(InlineObservation::CALLSITE_HAS_COMPLEX_HANDLE);
return TYP_UNDEF;
if (info.compInexactContext == NULL)
{
// Don't import runtime lookups when inlining
// Inlining has to be aborted in such a case
/* XXX Fri 3/20/2009
* By the way, this would never succeed. If the handle lookup is into the generic
* dictionary for a candidate, you'll generate different dictionary offsets and the
* inlined code will crash.
*
* To anyone code reviewing this, when could this ever succeed in the future? It'll
* always have a handle lookup. These lookups are safe intra-module, but we're just
* failing here.
*/
compInlineResult->NoteFatal(InlineObservation::CALLSITE_HAS_COMPLEX_HANDLE);
return TYP_UNDEF;
}
else
{
// Use of inexact context in inlining
compInlineResult->Note(InlineObservation::CALLSITE_INLINED_HAS_COMPLEX_HANDLE);
if (compInlineResult->IsFailure())
return TYP_UNDEF;
}
}

GenTree* stubAddr = impRuntimeLookupToTree(pResolvedToken, &callInfo->stubLookup, methHnd);
Expand Down Expand Up @@ -7893,6 +7924,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
{
// This is for a non-virtual, non-interface etc. call
call = gtNewCallNode(CT_USER_FUNC, callInfo->hMethod, callRetTyp, nullptr, ilOffset);
call->AsCall()->inexactContext = callInfo->inexactContextHandle;

// We remove the nullcheck for the GetType call instrinsic.
// TODO-CQ: JIT64 does not introduce the null check for many more helper calls
Expand Down Expand Up @@ -16957,6 +16989,7 @@ void Compiler::impVerifyEHBlock(BasicBlock* block, bool isTryStart)
{
CORINFO_RESOLVED_TOKEN resolvedToken;

resolvedToken.tokenInexactContext = NULL;
resolvedToken.tokenContext = impTokenLookupContextHandle;
resolvedToken.tokenScope = info.compScopeHnd;
resolvedToken.token = HBtab->ebdTyp;
Expand Down Expand Up @@ -20564,6 +20597,7 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
// First, cons up a suitable resolved token.
CORINFO_RESOLVED_TOKEN derivedResolvedToken = {};

derivedResolvedToken.tokenInexactContext = NULL; // TODO This might be wrong here.
derivedResolvedToken.tokenScope = info.compCompHnd->getMethodModule(derivedMethod);
derivedResolvedToken.tokenContext = *contextHandle;
derivedResolvedToken.token = info.compCompHnd->getMethodDefFromMethod(derivedMethod);
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/src/jit/inline.def
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ INLINE_OBSERVATION(PINVOKE_EH, bool, "PInvoke call site with EH
// ------ Call Site Performance -------

INLINE_OBSERVATION(RARE_GC_STRUCT, bool, "rarely called, has gc struct", INFORMATION, CALLSITE)
INLINE_OBSERVATION(INLINED_GENERIC_DICTIONARY_LOOKUP, bool, "runtime dictionary lookup (inlined)", INFORMATION, CALLSITE)
INLINE_OBSERVATION(INLINED_HAS_COMPLEX_HANDLE, bool, "complex handle access (inlined)", INFORMATION, CALLSITE)

// ------ Call Site Information -------

Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,17 @@ public ref CORINFO_CONST_LOOKUP constLookup
}
}

public struct CORINFO_INEXACT_CONTEXT_HANDLE
{
public IntPtr handleValue;
}

public unsafe struct CORINFO_RESOLVED_TOKEN
{
//
// [In] arguments of resolveToken
//
public IntPtr tokenInexactContext;
public CORINFO_CONTEXT_STRUCT* tokenContext; //Context for resolution of generic arguments
public CORINFO_MODULE_STRUCT_* tokenScope;
public mdToken token; //The source token
Expand Down Expand Up @@ -1074,6 +1080,8 @@ public unsafe struct CORINFO_CALL_INFO

public uint _wrapperDelegateInvoke;
public bool wrapperDelegateInvoke { get { return _wrapperDelegateInvoke != 0; } set { _wrapperDelegateInvoke = value ? (byte)1 : (byte)0; } }

public IntPtr inexactContextHandle;
}


Expand Down
Loading