From: Sergey Andreenko Date: Mon, 27 Mar 2017 19:46:59 +0000 (-0700) Subject: small changes in fgOptimizeDelegateConstructor X-Git-Tag: submit/tizen/20210909.063632~11030^2~7524^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8f2d4c785d754009899ae3531156203033ac515f;p=platform%2Fupstream%2Fdotnet%2Fruntime.git small changes in fgOptimizeDelegateConstructor Delete unnecessary condition. Use default methods to work with lists. ArgList construction reordering. Commit migrated from https://github.com/dotnet/coreclr/commit/1502744c6915bf4b53e64fe766f7136a2edd0fd3 --- diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index 6cd5f3a..79c9550 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -7065,124 +7065,119 @@ GenTreePtr Compiler::fgOptimizeDelegateConstructor(GenTreeCall* call, CORINFO_CO CORINFO_METHOD_HANDLE methHnd = call->gtCallMethHnd; CORINFO_CLASS_HANDLE clsHnd = info.compCompHnd->getMethodClass(methHnd); - GenTreePtr targetMethod = call->gtCallArgs->gtOp.gtOp2->gtOp.gtOp1; + GenTreePtr targetMethod = call->gtCallArgs->Rest()->Current(); noway_assert(targetMethod->TypeGet() == TYP_I_IMPL); - genTreeOps oper = targetMethod->OperGet(); - if (oper == GT_FTN_ADDR || oper == GT_CALL || oper == GT_QMARK) + genTreeOps oper = targetMethod->OperGet(); + CORINFO_METHOD_HANDLE targetMethodHnd = nullptr; + GenTreePtr qmarkNode = nullptr; + if (oper == GT_FTN_ADDR) { - CORINFO_METHOD_HANDLE targetMethodHnd = nullptr; - GenTreePtr qmarkNode = nullptr; - if (oper == GT_FTN_ADDR) - { - targetMethodHnd = targetMethod->gtFptrVal.gtFptrMethod; - } - else if (oper == GT_CALL && targetMethod->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_VIRTUAL_FUNC_PTR)) - { - GenTreePtr handleNode = targetMethod->gtCall.gtCallArgs->gtOp.gtOp2->gtOp.gtOp2->gtOp.gtOp1; + targetMethodHnd = targetMethod->gtFptrVal.gtFptrMethod; + } + else if (oper == GT_CALL && targetMethod->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_VIRTUAL_FUNC_PTR)) + { + GenTreePtr handleNode = targetMethod->gtCall.gtCallArgs->Rest()->Rest()->Current(); - if (handleNode->OperGet() == GT_CNS_INT) - { - // it's a ldvirtftn case, fetch the methodhandle off the helper for ldvirtftn. It's the 3rd arg - targetMethodHnd = CORINFO_METHOD_HANDLE(handleNode->gtIntCon.gtCompileTimeHandle); - } - // Sometimes the argument to this is the result of a generic dictionary lookup, which shows - // up as a GT_QMARK. - else if (handleNode->OperGet() == GT_QMARK) - { - qmarkNode = handleNode; - } - } - // Sometimes we don't call CORINFO_HELP_VIRTUAL_FUNC_PTR but instead just call - // CORINFO_HELP_RUNTIMEHANDLE_METHOD directly. - else if (oper == GT_QMARK) + if (handleNode->OperGet() == GT_CNS_INT) { - qmarkNode = targetMethod; + // it's a ldvirtftn case, fetch the methodhandle off the helper for ldvirtftn. It's the 3rd arg + targetMethodHnd = CORINFO_METHOD_HANDLE(handleNode->gtIntCon.gtCompileTimeHandle); } - if (qmarkNode) + // Sometimes the argument to this is the result of a generic dictionary lookup, which shows + // up as a GT_QMARK. + else if (handleNode->OperGet() == GT_QMARK) { - noway_assert(qmarkNode->OperGet() == GT_QMARK); - // The argument is actually a generic dictionary lookup. For delegate creation it looks - // like: - // GT_QMARK - // GT_COLON - // op1 -> call - // Arg 1 -> token (has compile time handle) - // op2 -> lclvar - // - // - // In this case I can find the token (which is a method handle) and that is the compile time - // handle. - noway_assert(qmarkNode->gtOp.gtOp2->OperGet() == GT_COLON); - noway_assert(qmarkNode->gtOp.gtOp2->gtOp.gtOp1->OperGet() == GT_CALL); - GenTreeCall* runtimeLookupCall = qmarkNode->gtOp.gtOp2->gtOp.gtOp1->AsCall(); - - // This could be any of CORINFO_HELP_RUNTIMEHANDLE_(METHOD|CLASS)(_LOG?) - GenTreePtr tokenNode = runtimeLookupCall->gtCallArgs->gtOp.gtOp2->gtOp.gtOp1; - noway_assert(tokenNode->OperGet() == GT_CNS_INT); - targetMethodHnd = CORINFO_METHOD_HANDLE(tokenNode->gtIntCon.gtCompileTimeHandle); + qmarkNode = handleNode; } + } + // Sometimes we don't call CORINFO_HELP_VIRTUAL_FUNC_PTR but instead just call + // CORINFO_HELP_RUNTIMEHANDLE_METHOD directly. + else if (oper == GT_QMARK) + { + qmarkNode = targetMethod; + } + if (qmarkNode) + { + noway_assert(qmarkNode->OperGet() == GT_QMARK); + // The argument is actually a generic dictionary lookup. For delegate creation it looks + // like: + // GT_QMARK + // GT_COLON + // op1 -> call + // Arg 1 -> token (has compile time handle) + // op2 -> lclvar + // + // + // In this case I can find the token (which is a method handle) and that is the compile time + // handle. + noway_assert(qmarkNode->gtOp.gtOp2->OperGet() == GT_COLON); + noway_assert(qmarkNode->gtOp.gtOp2->gtOp.gtOp1->OperGet() == GT_CALL); + GenTreeCall* runtimeLookupCall = qmarkNode->gtOp.gtOp2->gtOp.gtOp1->AsCall(); + + // This could be any of CORINFO_HELP_RUNTIMEHANDLE_(METHOD|CLASS)(_LOG?) + GenTreePtr tokenNode = runtimeLookupCall->gtCallArgs->gtOp.gtOp2->gtOp.gtOp1; + noway_assert(tokenNode->OperGet() == GT_CNS_INT); + targetMethodHnd = CORINFO_METHOD_HANDLE(tokenNode->gtIntCon.gtCompileTimeHandle); + } #ifdef FEATURE_READYTORUN_COMPILER - if (opts.IsReadyToRun()) + if (opts.IsReadyToRun()) + { + // ReadyToRun has this optimization for a non-virtual function pointers only for now. + if (oper == GT_FTN_ADDR) { - // ReadyToRun has this optimization for a non-virtual function pointers only for now. - if (oper == GT_FTN_ADDR) - { - // The first argument of the helper is delegate this pointer - GenTreeArgList* helperArgs = gtNewArgList(call->gtCallObjp); - CORINFO_CONST_LOOKUP entryPoint; + GenTreePtr thisPointer = call->gtCallObjp; + GenTreePtr targetObjPointers = call->gtCallArgs->Current(); + GenTreeArgList* helperArgs = gtNewArgList(thisPointer, targetObjPointers); - // The second argument of the helper is the target object pointers - helperArgs->gtOp.gtOp2 = gtNewArgList(call->gtCallArgs->gtOp.gtOp1); + call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_DELEGATE_CTOR, TYP_VOID, GTF_EXCEPT, helperArgs); - call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_DELEGATE_CTOR, TYP_VOID, GTF_EXCEPT, helperArgs); - info.compCompHnd->getReadyToRunDelegateCtorHelper(targetMethod->gtFptrVal.gtLdftnResolvedToken, clsHnd, - &entryPoint); - call->setEntryPoint(entryPoint); - } + CORINFO_RESOLVED_TOKEN* ldftnToken = targetMethod->gtFptrVal.gtLdftnResolvedToken; + CORINFO_CONST_LOOKUP entryPoint; + info.compCompHnd->getReadyToRunDelegateCtorHelper(ldftnToken, clsHnd, &entryPoint); + call->setEntryPoint(entryPoint); } - else + } + else #endif - if (targetMethodHnd != nullptr) - { - CORINFO_METHOD_HANDLE alternateCtor = nullptr; - DelegateCtorArgs ctorData; - ctorData.pMethod = info.compMethodHnd; - ctorData.pArg3 = nullptr; - ctorData.pArg4 = nullptr; - ctorData.pArg5 = nullptr; - - alternateCtor = info.compCompHnd->GetDelegateCtor(methHnd, clsHnd, targetMethodHnd, &ctorData); - if (alternateCtor != methHnd) - { - // we erase any inline info that may have been set for generics has it is not needed here, - // and in fact it will pass the wrong info to the inliner code - *ExactContextHnd = nullptr; - - call->gtCallMethHnd = alternateCtor; + if (targetMethodHnd != nullptr) + { + CORINFO_METHOD_HANDLE alternateCtor = nullptr; + DelegateCtorArgs ctorData; + ctorData.pMethod = info.compMethodHnd; + ctorData.pArg3 = nullptr; + ctorData.pArg4 = nullptr; + ctorData.pArg5 = nullptr; - noway_assert(call->gtCallArgs->gtOp.gtOp2->gtOp.gtOp2 == nullptr); - if (ctorData.pArg3) - { - call->gtCallArgs->gtOp.gtOp2->gtOp.gtOp2 = - gtNewArgList(gtNewIconHandleNode(size_t(ctorData.pArg3), GTF_ICON_FTN_ADDR)); + alternateCtor = info.compCompHnd->GetDelegateCtor(methHnd, clsHnd, targetMethodHnd, &ctorData); + if (alternateCtor != methHnd) + { + // we erase any inline info that may have been set for generics has it is not needed here, + // and in fact it will pass the wrong info to the inliner code + *ExactContextHnd = nullptr; - if (ctorData.pArg4) - { - call->gtCallArgs->gtOp.gtOp2->gtOp.gtOp2->gtOp.gtOp2 = - gtNewArgList(gtNewIconHandleNode(size_t(ctorData.pArg4), GTF_ICON_FTN_ADDR)); + call->gtCallMethHnd = alternateCtor; - if (ctorData.pArg5) - { - call->gtCallArgs->gtOp.gtOp2->gtOp.gtOp2->gtOp.gtOp2->gtOp.gtOp2 = - gtNewArgList(gtNewIconHandleNode(size_t(ctorData.pArg5), GTF_ICON_FTN_ADDR)); - } - } - } + noway_assert(call->gtCallArgs->Rest()->Rest() == nullptr); + GenTreeArgList* addArgs = nullptr; + if (ctorData.pArg5) + { + GenTreePtr arg5 = gtNewIconHandleNode(size_t(ctorData.pArg5), GTF_ICON_FTN_ADDR); + addArgs = gtNewListNode(arg5, addArgs); + } + if (ctorData.pArg4) + { + GenTreePtr arg4 = gtNewIconHandleNode(size_t(ctorData.pArg4), GTF_ICON_FTN_ADDR); + addArgs = gtNewListNode(arg4, addArgs); } + if (ctorData.pArg3) + { + GenTreePtr arg3 = gtNewIconHandleNode(size_t(ctorData.pArg3), GTF_ICON_FTN_ADDR); + addArgs = gtNewListNode(arg3, addArgs); + } + call->gtCallArgs->Rest()->Rest() = addArgs; } } - return call; }