Remove the LocAllocSP slot for non-x86 platforms
authorBruce Forstall <Bruce_Forstall@msn.com>
Tue, 23 Oct 2018 04:39:16 +0000 (21:39 -0700)
committerBruce Forstall <Bruce_Forstall@msn.com>
Tue, 23 Oct 2018 04:39:16 +0000 (21:39 -0700)
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
src/coreclr/src/jit/codegenarm64.cpp
src/coreclr/src/jit/codegencommon.cpp
src/coreclr/src/jit/codegenxarch.cpp
src/coreclr/src/jit/compiler.h
src/coreclr/src/jit/gentree.cpp
src/coreclr/src/jit/lclvars.cpp

index 7c2058c..b198da5 100644 (file)
@@ -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)
     {
index 3d5cedd..6aad5d9 100644 (file)
@@ -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)
     {
index 4d908da..0d4cd7d 100644 (file)
@@ -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
 
index 4946421..54ff6dc 100644 (file)
@@ -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)
index c1b60d8..87ab444 100644 (file)
@@ -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
 
index 443aec2..926aab7 100644 (file)
@@ -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)
             {
index 7cee828..645f3fe 100644 (file)
@@ -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.
  */