Refactoring siVarLoc creation (dotnet/coreclr#22543)
authorBrian Bohe <brianbohe@gmail.com>
Wed, 13 Feb 2019 01:22:35 +0000 (17:22 -0800)
committerCarol Eidt <carol.eidt@microsoft.com>
Wed, 13 Feb 2019 01:22:35 +0000 (17:22 -0800)
* Moving siVarLoc and siVarLocType from compiler.h to CodeGenInterface.h

* Encapsulating siVarLoc construction with siScope and LclVarDsc

* Encapsulating siVarLoc construction from psiScope

* Adding some argument description on genSetScopInfo header

* Changing const siVarLoc& to const siVarLoc* on eeSetLVInfo

* Changing siVarLoc& to siVarLoc* in genSetScopeInfo arguments

* Rename var in genSetScopeInfo header

Commit migrated from https://github.com/dotnet/coreclr/commit/2f75b38bd75e88860203a7fad83f5fbadff0b1f4

src/coreclr/src/jit/codegen.h
src/coreclr/src/jit/codegencommon.cpp
src/coreclr/src/jit/codegeninterface.h
src/coreclr/src/jit/compiler.h
src/coreclr/src/jit/ee_il_dll.cpp
src/coreclr/src/jit/scopeinfo.cpp

index c1fb7b4..1ce5c96 100644 (file)
@@ -548,13 +548,13 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
     //-------------------------------------------------------------------------
     // scope info for the variables
 
-    void genSetScopeInfo(unsigned            which,
-                         UNATIVE_OFFSET      startOffs,
-                         UNATIVE_OFFSET      length,
-                         unsigned            varNum,
-                         unsigned            LVnum,
-                         bool                avail,
-                         Compiler::siVarLoc& loc);
+    void genSetScopeInfo(unsigned       which,
+                         UNATIVE_OFFSET startOffs,
+                         UNATIVE_OFFSET length,
+                         unsigned       varNum,
+                         unsigned       LVnum,
+                         bool           avail,
+                         siVarLoc*      varLoc);
 
     void genSetScopeInfo();
 
@@ -619,6 +619,10 @@ protected:
         siScope* scNext;
     };
 
+    // Returns a "siVarLoc" instance representing the place where the variable lives base on
+    // varDsc and scope description.
+    CodeGenInterface::siVarLoc getSiVarLoc(const LclVarDsc* varDsc, const siScope* scope) const;
+
     siScope siOpenScopeList, siScopeList, *siOpenScopeLast, *siScopeLast;
 
     unsigned siScopeCnt;
@@ -724,6 +728,10 @@ protected:
 
         psiScope* scPrev;
         psiScope* scNext;
+
+        // Returns a "siVarLoc" instance representing the place where the variable lives base on
+        // psiScope properties.
+        CodeGenInterface::siVarLoc getSiVarLoc() const;
     };
 
     psiScope psiOpenScopeList, psiScopeList, *psiOpenScopeLast, *psiScopeLast;
@@ -749,13 +757,13 @@ protected:
 
     struct TrnslLocalVarInfo
     {
-        unsigned           tlviVarNum;
-        unsigned           tlviLVnum;
-        VarName            tlviName;
-        UNATIVE_OFFSET     tlviStartPC;
-        size_t             tlviLength;
-        bool               tlviAvailable;
-        Compiler::siVarLoc tlviVarLoc;
+        unsigned       tlviVarNum;
+        unsigned       tlviLVnum;
+        VarName        tlviName;
+        UNATIVE_OFFSET tlviStartPC;
+        size_t         tlviLength;
+        bool           tlviAvailable;
+        siVarLoc       tlviVarLoc;
     };
 
     // Array of scopes of LocalVars in terms of native code
index f287835..7d1c8c5 100644 (file)
@@ -10610,21 +10610,9 @@ void CodeGen::genSetScopeInfo()
             endOffs++;
         }
 
-        Compiler::siVarLoc varLoc;
+        siVarLoc varLoc = scopeP->getSiVarLoc();
 
-        if (scopeP->scRegister)
-        {
-            varLoc.vlType       = Compiler::VLT_REG;
-            varLoc.vlReg.vlrReg = (regNumber)scopeP->u1.scRegNum;
-        }
-        else
-        {
-            varLoc.vlType           = Compiler::VLT_STK;
-            varLoc.vlStk.vlsBaseReg = (regNumber)scopeP->u2.scBaseReg;
-            varLoc.vlStk.vlsOffset  = scopeP->u2.scOffset;
-        }
-
-        genSetScopeInfo(i, startOffs, endOffs - startOffs, varNum, scopeP->scLVnum, true, varLoc);
+        genSetScopeInfo(i, startOffs, endOffs - startOffs, varNum, scopeP->scLVnum, true, &varLoc);
     }
 
     // Record the scopes for the rest of the method.
@@ -10646,186 +10634,11 @@ void CodeGen::genSetScopeInfo()
 
         noway_assert(scopeL->scStartLoc != scopeL->scEndLoc);
 
-        // For stack vars, find the base register, and offset
-
-        regNumber baseReg;
-        signed    offset = compiler->lvaTable[scopeL->scVarNum].lvStkOffs;
-
-        if (!compiler->lvaTable[scopeL->scVarNum].lvFramePointerBased)
-        {
-            baseReg = REG_SPBASE;
-            offset += scopeL->scStackLevel;
-        }
-        else
-        {
-            baseReg = REG_FPBASE;
-        }
-
-        // Now fill in the varLoc
-
-        Compiler::siVarLoc varLoc;
-
-        // TODO-Review: This only works for always-enregistered variables. With LSRA, a variable might be in a register
-        // for part of its lifetime, or in different registers for different parts of its lifetime.
-        // This should only matter for non-debug code, where we do variable enregistration.
-        // We should store the ranges of variable enregistration in the scope table.
-        if (compiler->lvaTable[scopeL->scVarNum].lvIsInReg())
-        {
-            var_types type = genActualType(compiler->lvaTable[scopeL->scVarNum].TypeGet());
-            switch (type)
-            {
-                case TYP_INT:
-                case TYP_REF:
-                case TYP_BYREF:
-#ifdef _TARGET_64BIT_
-                case TYP_LONG:
-#endif // _TARGET_64BIT_
-
-                    varLoc.vlType       = Compiler::VLT_REG;
-                    varLoc.vlReg.vlrReg = compiler->lvaTable[scopeL->scVarNum].lvRegNum;
-                    break;
-
-#ifndef _TARGET_64BIT_
-                case TYP_LONG:
-#if !CPU_HAS_FP_SUPPORT
-                case TYP_DOUBLE:
-#endif
-
-                    if (compiler->lvaTable[scopeL->scVarNum].lvOtherReg != REG_STK)
-                    {
-                        varLoc.vlType            = Compiler::VLT_REG_REG;
-                        varLoc.vlRegReg.vlrrReg1 = compiler->lvaTable[scopeL->scVarNum].lvRegNum;
-                        varLoc.vlRegReg.vlrrReg2 = compiler->lvaTable[scopeL->scVarNum].lvOtherReg;
-                    }
-                    else
-                    {
-                        varLoc.vlType                        = Compiler::VLT_REG_STK;
-                        varLoc.vlRegStk.vlrsReg              = compiler->lvaTable[scopeL->scVarNum].lvRegNum;
-                        varLoc.vlRegStk.vlrsStk.vlrssBaseReg = baseReg;
-                        if (!isFramePointerUsed() && varLoc.vlRegStk.vlrsStk.vlrssBaseReg == REG_SPBASE)
-                        {
-                            varLoc.vlRegStk.vlrsStk.vlrssBaseReg = (regNumber)ICorDebugInfo::REGNUM_AMBIENT_SP;
-                        }
-                        varLoc.vlRegStk.vlrsStk.vlrssOffset = offset + sizeof(int);
-                    }
-                    break;
-#endif // !_TARGET_64BIT_
-
-#ifdef _TARGET_64BIT_
-
-                case TYP_FLOAT:
-                case TYP_DOUBLE:
-                    // TODO-AMD64-Bug: ndp\clr\src\inc\corinfo.h has a definition of RegNum that only goes up to R15,
-                    // so no XMM registers can get debug information.
-                    varLoc.vlType       = Compiler::VLT_REG_FP;
-                    varLoc.vlReg.vlrReg = compiler->lvaTable[scopeL->scVarNum].lvRegNum;
-                    break;
-
-#else // !_TARGET_64BIT_
-
-#if CPU_HAS_FP_SUPPORT
-                case TYP_FLOAT:
-                case TYP_DOUBLE:
-                    if (isFloatRegType(type))
-                    {
-                        varLoc.vlType         = Compiler::VLT_FPSTK;
-                        varLoc.vlFPstk.vlfReg = compiler->lvaTable[scopeL->scVarNum].lvRegNum;
-                    }
-                    break;
-#endif // CPU_HAS_FP_SUPPORT
-
-#endif // !_TARGET_64BIT_
-
-#ifdef FEATURE_SIMD
-                case TYP_SIMD8:
-                case TYP_SIMD12:
-                case TYP_SIMD16:
-                case TYP_SIMD32:
-                    varLoc.vlType = Compiler::VLT_REG_FP;
-
-                    // TODO-AMD64-Bug: ndp\clr\src\inc\corinfo.h has a definition of RegNum that only goes up to R15,
-                    // so no XMM registers can get debug information.
-                    //
-                    // Note: Need to initialize vlrReg field, otherwise during jit dump hitting an assert
-                    // in eeDispVar() --> getRegName() that regNumber is valid.
-                    varLoc.vlReg.vlrReg = compiler->lvaTable[scopeL->scVarNum].lvRegNum;
-                    break;
-#endif // FEATURE_SIMD
-
-                default:
-                    noway_assert(!"Invalid type");
-            }
-        }
-        else
-        {
-            assert(offset != BAD_STK_OFFS);
-            LclVarDsc* varDsc = compiler->lvaTable + scopeL->scVarNum;
-            switch (genActualType(varDsc->TypeGet()))
-            {
-                case TYP_INT:
-                case TYP_REF:
-                case TYP_BYREF:
-                case TYP_FLOAT:
-                case TYP_STRUCT:
-                case TYP_BLK: // Needed because of the TYP_BLK stress mode
-#ifdef FEATURE_SIMD
-                case TYP_SIMD8:
-                case TYP_SIMD12:
-                case TYP_SIMD16:
-                case TYP_SIMD32:
-#endif
-#ifdef _TARGET_64BIT_
-                case TYP_LONG:
-                case TYP_DOUBLE:
-#endif // _TARGET_64BIT_
-#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
-                    // In the AMD64 ABI we are supposed to pass a struct by reference when its
-                    // size is not 1, 2, 4 or 8 bytes in size. During fgMorph, the compiler modifies
-                    // the IR to comply with the ABI and therefore changes the type of the lclVar
-                    // that holds the struct from TYP_STRUCT to TYP_BYREF but it gives us a hint that
-                    // this is still a struct by setting the lvIsTemp flag.
-                    // The same is true for ARM64 and structs > 16 bytes.
-                    // (See Compiler::fgMarkImplicitByRefArgs in Morph.cpp for further detail)
-                    // Now, the VM expects a special enum for these type of local vars: VLT_STK_BYREF
-                    // to accomodate for this situation.
-                    if (varDsc->lvType == TYP_BYREF && varDsc->lvIsTemp)
-                    {
-                        assert(varDsc->lvIsParam);
-                        varLoc.vlType = Compiler::VLT_STK_BYREF;
-                    }
-                    else
-#endif // defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
-                    {
-                        varLoc.vlType = Compiler::VLT_STK;
-                    }
-                    varLoc.vlStk.vlsBaseReg = baseReg;
-                    varLoc.vlStk.vlsOffset  = offset;
-                    if (!isFramePointerUsed() && varLoc.vlStk.vlsBaseReg == REG_SPBASE)
-                    {
-                        varLoc.vlStk.vlsBaseReg = (regNumber)ICorDebugInfo::REGNUM_AMBIENT_SP;
-                    }
-                    break;
-
-#ifndef _TARGET_64BIT_
-                case TYP_LONG:
-                case TYP_DOUBLE:
-                    varLoc.vlType             = Compiler::VLT_STK2;
-                    varLoc.vlStk2.vls2BaseReg = baseReg;
-                    varLoc.vlStk2.vls2Offset  = offset;
-                    if (!isFramePointerUsed() && varLoc.vlStk2.vls2BaseReg == REG_SPBASE)
-                    {
-                        varLoc.vlStk2.vls2BaseReg = (regNumber)ICorDebugInfo::REGNUM_AMBIENT_SP;
-                    }
-                    break;
-#endif // !_TARGET_64BIT_
-
-                default:
-                    noway_assert(!"Invalid type");
-            }
-        }
+        LclVarDsc* varDsc = compiler->lvaGetDesc(scopeL->scVarNum);
+        siVarLoc   varLoc = getSiVarLoc(varDsc, scopeL);
 
         genSetScopeInfo(psiScopeCnt + i, startOffs, endOffs - startOffs, scopeL->scVarNum, scopeL->scLVnum,
-                        scopeL->scAvailable, varLoc);
+                        scopeL->scAvailable, &varLoc);
     }
 
     compiler->eeSetLVdone();
@@ -10840,19 +10653,19 @@ void CodeGen::genSetScopeInfo()
 //    length    - the length of this scope
 //    varNum    - the lclVar for this scope info
 //    LVnum
-//    avail
-//    varLoc
+//    avail     - a bool indicating if it has a home
+//    varLoc    - the position (reg or stack) of the variable
 //
 // Notes:
 //    Called for every scope info piece to record by the main genSetScopeInfo()
 
-void CodeGen::genSetScopeInfo(unsigned            which,
-                              UNATIVE_OFFSET      startOffs,
-                              UNATIVE_OFFSET      length,
-                              unsigned            varNum,
-                              unsigned            LVnum,
-                              bool                avail,
-                              Compiler::siVarLoc& varLoc)
+void CodeGen::genSetScopeInfo(unsigned       which,
+                              UNATIVE_OFFSET startOffs,
+                              UNATIVE_OFFSET length,
+                              unsigned       varNum,
+                              unsigned       LVnum,
+                              bool           avail,
+                              siVarLoc*      varLoc)
 {
     // We need to do some mapping while reporting back these variables.
 
@@ -10868,7 +10681,7 @@ void CodeGen::genSetScopeInfo(unsigned            which,
     if (compiler->info.compIsVarArgs && varNum != compiler->lvaVarargsHandleArg &&
         varNum < compiler->info.compArgsCount && !compiler->lvaTable[varNum].lvIsRegArg)
     {
-        noway_assert(varLoc.vlType == Compiler::VLT_STK || varLoc.vlType == Compiler::VLT_STK2);
+        noway_assert(varLoc->vlType == VLT_STK || varLoc->vlType == VLT_STK2);
 
         // All stack arguments (except the varargs handle) have to be
         // accessed via the varargs cookie. Discard generated info,
@@ -10893,8 +10706,8 @@ void CodeGen::genSetScopeInfo(unsigned            which,
         noway_assert(offset < stkArgSize);
         offset = stkArgSize - offset;
 
-        varLoc.vlType                   = Compiler::VLT_FIXED_VA;
-        varLoc.vlFixedVarArg.vlfvOffset = offset;
+        varLoc->vlType                   = VLT_FIXED_VA;
+        varLoc->vlFixedVarArg.vlfvOffset = offset;
     }
 
 #endif // _TARGET_X86_
@@ -10921,7 +10734,7 @@ void CodeGen::genSetScopeInfo(unsigned            which,
     tlvi.tlviStartPC   = startOffs;
     tlvi.tlviLength    = length;
     tlvi.tlviAvailable = avail;
-    tlvi.tlviVarLoc    = varLoc;
+    tlvi.tlviVarLoc    = *varLoc;
 
 #endif // DEBUG
 
index c5d9ec6..25027c1 100644 (file)
@@ -387,6 +387,150 @@ private:
 public:
     virtual void siUpdate() = 0;
 
+    /* These are the different addressing modes used to access a local var.
+     * The JIT has to report the location of the locals back to the EE
+     * for debugging purposes.
+     */
+
+    enum siVarLocType
+    {
+        VLT_REG,
+        VLT_REG_BYREF, // this type is currently only used for value types on X64
+        VLT_REG_FP,
+        VLT_STK,
+        VLT_STK_BYREF, // this type is currently only used for value types on X64
+        VLT_REG_REG,
+        VLT_REG_STK,
+        VLT_STK_REG,
+        VLT_STK2,
+        VLT_FPSTK,
+        VLT_FIXED_VA,
+
+        VLT_COUNT,
+        VLT_INVALID
+    };
+
+    struct siVarLoc
+    {
+        siVarLocType vlType;
+
+        union {
+            // VLT_REG/VLT_REG_FP -- Any pointer-sized enregistered value (TYP_INT, TYP_REF, etc)
+            // eg. EAX
+            // VLT_REG_BYREF -- the specified register contains the address of the variable
+            // eg. [EAX]
+
+            struct
+            {
+                regNumber vlrReg;
+            } vlReg;
+
+            // VLT_STK       -- Any 32 bit value which is on the stack
+            // eg. [ESP+0x20], or [EBP-0x28]
+            // VLT_STK_BYREF -- the specified stack location contains the address of the variable
+            // eg. mov EAX, [ESP+0x20]; [EAX]
+
+            struct
+            {
+                regNumber     vlsBaseReg;
+                NATIVE_OFFSET vlsOffset;
+            } vlStk;
+
+            // VLT_REG_REG -- TYP_LONG/TYP_DOUBLE with both DWords enregistered
+            // eg. RBM_EAXEDX
+
+            struct
+            {
+                regNumber vlrrReg1;
+                regNumber vlrrReg2;
+            } vlRegReg;
+
+            // VLT_REG_STK -- Partly enregistered TYP_LONG/TYP_DOUBLE
+            // eg { LowerDWord=EAX UpperDWord=[ESP+0x8] }
+
+            struct
+            {
+                regNumber vlrsReg;
+
+                struct
+                {
+                    regNumber     vlrssBaseReg;
+                    NATIVE_OFFSET vlrssOffset;
+                } vlrsStk;
+            } vlRegStk;
+
+            // VLT_STK_REG -- Partly enregistered TYP_LONG/TYP_DOUBLE
+            // eg { LowerDWord=[ESP+0x8] UpperDWord=EAX }
+
+            struct
+            {
+                struct
+                {
+                    regNumber     vlsrsBaseReg;
+                    NATIVE_OFFSET vlsrsOffset;
+                } vlsrStk;
+
+                regNumber vlsrReg;
+            } vlStkReg;
+
+            // VLT_STK2 -- Any 64 bit value which is on the stack, in 2 successsive DWords
+            // eg 2 DWords at [ESP+0x10]
+
+            struct
+            {
+                regNumber     vls2BaseReg;
+                NATIVE_OFFSET vls2Offset;
+            } vlStk2;
+
+            // VLT_FPSTK -- enregisterd TYP_DOUBLE (on the FP stack)
+            // eg. ST(3). Actually it is ST("FPstkHeight - vpFpStk")
+
+            struct
+            {
+                unsigned vlfReg;
+            } vlFPstk;
+
+            // VLT_FIXED_VA -- fixed argument of a varargs function.
+            // The argument location depends on the size of the variable
+            // arguments (...). Inspecting the VARARGS_HANDLE indicates the
+            // location of the first arg. This argument can then be accessed
+            // relative to the position of the first arg
+
+            struct
+            {
+                unsigned vlfvOffset;
+            } vlFixedVarArg;
+
+            // VLT_MEMORY
+
+            struct
+            {
+                void* rpValue; // pointer to the in-process
+                               // location of the value.
+            } vlMemory;
+        };
+
+        // Helper functions
+
+        bool vlIsInReg(regNumber reg);
+        bool vlIsOnStk(regNumber reg, signed offset);
+
+        siVarLoc(const LclVarDsc* varDsc, regNumber baseReg, int offset, bool isFramePointerUsed);
+        siVarLoc(){};
+
+    private:
+        // Fill "siVarLoc" properties indicating the register position of the variable
+        // using "LclVarDsc" and "baseReg"/"offset" if it has a part in the stack (x64 bit float or long).
+        void siFillRegisterVarLoc(
+            const LclVarDsc* varDsc, var_types type, regNumber baseReg, int offset, bool isFramePointerUsed);
+
+        // Fill "siVarLoc" properties indicating the register position of the variable
+        // using "LclVarDsc" and "baseReg"/"offset" if it is a variable with part in a register and
+        // part in thestack
+        void siFillStackVarLoc(
+            const LclVarDsc* varDsc, var_types type, regNumber baseReg, int offset, bool isFramePointerUsed);
+    };
+
 #ifdef LATE_DISASM
 public:
     virtual const char* siRegVarName(size_t offs, size_t size, unsigned reg) = 0;
index 48ce141..ca47df7 100644 (file)
@@ -6739,138 +6739,6 @@ private:
     */
 
 public:
-    /* These are the different addressing modes used to access a local var.
-     * The JIT has to report the location of the locals back to the EE
-     * for debugging purposes.
-     */
-
-    enum siVarLocType
-    {
-        VLT_REG,
-        VLT_REG_BYREF, // this type is currently only used for value types on X64
-        VLT_REG_FP,
-        VLT_STK,
-        VLT_STK_BYREF, // this type is currently only used for value types on X64
-        VLT_REG_REG,
-        VLT_REG_STK,
-        VLT_STK_REG,
-        VLT_STK2,
-        VLT_FPSTK,
-        VLT_FIXED_VA,
-
-        VLT_COUNT,
-        VLT_INVALID
-    };
-
-    struct siVarLoc
-    {
-        siVarLocType vlType;
-
-        union {
-            // VLT_REG/VLT_REG_FP -- Any pointer-sized enregistered value (TYP_INT, TYP_REF, etc)
-            // eg. EAX
-            // VLT_REG_BYREF -- the specified register contains the address of the variable
-            // eg. [EAX]
-
-            struct
-            {
-                regNumber vlrReg;
-            } vlReg;
-
-            // VLT_STK       -- Any 32 bit value which is on the stack
-            // eg. [ESP+0x20], or [EBP-0x28]
-            // VLT_STK_BYREF -- the specified stack location contains the address of the variable
-            // eg. mov EAX, [ESP+0x20]; [EAX]
-
-            struct
-            {
-                regNumber     vlsBaseReg;
-                NATIVE_OFFSET vlsOffset;
-            } vlStk;
-
-            // VLT_REG_REG -- TYP_LONG/TYP_DOUBLE with both DWords enregistered
-            // eg. RBM_EAXEDX
-
-            struct
-            {
-                regNumber vlrrReg1;
-                regNumber vlrrReg2;
-            } vlRegReg;
-
-            // VLT_REG_STK -- Partly enregistered TYP_LONG/TYP_DOUBLE
-            // eg { LowerDWord=EAX UpperDWord=[ESP+0x8] }
-
-            struct
-            {
-                regNumber vlrsReg;
-
-                struct
-                {
-                    regNumber     vlrssBaseReg;
-                    NATIVE_OFFSET vlrssOffset;
-                } vlrsStk;
-            } vlRegStk;
-
-            // VLT_STK_REG -- Partly enregistered TYP_LONG/TYP_DOUBLE
-            // eg { LowerDWord=[ESP+0x8] UpperDWord=EAX }
-
-            struct
-            {
-                struct
-                {
-                    regNumber     vlsrsBaseReg;
-                    NATIVE_OFFSET vlsrsOffset;
-                } vlsrStk;
-
-                regNumber vlsrReg;
-            } vlStkReg;
-
-            // VLT_STK2 -- Any 64 bit value which is on the stack, in 2 successsive DWords
-            // eg 2 DWords at [ESP+0x10]
-
-            struct
-            {
-                regNumber     vls2BaseReg;
-                NATIVE_OFFSET vls2Offset;
-            } vlStk2;
-
-            // VLT_FPSTK -- enregisterd TYP_DOUBLE (on the FP stack)
-            // eg. ST(3). Actually it is ST("FPstkHeight - vpFpStk")
-
-            struct
-            {
-                unsigned vlfReg;
-            } vlFPstk;
-
-            // VLT_FIXED_VA -- fixed argument of a varargs function.
-            // The argument location depends on the size of the variable
-            // arguments (...). Inspecting the VARARGS_HANDLE indicates the
-            // location of the first arg. This argument can then be accessed
-            // relative to the position of the first arg
-
-            struct
-            {
-                unsigned vlfvOffset;
-            } vlFixedVarArg;
-
-            // VLT_MEMORY
-
-            struct
-            {
-                void* rpValue; // pointer to the in-process
-                               // location of the value.
-            } vlMemory;
-        };
-
-        // Helper functions
-
-        bool vlIsInReg(regNumber reg);
-        bool vlIsOnStk(regNumber reg, signed offset);
-    };
-
-    /*************************************************************************/
-
-public:
     // Get handles
 
     void eeGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
@@ -7082,20 +6950,20 @@ public:
 
     struct VarResultInfo
     {
-        UNATIVE_OFFSET startOffset;
-        UNATIVE_OFFSET endOffset;
-        DWORD          varNumber;
-        siVarLoc       loc;
+        UNATIVE_OFFSET             startOffset;
+        UNATIVE_OFFSET             endOffset;
+        DWORD                      varNumber;
+        CodeGenInterface::siVarLoc loc;
     } * eeVars;
     void eeSetLVcount(unsigned count);
-    void eeSetLVinfo(unsigned        which,
-                     UNATIVE_OFFSET  startOffs,
-                     UNATIVE_OFFSET  length,
-                     unsigned        varNum,
-                     unsigned        LVnum,
-                     VarName         namex,
-                     bool            avail,
-                     const siVarLoc& loc);
+    void eeSetLVinfo(unsigned                          which,
+                     UNATIVE_OFFSET                    startOffs,
+                     UNATIVE_OFFSET                    length,
+                     unsigned                          varNum,
+                     unsigned                          LVnum,
+                     VarName                           namex,
+                     bool                              avail,
+                     const CodeGenInterface::siVarLoc* loc);
     void eeSetLVdone();
 
 #ifdef DEBUG
@@ -7224,7 +7092,7 @@ public:
         return codeGen->getEmitter();
     }
 
-    bool isFramePointerUsed()
+    bool isFramePointerUsed() const
     {
         return codeGen->isFramePointerUsed();
     }
index e24de9d..8b2f29e 100644 (file)
@@ -643,16 +643,16 @@ void Compiler::eeSetLVcount(unsigned count)
     }
 }
 
-void Compiler::eeSetLVinfo(unsigned                  which,
-                           UNATIVE_OFFSET            startOffs,
-                           UNATIVE_OFFSET            length,
-                           unsigned                  varNum,
-                           unsigned                  LVnum,
-                           VarName                   name,
-                           bool                      avail,
-                           const Compiler::siVarLoc& varLoc)
+void Compiler::eeSetLVinfo(unsigned                          which,
+                           UNATIVE_OFFSET                    startOffs,
+                           UNATIVE_OFFSET                    length,
+                           unsigned                          varNum,
+                           unsigned                          LVnum,
+                           VarName                           name,
+                           bool                              avail,
+                           const CodeGenInterface::siVarLoc* varLoc)
 {
-    // ICorDebugInfo::VarLoc and Compiler::siVarLoc have to overlap
+    // ICorDebugInfo::VarLoc and CodeGenInterface::siVarLoc have to overlap
     // This is checked in siInit()
 
     assert(opts.compScopeInfo);
@@ -664,7 +664,7 @@ void Compiler::eeSetLVinfo(unsigned                  which,
         eeVars[which].startOffset = startOffs;
         eeVars[which].endOffset   = startOffs + length;
         eeVars[which].varNumber   = varNum;
-        eeVars[which].loc         = varLoc;
+        eeVars[which].loc         = *varLoc;
     }
 }
 
@@ -832,20 +832,20 @@ void Compiler::eeDispVar(ICorDebugInfo::NativeVarInfo* var)
     printf("%3d(%10s) : From %08Xh to %08Xh, in ", var->varNumber,
            (VarNameToStr(name) == nullptr) ? "UNKNOWN" : VarNameToStr(name), var->startOffset, var->endOffset);
 
-    switch ((Compiler::siVarLocType)var->loc.vlType)
+    switch ((CodeGenInterface::siVarLocType)var->loc.vlType)
     {
-        case VLT_REG:
-        case VLT_REG_BYREF:
-        case VLT_REG_FP:
+        case CodeGenInterface::VLT_REG:
+        case CodeGenInterface::VLT_REG_BYREF:
+        case CodeGenInterface::VLT_REG_FP:
             printf("%s", getRegName(var->loc.vlReg.vlrReg));
-            if (var->loc.vlType == (ICorDebugInfo::VarLocType)VLT_REG_BYREF)
+            if (var->loc.vlType == (ICorDebugInfo::VarLocType)CodeGenInterface::VLT_REG_BYREF)
             {
                 printf(" byref");
             }
             break;
 
-        case VLT_STK:
-        case VLT_STK_BYREF:
+        case CodeGenInterface::VLT_STK:
+        case CodeGenInterface::VLT_STK_BYREF:
             if ((int)var->loc.vlStk.vlsBaseReg != (int)ICorDebugInfo::REGNUM_AMBIENT_SP)
             {
                 printf("%s[%d] (1 slot)", getRegName(var->loc.vlStk.vlsBaseReg), var->loc.vlStk.vlsOffset);
@@ -854,18 +854,18 @@ void Compiler::eeDispVar(ICorDebugInfo::NativeVarInfo* var)
             {
                 printf(STR_SPBASE "'[%d] (1 slot)", var->loc.vlStk.vlsOffset);
             }
-            if (var->loc.vlType == (ICorDebugInfo::VarLocType)VLT_REG_BYREF)
+            if (var->loc.vlType == (ICorDebugInfo::VarLocType)CodeGenInterface::VLT_REG_BYREF)
             {
                 printf(" byref");
             }
             break;
 
 #ifndef _TARGET_AMD64_
-        case VLT_REG_REG:
+        case CodeGenInterface::VLT_REG_REG:
             printf("%s-%s", getRegName(var->loc.vlRegReg.vlrrReg1), getRegName(var->loc.vlRegReg.vlrrReg2));
             break;
 
-        case VLT_REG_STK:
+        case CodeGenInterface::VLT_REG_STK:
             if ((int)var->loc.vlRegStk.vlrsStk.vlrssBaseReg != (int)ICorDebugInfo::REGNUM_AMBIENT_SP)
             {
                 printf("%s-%s[%d]", getRegName(var->loc.vlRegStk.vlrsReg),
@@ -878,10 +878,10 @@ void Compiler::eeDispVar(ICorDebugInfo::NativeVarInfo* var)
             }
             break;
 
-        case VLT_STK_REG:
+        case CodeGenInterface::VLT_STK_REG:
             unreached(); // unexpected
 
-        case VLT_STK2:
+        case CodeGenInterface::VLT_STK2:
             if ((int)var->loc.vlStk2.vls2BaseReg != (int)ICorDebugInfo::REGNUM_AMBIENT_SP)
             {
                 printf("%s[%d] (2 slots)", getRegName(var->loc.vlStk2.vls2BaseReg), var->loc.vlStk2.vls2Offset);
@@ -892,11 +892,11 @@ void Compiler::eeDispVar(ICorDebugInfo::NativeVarInfo* var)
             }
             break;
 
-        case VLT_FPSTK:
+        case CodeGenInterface::VLT_FPSTK:
             printf("ST(L-%d)", var->loc.vlFPstk.vlfReg);
             break;
 
-        case VLT_FIXED_VA:
+        case CodeGenInterface::VLT_FIXED_VA:
             printf("fxd_va[%d]", var->loc.vlFixedVarArg.vlfvOffset);
             break;
 #endif // !_TARGET_AMD64_
index 21122bb..51f231e 100644 (file)
@@ -58,22 +58,22 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 #include "emit.h"
 #include "codegen.h"
 
-bool Compiler::siVarLoc::vlIsInReg(regNumber reg)
+bool CodeGenInterface::siVarLoc::vlIsInReg(regNumber reg)
 {
     switch (vlType)
     {
-        case VLT_REG:
+        case CodeGenInterface::VLT_REG:
             return (vlReg.vlrReg == reg);
-        case VLT_REG_REG:
+        case CodeGenInterface::VLT_REG_REG:
             return ((vlRegReg.vlrrReg1 == reg) || (vlRegReg.vlrrReg2 == reg));
-        case VLT_REG_STK:
+        case CodeGenInterface::VLT_REG_STK:
             return (vlRegStk.vlrsReg == reg);
-        case VLT_STK_REG:
+        case CodeGenInterface::VLT_STK_REG:
             return (vlStkReg.vlsrReg == reg);
 
-        case VLT_STK:
-        case VLT_STK2:
-        case VLT_FPSTK:
+        case CodeGenInterface::VLT_STK:
+        case CodeGenInterface::VLT_STK2:
+        case CodeGenInterface::VLT_FPSTK:
             return false;
 
         default:
@@ -82,35 +82,35 @@ bool Compiler::siVarLoc::vlIsInReg(regNumber reg)
     }
 }
 
-bool Compiler::siVarLoc::vlIsOnStk(regNumber reg, signed offset)
+bool CodeGenInterface::siVarLoc::vlIsOnStk(regNumber reg, signed offset)
 {
     regNumber actualReg;
 
     switch (vlType)
     {
 
-        case VLT_REG_STK:
+        case CodeGenInterface::VLT_REG_STK:
             actualReg = vlRegStk.vlrsStk.vlrssBaseReg;
             if ((int)actualReg == (int)ICorDebugInfo::REGNUM_AMBIENT_SP)
             {
                 actualReg = REG_SPBASE;
             }
             return ((actualReg == reg) && (vlRegStk.vlrsStk.vlrssOffset == offset));
-        case VLT_STK_REG:
+        case CodeGenInterface::VLT_STK_REG:
             actualReg = vlStkReg.vlsrStk.vlsrsBaseReg;
             if ((int)actualReg == (int)ICorDebugInfo::REGNUM_AMBIENT_SP)
             {
                 actualReg = REG_SPBASE;
             }
             return ((actualReg == reg) && (vlStkReg.vlsrStk.vlsrsOffset == offset));
-        case VLT_STK:
+        case CodeGenInterface::VLT_STK:
             actualReg = vlStk.vlsBaseReg;
             if ((int)actualReg == (int)ICorDebugInfo::REGNUM_AMBIENT_SP)
             {
                 actualReg = REG_SPBASE;
             }
             return ((actualReg == reg) && (vlStk.vlsOffset == offset));
-        case VLT_STK2:
+        case CodeGenInterface::VLT_STK2:
             actualReg = vlStk2.vls2BaseReg;
             if ((int)actualReg == (int)ICorDebugInfo::REGNUM_AMBIENT_SP)
             {
@@ -118,10 +118,10 @@ bool Compiler::siVarLoc::vlIsOnStk(regNumber reg, signed offset)
             }
             return ((actualReg == reg) && ((vlStk2.vls2Offset == offset) || (vlStk2.vls2Offset == (offset - 4))));
 
-        case VLT_REG:
-        case VLT_REG_FP:
-        case VLT_REG_REG:
-        case VLT_FPSTK:
+        case CodeGenInterface::VLT_REG:
+        case CodeGenInterface::VLT_REG_FP:
+        case CodeGenInterface::VLT_REG_REG:
+        case CodeGenInterface::VLT_FPSTK:
             return false;
 
         default:
@@ -130,6 +130,274 @@ bool Compiler::siVarLoc::vlIsOnStk(regNumber reg, signed offset)
     }
 }
 
+//------------------------------------------------------------------------
+// siVarLoc: Non-empty constructor of siVarLoc struct
+// Arguments:
+//    varDsc    - a "LclVarDsc *" to the variable it is desired to build the "siVarLoc".
+//    baseReg   - a "regNumber" use as a base for the offset.
+//    offset    - a signed amount of bytes distance from "baseReg" for the position of the variable.
+//    isFramePointerUsed - a boolean variable
+//
+// Notes:
+//    Called for every psiScope in "psiScopeList" codegen.h
+CodeGenInterface::siVarLoc::siVarLoc(const LclVarDsc* varDsc, regNumber baseReg, int offset, bool isFramePointerUsed)
+{
+    var_types type = genActualType(varDsc->TypeGet());
+
+    if (varDsc->lvIsInReg())
+    {
+        siFillRegisterVarLoc(varDsc, type, baseReg, offset, isFramePointerUsed);
+    }
+    else
+    {
+        siFillStackVarLoc(varDsc, type, baseReg, offset, isFramePointerUsed);
+    }
+}
+
+//------------------------------------------------------------------------
+// getSiVarLoc: Creates a "CodegenInterface::siVarLoc" instance from using the properties
+// of the "psiScope" instance.
+//
+// Notes:
+//    Called for every psiScope in "psiScopeList" codegen.h
+CodeGenInterface::siVarLoc CodeGen::psiScope::getSiVarLoc() const
+{
+    CodeGenInterface::siVarLoc varLoc;
+
+    if (scRegister)
+    {
+        varLoc.vlType       = VLT_REG;
+        varLoc.vlReg.vlrReg = (regNumber)u1.scRegNum;
+    }
+    else
+    {
+        varLoc.vlType           = VLT_STK;
+        varLoc.vlStk.vlsBaseReg = (regNumber)u2.scBaseReg;
+        varLoc.vlStk.vlsOffset  = u2.scOffset;
+    }
+
+    return varLoc;
+}
+
+//------------------------------------------------------------------------
+// getSiVarLoc: Returns a "siVarLoc" instance representing the place where the variable
+// is given its description, "baseReg", and "offset" (if needed).
+//
+// Arguments:
+//    varDsc    - a "LclVarDsc *" to the variable it is desired to build the "siVarLoc".
+//    scope   - a "siScope" Scope info of the variable.
+//
+// Return Value:
+//    A "siVarLoc" filled with the correct case struct fields for the variable, which could live
+//    in a register, an stack position, or a combination of both.
+//
+// Notes:
+//    Called for each siScope in siScopeList when "genSetScopeInfo".
+CodeGenInterface::siVarLoc CodeGen::getSiVarLoc(const LclVarDsc* varDsc, const siScope* scope) const
+{
+    // For stack vars, find the base register, and offset
+
+    regNumber baseReg;
+    signed    offset = varDsc->lvStkOffs;
+
+    if (!varDsc->lvFramePointerBased)
+    {
+        baseReg = REG_SPBASE;
+        offset += scope->scStackLevel;
+    }
+    else
+    {
+        baseReg = REG_FPBASE;
+    }
+
+    return CodeGenInterface::siVarLoc(varDsc, baseReg, offset, isFramePointerUsed());
+}
+
+//------------------------------------------------------------------------
+// siFillStackVarLoc: Fill "siVarLoc" struct indicating the stack position of the variable
+// using "LclVarDsc" and "baseReg"/"offset".
+//
+// Arguments:
+//    varDsc    - a "LclVarDsc *" to the variable it is desired to build the "siVarLoc".
+//    varLoc    - a "siVarLoc &" to fill with the data of the "varDsc".
+//    type      - a "var_types" which indicate the type of the variable.
+//    baseReg   - a "regNumber" use as a base for the offset.
+//    offset    - a signed amount of bytes distance from "baseReg" for the position of the variable.
+//    isFramePointerUsed - a boolean variable
+//
+// Notes:
+//    The "varLoc" argument is filled depending of the "type" argument but as a VLT_STK... variation.
+//    "baseReg" and "offset" are used to indicate the position of the variable in the stack.
+void CodeGenInterface::siVarLoc::siFillStackVarLoc(
+    const LclVarDsc* varDsc, var_types type, regNumber baseReg, int offset, bool isFramePointerUsed)
+{
+    assert(offset != BAD_STK_OFFS);
+
+    switch (type)
+    {
+        case TYP_INT:
+        case TYP_REF:
+        case TYP_BYREF:
+        case TYP_FLOAT:
+        case TYP_STRUCT:
+        case TYP_BLK: // Needed because of the TYP_BLK stress mode
+#ifdef FEATURE_SIMD
+        case TYP_SIMD8:
+        case TYP_SIMD12:
+        case TYP_SIMD16:
+        case TYP_SIMD32:
+#endif
+#ifdef _TARGET_64BIT_
+        case TYP_LONG:
+        case TYP_DOUBLE:
+#endif // _TARGET_64BIT_
+#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
+            // In the AMD64 ABI we are supposed to pass a struct by reference when its
+            // size is not 1, 2, 4 or 8 bytes in size. During fgMorph, the compiler modifies
+            // the IR to comply with the ABI and therefore changes the type of the lclVar
+            // that holds the struct from TYP_STRUCT to TYP_BYREF but it gives us a hint that
+            // this is still a struct by setting the lvIsTemp flag.
+            // The same is true for ARM64 and structs > 16 bytes.
+            // (See Compiler::fgMarkImplicitByRefArgs in Morph.cpp for further detail)
+            // Now, the VM expects a special enum for these type of local vars: VLT_STK_BYREF
+            // to accomodate for this situation.
+            if (varDsc->lvType == TYP_BYREF && varDsc->lvIsTemp)
+            {
+                assert(varDsc->lvIsParam);
+                this->vlType = VLT_STK_BYREF;
+            }
+            else
+#endif // defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
+            {
+                this->vlType = VLT_STK;
+            }
+            this->vlStk.vlsBaseReg = baseReg;
+            this->vlStk.vlsOffset  = offset;
+            if (!isFramePointerUsed && this->vlStk.vlsBaseReg == REG_SPBASE)
+            {
+                this->vlStk.vlsBaseReg = (regNumber)ICorDebugInfo::REGNUM_AMBIENT_SP;
+            }
+            break;
+
+#ifndef _TARGET_64BIT_
+        case TYP_LONG:
+        case TYP_DOUBLE:
+            this->vlType             = VLT_STK2;
+            this->vlStk2.vls2BaseReg = baseReg;
+            this->vlStk2.vls2Offset  = offset;
+            if (!isFramePointerUsed && this->vlStk2.vls2BaseReg == REG_SPBASE)
+            {
+                this->vlStk2.vls2BaseReg = (regNumber)ICorDebugInfo::REGNUM_AMBIENT_SP;
+            }
+            break;
+#endif // !_TARGET_64BIT_
+
+        default:
+            noway_assert(!"Invalid type");
+    }
+}
+
+//------------------------------------------------------------------------
+// siFillRegisterVarLoc: Fill "siVarLoc" struct indicating the register position of the variable
+// using "LclVarDsc" and "baseReg"/"offset" if it has a part in the stack (x64 bit float or long).
+//
+// Arguments:
+//    varDsc    - a "LclVarDsc *" to the variable it is desired to build the "siVarLoc".
+//    varLoc    - a "siVarLoc &" to fill with the data of the "varDsc".
+//    type      - a "var_types" which indicate the type of the variable.
+//    baseReg   - a "regNumber" use as a base for the offset.
+//    offset    - a signed amount of bytes distance from "baseReg" for the position of the variable.
+//    isFramePointerUsed    - a boolean indicating whether the current method sets up an
+//    explicit stack frame or not.
+//
+// Notes:
+//    The "varLoc" argument is filled depending of the "type" argument but as a VLT_REG... variation.
+//    "baseReg" and "offset" are used .for not 64 bit and values that are splitted in two parts.
+void CodeGenInterface::siVarLoc::siFillRegisterVarLoc(
+    const LclVarDsc* varDsc, var_types type, regNumber baseReg, int offset, bool isFramePointerUsed)
+{
+    switch (type)
+    {
+        case TYP_INT:
+        case TYP_REF:
+        case TYP_BYREF:
+#ifdef _TARGET_64BIT_
+        case TYP_LONG:
+#endif // _TARGET_64BIT_
+            this->vlType       = VLT_REG;
+            this->vlReg.vlrReg = varDsc->lvRegNum;
+            break;
+
+#ifndef _TARGET_64BIT_
+        case TYP_LONG:
+#if !CPU_HAS_FP_SUPPORT
+        case TYP_DOUBLE:
+#endif
+            if (varDsc->lvOtherReg != REG_STK)
+            {
+                this->vlType            = VLT_REG_REG;
+                this->vlRegReg.vlrrReg1 = varDsc->lvRegNum;
+                this->vlRegReg.vlrrReg2 = varDsc->lvOtherReg;
+            }
+            else
+            {
+                this->vlType                        = VLT_REG_STK;
+                this->vlRegStk.vlrsReg              = varDsc->lvRegNum;
+                this->vlRegStk.vlrsStk.vlrssBaseReg = baseReg;
+                if (isFramePointerUsed && this->vlRegStk.vlrsStk.vlrssBaseReg == REG_SPBASE)
+                {
+                    this->vlRegStk.vlrsStk.vlrssBaseReg = (regNumber)ICorDebugInfo::REGNUM_AMBIENT_SP;
+                }
+                this->vlRegStk.vlrsStk.vlrssOffset = offset + sizeof(int);
+            }
+            break;
+#endif // !_TARGET_64BIT_
+
+#ifdef _TARGET_64BIT_
+        case TYP_FLOAT:
+        case TYP_DOUBLE:
+            // TODO-AMD64-Bug: ndp\clr\src\inc\corinfo.h has a definition of RegNum that only goes up to R15,
+            // so no XMM registers can get debug information.
+            this->vlType       = VLT_REG_FP;
+            this->vlReg.vlrReg = varDsc->lvRegNum;
+            break;
+
+#else // !_TARGET_64BIT_
+
+#if CPU_HAS_FP_SUPPORT
+        case TYP_FLOAT:
+        case TYP_DOUBLE:
+            if (isFloatRegType(type))
+            {
+                this->vlType         = VLT_FPSTK;
+                this->vlFPstk.vlfReg = varDsc->lvRegNum;
+            }
+            break;
+#endif // CPU_HAS_FP_SUPPORT
+
+#endif // !_TARGET_64BIT_
+
+#ifdef FEATURE_SIMD
+        case TYP_SIMD8:
+        case TYP_SIMD12:
+        case TYP_SIMD16:
+        case TYP_SIMD32:
+            this->vlType = VLT_REG_FP;
+
+            // TODO-AMD64-Bug: ndp\clr\src\inc\corinfo.h has a definition of RegNum that only goes up to R15,
+            // so no XMM registers can get debug information.
+            //
+            // Note: Need to initialize vlrReg field, otherwise during jit dump hitting an assert
+            // in eeDispVar() --> getRegName() that regNumber is valid.
+            this->vlReg.vlrReg = varDsc->lvRegNum;
+            break;
+#endif // FEATURE_SIMD
+
+        default:
+            noway_assert(!"Invalid type");
+    }
+}
+
 /*============================================================================
  *
  *              Implementation for ScopeInfo
@@ -349,23 +617,23 @@ void CodeGen::siInit()
     assert((unsigned)ICorDebugInfo::REGNUM_EDI == REG_EDI);
 #endif
 
-    assert((unsigned)ICorDebugInfo::VLT_REG == Compiler::VLT_REG);
-    assert((unsigned)ICorDebugInfo::VLT_STK == Compiler::VLT_STK);
-    assert((unsigned)ICorDebugInfo::VLT_REG_REG == Compiler::VLT_REG_REG);
-    assert((unsigned)ICorDebugInfo::VLT_REG_STK == Compiler::VLT_REG_STK);
-    assert((unsigned)ICorDebugInfo::VLT_STK_REG == Compiler::VLT_STK_REG);
-    assert((unsigned)ICorDebugInfo::VLT_STK2 == Compiler::VLT_STK2);
-    assert((unsigned)ICorDebugInfo::VLT_FPSTK == Compiler::VLT_FPSTK);
-    assert((unsigned)ICorDebugInfo::VLT_FIXED_VA == Compiler::VLT_FIXED_VA);
-    assert((unsigned)ICorDebugInfo::VLT_COUNT == Compiler::VLT_COUNT);
-    assert((unsigned)ICorDebugInfo::VLT_INVALID == Compiler::VLT_INVALID);
+    assert((unsigned)ICorDebugInfo::VLT_REG == CodeGenInterface::VLT_REG);
+    assert((unsigned)ICorDebugInfo::VLT_STK == CodeGenInterface::VLT_STK);
+    assert((unsigned)ICorDebugInfo::VLT_REG_REG == CodeGenInterface::VLT_REG_REG);
+    assert((unsigned)ICorDebugInfo::VLT_REG_STK == CodeGenInterface::VLT_REG_STK);
+    assert((unsigned)ICorDebugInfo::VLT_STK_REG == CodeGenInterface::VLT_STK_REG);
+    assert((unsigned)ICorDebugInfo::VLT_STK2 == CodeGenInterface::VLT_STK2);
+    assert((unsigned)ICorDebugInfo::VLT_FPSTK == CodeGenInterface::VLT_FPSTK);
+    assert((unsigned)ICorDebugInfo::VLT_FIXED_VA == CodeGenInterface::VLT_FIXED_VA);
+    assert((unsigned)ICorDebugInfo::VLT_COUNT == CodeGenInterface::VLT_COUNT);
+    assert((unsigned)ICorDebugInfo::VLT_INVALID == CodeGenInterface::VLT_INVALID);
 
     /* ICorDebugInfo::VarLoc and siVarLoc should overlap exactly as we cast
      * one to the other in eeSetLVinfo()
      * Below is a "required but not sufficient" condition
      */
 
-    assert(sizeof(ICorDebugInfo::VarLoc) == sizeof(Compiler::siVarLoc));
+    assert(sizeof(ICorDebugInfo::VarLoc) == sizeof(CodeGenInterface::siVarLoc));
 
     assert(compiler->opts.compScopeInfo);