From 85c59f9aa92092e72618df51879a9338ca9d4307 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Wed, 23 Aug 2017 09:16:07 -0700 Subject: [PATCH] JIT: refine types when creating arg temps to improve devirtualization (#13530) The jit will refine the types of temps used to pass arguments to inlinees when it creates the assignments to these temps. Unfortunately this is too late to drive devirtualization in the body of the inlinee, as thes assignments are created after the inlinee body is imported. So, add similar refinement logic to the place where the temps are first created. Closes #13520. --- src/jit/flowgraph.cpp | 11 ++++------- src/jit/importer.cpp | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp index 7790363..d6afead 100644 --- a/src/jit/flowgraph.cpp +++ b/src/jit/flowgraph.cpp @@ -22625,13 +22625,10 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo) impAssignTempGen(tmpNum, argNode, structHnd, (unsigned)CHECK_SPILL_NONE, &afterStmt, callILOffset, block); - // If we know the argument's value can't be - // changed within the method body, try and improve - // the type of the temp. - if (argIsSingleDef && (argType == TYP_REF)) - { - lvaUpdateClass(tmpNum, argNode); - } + // We used to refine the temp type here based on + // the actual arg, but we now do this up front, when + // creating the temp, over in impInlineFetchArg. + CLANG_FORMAT_COMMENT_ANCHOR; #ifdef DEBUG if (verbose) diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 46ca8ff..b824e6b 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -18165,11 +18165,22 @@ GenTreePtr Compiler::impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo, lvaTable[tmpNum].lvType = lclTyp; - // Copy over class handle for ref types. Note this may be - // further improved if it is a shared type and we know the exact context. + // For ref types, determine the type of the temp. if (lclTyp == TYP_REF) { - lvaSetClass(tmpNum, lclInfo.lclVerTypeInfo.GetClassHandleForObjRef()); + if (!argCanBeModified) + { + // If the arg can't be modified in the method + // body, use the type of the value, if + // known. Otherwise, use the declared type. + lvaSetClass(tmpNum, argInfo.argNode, lclInfo.lclVerTypeInfo.GetClassHandleForObjRef()); + } + else + { + // Arg might be modified, use the delcared type of + // the argument. + lvaSetClass(tmpNum, lclInfo.lclVerTypeInfo.GetClassHandleForObjRef()); + } } assert(lvaTable[tmpNum].lvAddrExposed == 0); -- 2.7.4