diff options
author | Brian Sullivan <briansul@microsoft.com> | 2019-01-03 19:11:34 -0800 |
---|---|---|
committer | Brian Sullivan <briansul@microsoft.com> | 2019-01-09 15:57:45 -0800 |
commit | 8c12e27d308a35132f8608c0e6f988ce9617c59a (patch) | |
tree | 95e4f9b6f76838f35be8942005f99b76d65a4861 /src/jit/importer.cpp | |
parent | 5c480a4a83339564d4631762c100a5e12ed87357 (diff) | |
download | coreclr-8c12e27d308a35132f8608c0e6f988ce9617c59a.tar.gz coreclr-8c12e27d308a35132f8608c0e6f988ce9617c59a.tar.bz2 coreclr-8c12e27d308a35132f8608c0e6f988ce9617c59a.zip |
When performing devirtualization we can not do both an unboxing optimization and a tail call optimization
Explicit tail calls are now checked for and blocked from performing an unboxing operation in impDevirtualizeCall
If late devirtualization calls impDevirtualizeCall with an IMPLICIT_TAILCALL we will clear this flag if we
decide to perform the unboxing operation.
Diffstat (limited to 'src/jit/importer.cpp')
-rw-r--r-- | src/jit/importer.cpp | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 47ed202e1b..37b506b6af 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -8590,9 +8590,11 @@ var_types Compiler::impImportCall(OPCODE opcode, assert(obj->gtType == TYP_REF); // See if we can devirtualize. + + bool explicitTailCall = (tailCall & PREFIX_TAILCALL_EXPLICIT) != 0; const bool isLateDevirtualization = false; impDevirtualizeCall(call->AsCall(), &callInfo->hMethod, &callInfo->methodFlags, &callInfo->contextHandle, - &exactContextHnd, isLateDevirtualization); + &exactContextHnd, isLateDevirtualization, explicitTailCall); } if (impIsThis(obj)) @@ -8742,7 +8744,6 @@ DONE: if (info.compCompHnd->canTailCall(info.compMethodHnd, methHnd, exactCalleeHnd, explicitTailCall)) { - canTailCall = true; if (explicitTailCall) { // In case of explicit tail calls, mark it so that it is not considered @@ -20174,6 +20175,7 @@ bool Compiler::IsMathIntrinsic(GenTree* tree) // contextHandle -- [IN/OUT] context handle for the call. Updated iff call devirtualized. // exactContextHnd -- [OUT] updated context handle iff call devirtualized // isLateDevirtualization -- if devirtualization is happening after importation +// isTailCall -- [IN/OUT] true if we plan on using a tail call // // Notes: // Virtual calls in IL will always "invoke" the base class method. @@ -20207,7 +20209,8 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call, unsigned* methodFlags, CORINFO_CONTEXT_HANDLE* contextHandle, CORINFO_CONTEXT_HANDLE* exactContextHandle, - bool isLateDevirtualization) + bool isLateDevirtualization, + bool isTailCall) { assert(call != nullptr); assert(method != nullptr); @@ -20558,6 +20561,12 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call, { JITDUMP("Now have direct call to boxed entry point, looking for unboxed entry point\n"); + if (isTailCall) + { + JITDUMP("Call is an explcit tail call, we cannot perform an unbox\n"); + return; + } + // Note for some shared methods the unboxed entry point requires an extra parameter. bool requiresInstMethodTableArg = false; CORINFO_METHOD_HANDLE unboxedEntryMethod = @@ -20640,6 +20649,16 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call, call->gtCallMethHnd = unboxedEntryMethod; call->gtCallMoreFlags |= GTF_CALL_M_UNBOXED; derivedMethod = unboxedEntryMethod; + + if (call->IsImplicitTailCall()) + { + JITDUMP("Clearing the implicit tail call flag\n"); + + // If set, we clear the implicit tail call flag + // as we just introduced a new address taken local variable + // + call->gtCallMoreFlags &= ~GTF_CALL_M_IMPLICIT_TAILCALL; + } } else { |