summaryrefslogtreecommitdiff
path: root/src/jit/flowgraph.cpp
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2018-10-29 16:11:53 -0700
committerGitHub <noreply@github.com>2018-10-29 16:11:53 -0700
commitccc18a6352c7a6232606131424c0377ea3529991 (patch)
tree1481a71638bc2add48809936543d2aad25055123 /src/jit/flowgraph.cpp
parent17879dfcda03bb47571daab2addb318ef47b04d9 (diff)
downloadcoreclr-ccc18a6352c7a6232606131424c0377ea3529991.tar.gz
coreclr-ccc18a6352c7a6232606131424c0377ea3529991.tar.bz2
coreclr-ccc18a6352c7a6232606131424c0377ea3529991.zip
JIT: streamline temp usage for returns (#20640)
If the jit decides it needs a return spill temp, and the return value has already been spilled to a single-def temp, re-use the existing for the return temp rather than creating a new one. In conjunction with #20553 this allows late devirtualization for calls where the object in the virtual call is the result of an inline that provides a better type, and the objected formerly reached the call via one or more intermediate temps. Closes #15873.
Diffstat (limited to 'src/jit/flowgraph.cpp')
-rw-r--r--src/jit/flowgraph.cpp35
1 files changed, 25 insertions, 10 deletions
diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp
index 7c5e264220..b2846ed7cf 100644
--- a/src/jit/flowgraph.cpp
+++ b/src/jit/flowgraph.cpp
@@ -5853,19 +5853,34 @@ void Compiler::fgFindBasicBlocks()
// or if the inlinee has GC ref locals.
if ((info.compRetNativeType != TYP_VOID) && ((retBlocks > 1) || impInlineInfo->HasGcRefLocals()))
{
- // The lifetime of this var might expand multiple BBs. So it is a long lifetime compiler temp.
- lvaInlineeReturnSpillTemp = lvaGrabTemp(false DEBUGARG("Inline return value spill temp"));
- lvaTable[lvaInlineeReturnSpillTemp].lvType = info.compRetNativeType;
+ // If we've spilled the ret expr to a temp we can reuse the temp
+ // as the inlinee return spill temp.
+ //
+ // Todo: see if it is even better to always use this existing temp
+ // for return values, even if we otherwise wouldn't need a return spill temp...
+ lvaInlineeReturnSpillTemp = impInlineInfo->inlineCandidateInfo->preexistingSpillTemp;
- // If the method returns a ref class, set the class of the spill temp
- // to the method's return value. We may update this later if it turns
- // out we can prove the method returns a more specific type.
- if (info.compRetType == TYP_REF)
+ if (lvaInlineeReturnSpillTemp != BAD_VAR_NUM)
+ {
+ // This temp should already have the type of the return value.
+ JITDUMP("\nInliner: re-using pre-existing spill temp V%02u\n", lvaInlineeReturnSpillTemp);
+ }
+ else
{
- CORINFO_CLASS_HANDLE retClassHnd = impInlineInfo->inlineCandidateInfo->methInfo.args.retTypeClass;
- if (retClassHnd != nullptr)
+ // The lifetime of this var might expand multiple BBs. So it is a long lifetime compiler temp.
+ lvaInlineeReturnSpillTemp = lvaGrabTemp(false DEBUGARG("Inline return value spill temp"));
+ lvaTable[lvaInlineeReturnSpillTemp].lvType = info.compRetNativeType;
+
+ // If the method returns a ref class, set the class of the spill temp
+ // to the method's return value. We may update this later if it turns
+ // out we can prove the method returns a more specific type.
+ if (info.compRetType == TYP_REF)
{
- lvaSetClass(lvaInlineeReturnSpillTemp, retClassHnd);
+ CORINFO_CLASS_HANDLE retClassHnd = impInlineInfo->inlineCandidateInfo->methInfo.args.retTypeClass;
+ if (retClassHnd != nullptr)
+ {
+ lvaSetClass(lvaInlineeReturnSpillTemp, retClassHnd);
+ }
}
}
}