From 567dda08e1b93631e202b28e2a7614dc4304c324 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Mon, 22 Oct 2018 21:39:16 -0700 Subject: [PATCH] Remove the LocAllocSP slot for non-x86 platforms This special local variable is only needed on x86 when a function contains localloc. Commit migrated from https://github.com/dotnet/coreclr/commit/c8a63947382b0db428db602238199ca81badbe8e --- src/coreclr/src/jit/codegenarm.cpp | 6 ------ src/coreclr/src/jit/codegenarm64.cpp | 6 ------ src/coreclr/src/jit/codegencommon.cpp | 9 +++------ src/coreclr/src/jit/codegenxarch.cpp | 7 +++++-- src/coreclr/src/jit/compiler.h | 6 +++++- src/coreclr/src/jit/gentree.cpp | 2 ++ src/coreclr/src/jit/lclvars.cpp | 33 +++++++++++++++++++++++++-------- 7 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/coreclr/src/jit/codegenarm.cpp b/src/coreclr/src/jit/codegenarm.cpp index 7c2058c..b198da5 100644 --- a/src/coreclr/src/jit/codegenarm.cpp +++ b/src/coreclr/src/jit/codegenarm.cpp @@ -527,12 +527,6 @@ BAILOUT: if (endLabel != nullptr) genDefineTempLabel(endLabel); - // Write the lvaLocAllocSPvar stack frame slot - if (compiler->lvaLocAllocSPvar != BAD_VAR_NUM) - { - getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, regCnt, compiler->lvaLocAllocSPvar, 0); - } - #if STACK_PROBES if (compiler->opts.compNeedStackProbes) { diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index 3d5cedd..6aad5d9 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -2139,12 +2139,6 @@ BAILOUT: if (endLabel != nullptr) genDefineTempLabel(endLabel); - // Write the lvaLocAllocSPvar stack frame slot - if (compiler->lvaLocAllocSPvar != BAD_VAR_NUM) - { - getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, targetReg, compiler->lvaLocAllocSPvar, 0); - } - #if STACK_PROBES if (compiler->opts.compNeedStackProbes) { diff --git a/src/coreclr/src/jit/codegencommon.cpp b/src/coreclr/src/jit/codegencommon.cpp index 4d908da..0d4cd7d 100644 --- a/src/coreclr/src/jit/codegencommon.cpp +++ b/src/coreclr/src/jit/codegencommon.cpp @@ -8361,16 +8361,13 @@ void CodeGen::genFnProlog() (compiler->lvaTable[compiler->lvaSecurityObject].lvOnFrame && compiler->lvaTable[compiler->lvaSecurityObject].lvMustInit)); - // Initialize any "hidden" slots/locals - +#ifdef JIT32_GCENCODER + // Initialize the LocalAllocSP slot if there is localloc in the function. if (compiler->lvaLocAllocSPvar != BAD_VAR_NUM) { -#ifdef _TARGET_ARM64_ - getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_FPBASE, compiler->lvaLocAllocSPvar, 0); -#else getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_SPBASE, compiler->lvaLocAllocSPvar, 0); -#endif } +#endif // JIT32_GCENCODER // Set up the GS security cookie diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index 4946421..54ff6dc 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -2130,7 +2130,9 @@ void CodeGen::genMultiRegCallStoreToLocal(GenTree* treeNode) // The ESP tracking is used to report stack pointer-relative GC info, which is not // interesting while doing the localloc construction. Also, for functions with localloc, // we have EBP frames, and EBP-relative locals, and ESP-relative accesses only for function -// call arguments. We store the ESP after the localloc is complete in the LocAllocSP +// call arguments. +// +// For x86, we store the ESP after the localloc is complete in the LocAllocSP // variable. This variable is implicitly reported to the VM in the GC info (its position // is defined by convention relative to other items), and is used by the GC to find the // "base" stack pointer in functions with localloc. @@ -2456,11 +2458,12 @@ ALLOC_DONE: BAILOUT: - // Write the lvaLocAllocSPvar stack frame slot +#ifdef JIT32_GCENCODER if (compiler->lvaLocAllocSPvar != BAD_VAR_NUM) { getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_SPBASE, compiler->lvaLocAllocSPvar, 0); } +#endif // JIT32_GCENCODER #if STACK_PROBES if (compiler->opts.compNeedStackProbes) diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index c1b60d8..87ab444 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -2884,7 +2884,11 @@ public: int lvaCachedGenericContextArgOffset(); // For CORINFO_CALLCONV_PARAMTYPE and if generic context is passed as // THIS pointer - unsigned lvaLocAllocSPvar; // variable which has the result of the last alloca/localloc +#ifdef JIT32_GCENCODER + + unsigned lvaLocAllocSPvar; // variable which stores the value of ESP after the the last alloca/localloc + +#endif // JIT32_GCENCODER unsigned lvaNewObjArrayArgs; // variable with arguments for new MD array helper diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index 443aec2..926aab7 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -10113,10 +10113,12 @@ void Compiler::gtGetLclVarNameInfo(unsigned lclNum, const char** ilKindOut, cons ilName = "EHSlots"; } #endif // !FEATURE_EH_FUNCLETS +#ifdef JIT32_GCENCODER else if (lclNum == lvaLocAllocSPvar) { ilName = "LocAllocSP"; } +#endif // JIT32_GCENCODER #if FEATURE_EH_FUNCLETS else if (lclNum == lvaPSPSym) { diff --git a/src/coreclr/src/jit/lclvars.cpp b/src/coreclr/src/jit/lclvars.cpp index 7cee828..645f3fe 100644 --- a/src/coreclr/src/jit/lclvars.cpp +++ b/src/coreclr/src/jit/lclvars.cpp @@ -57,7 +57,9 @@ void Compiler::lvaInit() #ifdef _TARGET_ARM_ lvaPromotedStructAssemblyScratchVar = BAD_VAR_NUM; #endif // _TARGET_ARM_ - lvaLocAllocSPvar = BAD_VAR_NUM; +#ifdef JIT32_GCENCODER + lvaLocAllocSPvar = BAD_VAR_NUM; +#endif // JIT32_GCENCODER lvaNewObjArrayArgs = BAD_VAR_NUM; lvaGSSecurityCookie = BAD_VAR_NUM; #ifdef _TARGET_X86_ @@ -3951,14 +3953,27 @@ void Compiler::lvaMarkLocalVars() } #endif // FEATURE_EH_FUNCLETS - // TODO: LocAllocSPvar should be only required by the implicit frame layout expected by the VM on x86. - // It should be removed on other platforms once we check there are no other implicit dependencies. +#ifdef JIT32_GCENCODER + // LocAllocSPvar is only required by the implicit frame layout expected by the VM on x86. Whether + // a function contains a Localloc is conveyed in the GC information, in the InfoHdrSmall.localloc + // field. The function must have an EBP frame. Then, the VM finds the LocAllocSP slot by assuming + // the following stack layout: + // + // -- higher addresses -- + // saved EBP <-- EBP points here + // other callee-saved registers // InfoHdrSmall.savedRegsCountExclFP specifies this size + // optional GS cookie // InfoHdrSmall.security is 1 if this exists + // LocAllocSP slot + // -- lower addresses -- + // + // See also eetwain.cpp::GetLocallocSPOffset() and its callers. if (compLocallocUsed) { lvaLocAllocSPvar = lvaGrabTempWithImplicitUse(false DEBUGARG("LocAllocSPvar")); LclVarDsc* locAllocSPvar = &lvaTable[lvaLocAllocSPvar]; locAllocSPvar->lvType = TYP_I_IMPL; } +#endif // JIT32_GCENCODER } // Ref counting is now enabled normally. @@ -5688,13 +5703,13 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals() stkOffs = lvaAllocLocalAndSetVirtualOffset(lvaSecurityObject, TARGET_POINTER_SIZE, stkOffs); } +#ifdef JIT32_GCENCODER if (lvaLocAllocSPvar != BAD_VAR_NUM) { -#ifdef JIT32_GCENCODER noway_assert(codeGen->isFramePointerUsed()); // else offsets of locals of frameless methods will be incorrect -#endif stkOffs = lvaAllocLocalAndSetVirtualOffset(lvaLocAllocSPvar, TARGET_POINTER_SIZE, stkOffs); } +#endif // JIT32_GCENCODER if (lvaReportParamTypeArg()) { @@ -5886,7 +5901,10 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals() #else lclNum == lvaShadowSPslotsVar || #endif // FEATURE_EH_FUNCLETS - lclNum == lvaLocAllocSPvar || lclNum == lvaSecurityObject) +#ifdef JIT32_GCENCODER + lclNum == lvaLocAllocSPvar || +#endif // JIT32_GCENCODER + lclNum == lvaSecurityObject) { assert(varDsc->lvStkOffs != BAD_STK_OFFS); continue; @@ -6658,8 +6676,7 @@ void Compiler::lvaDumpRegLocation(unsigned lclNum) /***************************************************************************** * * Dump the frame location assigned to a local. - * For non-LSRA, this will only be valid if there is no assigned register. - * For LSRA, it's the home location, even though the variable doesn't always live + * It's the home location, even though the variable doesn't always live * in its home location. */ -- 2.7.4