diff options
author | Jarret Shook <jashoo@microsoft.com> | 2019-04-17 11:06:16 -0700 |
---|---|---|
committer | Andy Ayers <andya@microsoft.com> | 2019-04-17 11:06:16 -0700 |
commit | adf6d4661a5f7367e70256ac1c37d71149a37f5b (patch) | |
tree | 7a5d54397a5f800501086874bf25d0fa815012e9 /src/jit/morph.cpp | |
parent | 35172e140236d5197a4d7d19f46d627dd6c119c1 (diff) | |
download | coreclr-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.cpp | 59 |
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); } } |