summaryrefslogtreecommitdiff
path: root/src/jit/morph.cpp
diff options
context:
space:
mode:
authorJarret Shook <jashoo@microsoft.com>2019-04-17 11:06:16 -0700
committerAndy Ayers <andya@microsoft.com>2019-04-17 11:06:16 -0700
commitadf6d4661a5f7367e70256ac1c37d71149a37f5b (patch)
tree7a5d54397a5f800501086874bf25d0fa815012e9 /src/jit/morph.cpp
parent35172e140236d5197a4d7d19f46d627dd6c119c1 (diff)
downloadcoreclr-adf6d4661a5f7367e70256ac1c37d71149a37f5b.tar.gz
coreclr-adf6d4661a5f7367e70256ac1c37d71149a37f5b.tar.bz2
coreclr-adf6d4661a5f7367e70256ac1c37d71149a37f5b.zip
Add lvIsImplicitByRef information to lvaSetStruct (#19223)
Before implicit byrefs were tracked by setting lvIsParam and lvIsTemp. This change explicitly adds a flag for implicitByRef instead of overloading. In addition, it fixes the decision to copy an implicitByRef for arm64 varargs. Temporarily bump weight on byref params to match old behavior and avoid codegen diffs. Re-enabled various tests and parts of tests. Closes #20046 Closes #19860
Diffstat (limited to 'src/jit/morph.cpp')
-rw-r--r--src/jit/morph.cpp59
1 files changed, 12 insertions, 47 deletions
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp
index fbfa173311..83e069cebf 100644
--- a/src/jit/morph.cpp
+++ b/src/jit/morph.cpp
@@ -17061,9 +17061,8 @@ void Compiler::fgMorph()
fgUpdateFinallyTargetFlags();
/* For x64 and ARM64 we need to mark irregular parameters */
-
lvaRefCountState = RCS_EARLY;
- fgMarkImplicitByRefArgs();
+ fgResetImplicitByRefRefCount();
/* Promote struct locals if necessary */
fgPromoteStructs();
@@ -17491,63 +17490,29 @@ void Compiler::fgMorphLocalField(GenTree* tree, GenTree* parent)
}
//------------------------------------------------------------------------
-// fgMarkImplicitByRefArgs: Identify any by-value struct parameters which are "implicit by-reference";
-// i.e. which the ABI requires to be passed by making a copy in the caller and
-// passing its address to the callee. Mark their `LclVarDsc`s such that
-// `lvaIsImplicitByRefLocal` will return true for them.
+// fgResetImplicitByRefRefCount: Clear the ref count field of all implicit byrefs
-void Compiler::fgMarkImplicitByRefArgs()
+void Compiler::fgResetImplicitByRefRefCount()
{
#if (defined(_TARGET_AMD64_) && !defined(UNIX_AMD64_ABI)) || defined(_TARGET_ARM64_)
#ifdef DEBUG
if (verbose)
{
- printf("\n*************** In fgMarkImplicitByRefs()\n");
+ printf("\n*************** In fgResetImplicitByRefRefCount()\n");
}
#endif // DEBUG
- for (unsigned lclNum = 0; lclNum < info.compArgsCount; lclNum++)
+ for (unsigned lclNum = 0; lclNum < info.compArgsCount; ++lclNum)
{
- LclVarDsc* varDsc = &lvaTable[lclNum];
+ LclVarDsc* varDsc = lvaGetDesc(lclNum);
- if (varDsc->lvIsParam && varTypeIsStruct(varDsc))
+ if (varDsc->lvIsImplicitByRef)
{
- size_t size = varDsc->lvExactSize;
- assert(size == info.compCompHnd->getClassSize(varDsc->lvVerTypeInfo.GetClassHandle()));
-
- bool isPassedByReference;
-#if defined(_TARGET_AMD64_)
- isPassedByReference = (size > REGSIZE_BYTES || (size & (size - 1)) != 0);
-#elif defined(_TARGET_ARM64_)
- if (size > TARGET_POINTER_SIZE)
- {
- CORINFO_CLASS_HANDLE clsHnd = varDsc->lvVerTypeInfo.GetClassHandleForValueClass();
- structPassingKind howToPassStruct;
- var_types type =
- getArgTypeForStruct(clsHnd, &howToPassStruct, this->info.compIsVarArgs, varDsc->lvExactSize);
- isPassedByReference = (howToPassStruct == SPK_ByReference);
- }
- else
- {
- isPassedByReference = false;
- }
-#endif
-
- if (isPassedByReference)
- {
- // Previously nobody was ever setting lvIsParam and lvIsTemp on the same local
- // So I am now using it to indicate that this is one of the weird implicit
- // by ref locals.
- // The address taken cleanup will look for references to locals marked like
- // this, and transform them appropriately.
- varDsc->lvIsTemp = 1;
-
- // Clear the ref count field; fgMarkAddressTakenLocals will increment it per
- // appearance of implicit-by-ref param so that call arg morphing can do an
- // optimization for single-use implicit-by-ref params whose single use is as
- // an outgoing call argument.
- varDsc->setLvRefCnt(0, RCS_EARLY);
- }
+ // Clear the ref count field; fgMarkAddressTakenLocals will increment it per
+ // appearance of implicit-by-ref param so that call arg morphing can do an
+ // optimization for single-use implicit-by-ref params whose single use is as
+ // an outgoing call argument.
+ varDsc->setLvRefCnt(0, RCS_EARLY);
}
}