JIT: refactor IsOSRLocal (#67247)
authorAndy Ayers <andya@microsoft.com>
Tue, 29 Mar 2022 01:27:55 +0000 (18:27 -0700)
committerGitHub <noreply@github.com>
Tue, 29 Mar 2022 01:27:55 +0000 (18:27 -0700)
Make this a property of the local, in anticipation of needing to check this in
cases where we won't have access to the compiler object.

Unify marking of OSR exposed locals.

src/coreclr/jit/compiler.cpp
src/coreclr/jit/compiler.h
src/coreclr/jit/lclvars.cpp
src/coreclr/jit/scopeinfo.cpp

index e348db6..0920016 100644 (file)
@@ -9734,24 +9734,16 @@ bool Compiler::killGCRefs(GenTree* tree)
 
 bool Compiler::lvaIsOSRLocal(unsigned varNum)
 {
-    if (!opts.IsOSR())
-    {
-        return false;
-    }
+    LclVarDsc* const varDsc = lvaGetDesc(varNum);
 
-    if (varNum < info.compLocalsCount)
-    {
-        return true;
-    }
-
-    LclVarDsc* varDsc = lvaGetDesc(varNum);
-
-    if (varDsc->lvIsStructField)
+#ifdef DEBUG
+    if (!opts.IsOSR())
     {
-        return (varDsc->lvParentLcl < info.compLocalsCount);
+        assert(!varDsc->lvIsOSRLocal);
     }
+#endif
 
-    return false;
+    return varDsc->lvIsOSRLocal;
 }
 
 //------------------------------------------------------------------------------
index 71336c6..3e69386 100644 (file)
@@ -592,6 +592,9 @@ public:
                                          // the prolog. If the local has gc pointers, there are no gc-safe points
                                          // between the prolog and the explicit initialization.
 
+    unsigned char lvIsOSRLocal : 1; // Root method local in an OSR method. Any stack home will be on the Tier0 frame.
+                                    // Initial value will be defined by Tier0. Requires special handing in prolog.
+
     union {
         unsigned lvFieldLclStart; // The index of the local var representing the first field in the promoted struct
                                   // local.  For implicit byref parameters, this gets hijacked between
index 01fca4b..cd13f96 100644 (file)
@@ -303,19 +303,6 @@ void Compiler::lvaInitTypeRef()
             CORINFO_CLASS_HANDLE clsHnd = info.compCompHnd->getArgClass(&info.compMethodInfo->locals, localsSig);
             lvaSetClass(varNum, clsHnd);
         }
-
-        if (opts.IsOSR() && info.compPatchpointInfo->IsExposed(varNum))
-        {
-            JITDUMP("-- V%02u is OSR exposed\n", varNum);
-            varDsc->lvHasLdAddrOp = 1;
-
-            // todo: Why does it apply only to non-structs?
-            //
-            if (!varTypeIsStruct(varDsc) && !varTypeIsSIMD(varDsc))
-            {
-                lvaSetVarAddrExposed(varNum DEBUGARG(AddressExposedReason::OSR_EXPOSED));
-            }
-        }
     }
 
     if ( // If there already exist unsafe buffers, don't mark more structs as unsafe
@@ -338,6 +325,33 @@ void Compiler::lvaInitTypeRef()
         }
     }
 
+    // If this is an OSR method, mark all the OSR locals and model OSR exposure.
+    //
+    // Do this before we add the GS Cookie Dummy or Outgoing args to the locals
+    // so we don't have to do special checks to exclude them.
+    //
+    if (opts.IsOSR())
+    {
+        for (unsigned lclNum = 0; lclNum < lvaCount; lclNum++)
+        {
+            LclVarDsc* const varDsc = lvaGetDesc(lclNum);
+            varDsc->lvIsOSRLocal    = true;
+
+            if (info.compPatchpointInfo->IsExposed(lclNum))
+            {
+                JITDUMP("-- V%02u is OSR exposed\n", lclNum);
+                varDsc->lvHasLdAddrOp = 1;
+
+                // todo: Why does it apply only to non-structs?
+                //
+                if (!varTypeIsStruct(varDsc) && !varTypeIsSIMD(varDsc))
+                {
+                    lvaSetVarAddrExposed(lclNum DEBUGARG(AddressExposedReason::OSR_EXPOSED));
+                }
+            }
+        }
+    }
+
     if (getNeedsGSSecurityCookie())
     {
         // Ensure that there will be at least one stack variable since
@@ -1113,13 +1127,6 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
             lvaSetVarAddrExposed(varDscInfo->varNum DEBUGARG(AddressExposedReason::TOO_CONSERVATIVE));
 #endif // !TARGET_X86
         }
-
-        if (opts.IsOSR() && info.compPatchpointInfo->IsExposed(varDscInfo->varNum))
-        {
-            JITDUMP("-- V%02u is OSR exposed\n", varDscInfo->varNum);
-            varDsc->lvHasLdAddrOp = 1;
-            lvaSetVarAddrExposed(varDscInfo->varNum DEBUGARG(AddressExposedReason::OSR_EXPOSED));
-        }
     }
 
     compArgSize = GetOutgoingArgByteSize(compArgSize);
@@ -2311,6 +2318,7 @@ void Compiler::StructPromotionHelper::PromoteStructVar(unsigned lclNum)
         fieldVarDsc->lvFldOrdinal    = pFieldInfo->fldOrdinal;
         fieldVarDsc->lvParentLcl     = lclNum;
         fieldVarDsc->lvIsParam       = varDsc->lvIsParam;
+        fieldVarDsc->lvIsOSRLocal    = varDsc->lvIsOSRLocal;
 
         // This new local may be the first time we've seen a long typed local.
         if (fieldVarDsc->lvType == TYP_LONG)
index 69a63e0..9f9aa18 100644 (file)
@@ -454,7 +454,7 @@ CodeGenInterface::siVarLoc::siVarLoc(const LclVarDsc* varDsc, regNumber baseReg,
 {
     if (varDsc->lvIsInReg())
     {
-        var_types regType = varDsc->GetActualRegisterType();
+        var_types regType = genActualType(varDsc->GetActualRegisterType());
         siFillRegisterVarLoc(varDsc, regType, baseReg, offset, isFramePointerUsed);
     }
     else