Safe refactoring changes and code cleanup items
authorBrian Sullivan <briansul@microsoft.com>
Mon, 4 Apr 2016 22:26:38 +0000 (15:26 -0700)
committerBrian Sullivan <briansul@microsoft.com>
Tue, 5 Apr 2016 01:26:04 +0000 (18:26 -0700)
Fixed the dumper so that GT_LCL_VAR and GT_LCL_FLD use a common code path
and we now  display (last use) correctly
Moved the checking for invalid GT_LISTs with an op1 arg of a GT_LIST from gtNewArgList to the constructor
and called IsListForMultiRegArg in the new assert
Renamed IsListofLclFlds to IsListForMultiRegArgs and added ARM64 support
Modifed the dump to display the GTF_MORPHED flag using a '+'
Fix dumper's gtGetLateArgMsg to display each register for a multireg struct passed using a GT_LIST
Modified the NYI_<target> macros to include the target in their message
Fixed the gtCosts for GT_LIST, GT_OBJ, GT_MKREFANY and GT_BOX nodes
When we construct a new GT_LCL_FLD, initialize the gtFieldSeq to NotAField rather than nullptr
Fix comment header for getStructGcPtrsFromOp
Removed the define on ARM64 that changed the asserts(p) macro to notYetImplemented
In NewPutArg renamed the "fp" argument to be called "info" instead

src/jit/compiler.cpp
src/jit/compiler.h
src/jit/error.h
src/jit/gentree.cpp
src/jit/gentree.h
src/jit/host.h
src/jit/lclvars.cpp
src/jit/lower.cpp
src/jit/lower.h
src/jit/morph.cpp

index 3b78d17..61605c7 100644 (file)
@@ -426,14 +426,15 @@ var_types    Compiler::getJitGCType(BYTE gcType)
 }
 
 #if FEATURE_MULTIREG_ARGS
-//------------------------------------------------------------------------
-// getStructGcPtrsFromOp: Given a GenTree node of TYP_STRUCT that represents a pass by value argument
-//                        return the gcPtr layout for the pointers sized fields //
+//---------------------------------------------------------------------------
+// getStructGcPtrsFromOp: Given a GenTree node of TYP_STRUCT that represents
+//                        a pass by value argument, return the gcPtr layout 
+//                        for the pointers sized fields 
 // Arguments:
 //    op         - the operand of TYP_STRUCT that is passed by value
 //    gcPtrsOut  - an array of BYTES that are written by this method
 //                 they will contain the VM's CorInfoGCType values 
-//                 for each pointer sized field//
+//                 for each pointer sized field
 // Return Value:
 //     Two [or more] values are written into the gcPtrs array
 //
index 9407419..0c18dba 100644 (file)
@@ -2030,6 +2030,7 @@ public:
     void                    gtGetLateArgMsg (GenTreePtr             call,
                                              GenTreePtr             arg,
                                              int                    argNum,
+                                             int                    listCount,
                                              char*                  bufp,
                                              unsigned               bufLength);
     void                    gtDispArgList   (GenTreePtr              tree, 
index 7b6cf10..d883fb0 100644 (file)
@@ -92,7 +92,7 @@ extern void notYetImplemented(const char * msg, const char * file, unsigned line
 
 #ifdef _TARGET_AMD64_
 
-#define NYI_AMD64(msg)    notYetImplemented("NYI: " # msg, __FILE__, __LINE__)
+#define NYI_AMD64(msg)    notYetImplemented("NYI_AMD64: " # msg, __FILE__, __LINE__)
 #define NYI_X86(msg)      do { } while (0)
 #define NYI_ARM(msg)      do { } while (0)
 #define NYI_ARM64(msg)    do { } while (0)
@@ -100,7 +100,7 @@ extern void notYetImplemented(const char * msg, const char * file, unsigned line
 #elif defined(_TARGET_X86_)
 
 #define NYI_AMD64(msg)    do { } while (0)
-#define NYI_X86(msg)      notYetImplemented("NYI: " # msg, __FILE__, __LINE__)
+#define NYI_X86(msg)      notYetImplemented("NYI_X86: " # msg, __FILE__, __LINE__)
 #define NYI_ARM(msg)      do { } while (0)
 #define NYI_ARM64(msg)    do { } while (0)
 
@@ -108,7 +108,7 @@ extern void notYetImplemented(const char * msg, const char * file, unsigned line
 
 #define NYI_AMD64(msg)    do { } while (0)
 #define NYI_X86(msg)      do { } while (0)
-#define NYI_ARM(msg)      notYetImplemented("NYI: " # msg, __FILE__, __LINE__)
+#define NYI_ARM(msg)      notYetImplemented("NYI_ARM: " # msg, __FILE__, __LINE__)
 #define NYI_ARM64(msg)    do { } while (0)
 
 #elif defined(_TARGET_ARM64_)
@@ -116,7 +116,7 @@ extern void notYetImplemented(const char * msg, const char * file, unsigned line
 #define NYI_AMD64(msg)    do { } while (0)
 #define NYI_X86(msg)      do { } while (0)
 #define NYI_ARM(msg)      do { } while (0)
-#define NYI_ARM64(msg)    notYetImplemented("NYI: " # msg, __FILE__, __LINE__)
+#define NYI_ARM64(msg)    notYetImplemented("NYI_ARM64: " # msg, __FILE__, __LINE__)
 
 #else
 
index 6d9f6fe..ebc62ea 100644 (file)
@@ -3007,6 +3007,7 @@ COMMON_CNS:
                 break;
 
 
+            case GT_LIST:
             case GT_NOP:
                 costEx = 0;
                 costSz = 0;
@@ -3116,15 +3117,17 @@ COMMON_CNS:
             case GT_OBJ:
                 level  = gtSetEvalOrder(tree->gtOp.gtOp1);
                 ftreg |= tree->gtOp.gtOp1->gtRsvdRegs;
-                costEx = tree->gtOp.gtOp1->gtCostEx + 1;
-                costSz = tree->gtOp.gtOp1->gtCostSz + 1;
+                // We estimate the cost of a GT_OBJ or GT_MKREFANY to be two loads (GT_INDs)
+                costEx = 2*IND_COST_EX;
+                costSz = 2*2;
                 break;
 
             case GT_BOX:
                 level  = gtSetEvalOrder(tree->gtBox.BoxOp());
                 ftreg |= tree->gtBox.BoxOp()->gtRsvdRegs;
-                costEx = tree->gtBox.BoxOp()->gtCostEx;
-                costSz = tree->gtBox.BoxOp()->gtCostSz;
+                // We estimate the cost of a GT_BOX to be two stores (GT_INDs)
+                costEx = 2*IND_COST_EX;
+                costSz = 2*2;
                 break;
 
             case GT_IND:
@@ -5220,6 +5223,7 @@ GenTreeLclFld* Compiler::gtNewLclFldNode(unsigned  lnum,
 
     //assert(lnum < lvaCount);
 
+    node->gtFieldSeq = FieldSeqStore::NotAField();
     return node;
 }
 
@@ -5260,17 +5264,9 @@ GenTreeArgList* Compiler::gtNewListNode(GenTreePtr op1, GenTreeArgList* op2)
  *  Create a list out of one value.
  */
 
-GenTreeArgList* Compiler::gtNewArgList(GenTreePtr op)
+GenTreeArgList* Compiler::gtNewArgList(GenTreePtr arg)
 {
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
-    // With structs passed in multiple args we could have the arg
-    // GT_LIST containing a list of LCL_FLDs
-    assert((op != NULL) && ((!op->IsList()) || (op->IsListOfLclFlds())));
-#else // !FEATURE_UNIX_AMD64_STRUCT_PASSING
-    assert((op != NULL) && (op->OperGet() != GT_LIST));
-#endif // !FEATURE_UNIX_AMD64_STRUCT_PASSING
-
-    return new (this, GT_LIST) GenTreeArgList(op);
+    return new (this, GT_LIST) GenTreeArgList(arg);
 }
 
 /*****************************************************************************
@@ -5278,21 +5274,9 @@ GenTreeArgList* Compiler::gtNewArgList(GenTreePtr op)
  *  Create a list out of the two values.
  */
 
-GenTreeArgList* Compiler::gtNewArgList(GenTreePtr op1, GenTreePtr op2)
+GenTreeArgList* Compiler::gtNewArgList(GenTreePtr arg1, GenTreePtr arg2)
 {
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
-    // With structs passed in multiple args we could have the arg
-    // GT_LIST containing a list of LCL_FLDs
-    assert((op1 != NULL) && ((!op1->IsList()) || (op1->IsListOfLclFlds())));
-    assert((op2 != NULL) && ((!op2->IsList()) || (op2->IsListOfLclFlds())));
-#else // !FEATURE_UNIX_AMD64_STRUCT_PASSING
-    assert((op1 != NULL) && (!op1->IsList()));
-    assert((op2 != NULL) && (!op2->IsList()));
-#endif // !FEATURE_UNIX_AMD64_STRUCT_PASSING
-
-    GenTreePtr tree;
-
-    return new (this, GT_LIST) GenTreeArgList(op1, gtNewArgList(op2));
+    return new (this, GT_LIST) GenTreeArgList(arg1, gtNewArgList(arg2));
 }
 
 /*****************************************************************************
@@ -7122,7 +7106,8 @@ GenTreePtr GenTree::GetChild(unsigned childNum)
     printf("%c", (flags & GTF_CALL          ) ? 'C' : '-');
     printf("%c", (flags & GTF_EXCEPT        ) ? 'X' : '-');
     printf("%c", (flags & GTF_GLOB_REF      ) ? 'G' : '-');
-    printf("%c", (flags & GTF_ORDER_SIDEEFF ) ? 'O' : '-');
+    printf("%c", (flags & GTF_MORPHED       ) ? '+' :         // First print '+' if GTF_MORPHED is set
+                 (flags & GTF_ORDER_SIDEEFF ) ? 'O' : '-');   // otherwise print 'O' or '-'
     printf("%c", (flags & GTF_COLON_COND    ) ? '?' : '-');
     printf("%c", (flags & GTF_DONT_CSE      ) ? 'N' :         // N is for No cse
                  (flags & GTF_MAKE_CSE      ) ? 'H' : '-');   // H is for Hoist this expr
@@ -8038,17 +8023,27 @@ Compiler::gtDispLeaf(GenTree *tree, IndentStack* indentStack)
         return;
     }
 
+    bool isLclFld = false;
+
     switch  (tree->gtOper)
     {
         unsigned        varNum;
         LclVarDsc *     varDsc;
 
+    case GT_LCL_FLD:
+    case GT_LCL_FLD_ADDR:
+    case GT_STORE_LCL_FLD:
+        isLclFld = true;
+        __fallthrough;
+
     case GT_PHI_ARG:
     case GT_LCL_VAR:
     case GT_LCL_VAR_ADDR:
     case GT_STORE_LCL_VAR:
         printf(" ");
-        gtDispLclVar(tree->gtLclVarCommon.gtLclNum);
+        varNum = tree->gtLclVarCommon.gtLclNum;
+        varDsc = &lvaTable[varNum];
+        gtDispLclVar(varNum);
         if (tree->gtLclVarCommon.HasSsaName())
         {
             if (tree->gtFlags & GTF_VAR_USEASG)
@@ -8061,8 +8056,29 @@ Compiler::gtDispLeaf(GenTree *tree, IndentStack* indentStack)
                 printf("%s:%d", (tree->gtFlags & GTF_VAR_DEF) ? "d" : "u", tree->gtLclVarCommon.gtSsaNum);
             }
         }
-       
-        varDsc = &lvaTable[tree->gtLclVarCommon.gtLclNum];
+
+        if (isLclFld)
+        {
+            printf("[+%u]", tree->gtLclFld.gtLclOffs);
+            gtDispFieldSeq(tree->gtLclFld.gtFieldSeq);
+        }
+
+        if (varDsc->lvRegister)
+        {
+            printf(" ");
+            varDsc->PrintVarReg();
+        }
+#ifndef LEGACY_BACKEND
+        else if (tree->InReg())
+        {
+#if CPU_LONG_USES_REGPAIR
+            if (isRegPairType(tree->TypeGet()))
+                printf(" %s", compRegPairName(tree->gtRegPair));
+            else
+#endif
+                printf(" %s", compRegVarName(tree->gtRegNum));
+        }
+#endif // !LEGACY_BACKEND
         
         if (varDsc->lvPromoted)
         {
@@ -8090,7 +8106,7 @@ Compiler::gtDispLeaf(GenTree *tree, IndentStack* indentStack)
                 }
                 
                 printf("\n");                    
-                printf("                                                           ");
+                printf("                                                  ");
                 printIndent(indentStack);
                 printf("    %-6s V%02u.%s (offs=0x%02x) -> ",
                        varTypeName(fieldVarDsc->TypeGet()),
@@ -8106,7 +8122,7 @@ Compiler::gtDispLeaf(GenTree *tree, IndentStack* indentStack)
                     fieldVarDsc->PrintVarReg();
                 }
 
-                if ((fieldVarDsc->lvTracked) &&
+                if (fieldVarDsc->lvTracked &&
                     fgLocalVarLivenessDone &&  // Includes local variable liveness
                     ((tree->gtFlags & GTF_VAR_DEATH) != 0))
                 {
@@ -8114,57 +8130,15 @@ Compiler::gtDispLeaf(GenTree *tree, IndentStack* indentStack)
                 }
             }
         }
-            
-        goto LCL_COMMON;
-
-    case GT_LCL_FLD:
-    case GT_LCL_FLD_ADDR:
-    case GT_STORE_LCL_FLD:
-        printf(" ");
-        gtDispLclVar(tree->gtLclVarCommon.gtLclNum);
-        if (tree->gtLclVarCommon.HasSsaName())
+        else // a normal not-promoted lclvar
         {
-            if (tree->gtFlags & GTF_VAR_USEASG)
+            if (varDsc->lvTracked &&
+                fgLocalVarLivenessDone &&
+                ((tree->gtFlags & GTF_VAR_DEATH) != 0))
             {
-                assert(tree->gtFlags & GTF_VAR_DEF);
-                printf("ud:%d->%d", tree->gtLclVarCommon.gtSsaNum, GetSsaNumForLocalVarDef(tree));
+                printf(" (last use)");
             }
-            else
-            {
-                printf("%s:%d", (tree->gtFlags & GTF_VAR_DEF) ? "d" : "u", tree->gtLclVarCommon.gtSsaNum);
-            }
-        }
-        printf("[+%u]", tree->gtLclFld.gtLclOffs);
-        gtDispFieldSeq(tree->gtLclFld.gtFieldSeq);
-
-    LCL_COMMON:
-
-        varNum = tree->gtLclVarCommon.gtLclNum;
-        varDsc = &lvaTable[varNum];
-
-        if (varDsc->lvRegister)
-        {
-            printf(" ");
-            varDsc->PrintVarReg();
         }
-#ifndef LEGACY_BACKEND
-        else if (tree->InReg())
-        {
-#if CPU_LONG_USES_REGPAIR
-            if (isRegPairType(tree->TypeGet()))
-                printf(" %s", compRegPairName(tree->gtRegPair));
-            else
-#endif
-                printf(" %s", compRegVarName(tree->gtRegNum));
-        }
-#endif // !LEGACY_BACKEND
-
-        if (fgLocalVarLivenessDone &&
-            ((tree->gtFlags & GTF_VAR_DEATH) != 0))
-        {
-            printf(" (last use)");
-        }
-
         break;
 
     case GT_REG_VAR:
@@ -8183,7 +8157,7 @@ Compiler::gtDispLeaf(GenTree *tree, IndentStack* indentStack)
         varNum = tree->gtRegVar.gtLclNum;
         varDsc = &lvaTable[varNum];
 
-        if ((varDsc->lvTracked) &&
+        if (varDsc->lvTracked &&
             fgLocalVarLivenessDone &&
             ((tree->gtFlags & GTF_VAR_DEATH) != 0))
         {
@@ -8663,7 +8637,7 @@ void                Compiler::gtDispTree(GenTreePtr             tree,
                     argx    = lateArgs->Current();
 
                     IndentInfo arcType = (lateArgs->Rest() == nullptr) ? IIArcBottom : IIArc;
-                    gtGetLateArgMsg(tree, argx, lateArgIndex, bufp, sizeof(buf));
+                    gtGetLateArgMsg(tree, argx, lateArgIndex, -1, bufp, sizeof(buf));
                     gtDispChild(argx, indentStack, arcType, bufp, topOnly);
                 }
             }
@@ -8791,6 +8765,8 @@ void                Compiler::gtGetArgMsg(GenTreePtr        call,
 //    call         - The call for which 'arg' is an argument
 //    argx         - The argument for which a message should be constructed
 //    lateArgIndex - The ordinal number of the arg in the lastArg  list
+//    listCount    - When printing in Linear form this is the count for a multireg GT_LIST 
+//                   or -1 if we are not printing in Linear form
 //    bufp         - A pointer to the buffer into which the message is written
 //    bufLength    - The length of the buffer pointed to by bufp
 //
@@ -8804,6 +8780,7 @@ void                Compiler::gtGetArgMsg(GenTreePtr        call,
 void                Compiler::gtGetLateArgMsg(GenTreePtr        call,
                                               GenTreePtr        argx,
                                               int               lateArgIndex,
+                                              int               listCount,
                                               char*             bufp,
                                               unsigned          bufLength)
 {
@@ -8824,10 +8801,36 @@ void                Compiler::gtGetLateArgMsg(GenTreePtr        call,
     else
 #endif
     {
-        if  (gtArgIsThisPtr(curArgTabEntry))
+        if (gtArgIsThisPtr(curArgTabEntry))
+        {
             sprintf_s(bufp, bufLength, "this in %s%c", compRegVarName(argReg), 0);
-        else 
-            sprintf_s(bufp, bufLength, "arg%d in %s%c", curArgTabEntry->argNum, compRegVarName(argReg), 0);
+        }
+        else
+        {
+#ifdef _TARGET_ARM64_
+            if (curArgTabEntry->numRegs == 2)
+            {
+                regNumber argReg2 = REG_NEXT(argReg);
+                if (listCount == -1)
+                {
+                    sprintf_s(bufp, bufLength, "arg%d %s,%s%c", curArgTabEntry->argNum, compRegVarName(argReg), compRegVarName(argReg2), 0);
+                }
+                else if (listCount == 1)
+                {
+                    sprintf_s(bufp, bufLength, "arg%d hi %s%c", curArgTabEntry->argNum, compRegVarName(argReg2), 0);
+                }
+                else 
+                {
+                    assert(listCount == 0);
+                    sprintf_s(bufp, bufLength, "arg%d lo %s%c", curArgTabEntry->argNum, compRegVarName(argReg), 0);
+                }
+            }
+            else
+#endif
+            {
+                sprintf_s(bufp, bufLength, "arg%d in %s%c", curArgTabEntry->argNum, compRegVarName(argReg), 0);
+            }
+        }
     }
 }
 
@@ -9082,6 +9085,7 @@ GenTreePtr          Compiler::gtDispLinearTree(GenTreeStmt* curStmt,
                         // print the nodes of the nested list and continue to the next argument.
                         if (listElem->gtOper == GT_LIST)
                         {
+                            int listCount = 0;
                             GenTreePtr nextListNested = nullptr;
                             for (GenTreePtr listNested = listElem; listNested != nullptr; listNested = nextListNested)
                             {
@@ -9106,7 +9110,7 @@ GenTreePtr          Compiler::gtDispLinearTree(GenTreeStmt* curStmt,
                                 else
                                 {
                                     assert(child == tree->gtCall.gtCallLateArgs);
-                                    gtGetLateArgMsg(tree, listNested, listElemNum, bufp, BufLength);
+                                    gtGetLateArgMsg(tree, listNested, listElemNum, listCount++, bufp, BufLength);
                                 }
                                 nextLinearNode = gtDispLinearTree(curStmt, nextLinearNode, listElemNested, indentStack, bufp);
                                 indentStack->Pop();
@@ -9130,7 +9134,7 @@ GenTreePtr          Compiler::gtDispLinearTree(GenTreeStmt* curStmt,
                         else
                         {
                             assert(child == tree->gtCall.gtCallLateArgs);
-                            gtGetLateArgMsg(tree, listElem, listElemNum, bufp, BufLength);
+                            gtGetLateArgMsg(tree, listElem, listElemNum, -1, bufp, BufLength);
                         }
                     }
                     else
index d1dbb77..0c4b4e1 100644 (file)
@@ -1320,7 +1320,7 @@ public:
 
     static
     inline bool RequiresNonNullOp2(genTreeOps oper);
-    bool IsListOfLclFlds();
+    bool IsListForMultiRegArg();
 #endif // DEBUG
 
     inline bool IsZero();
@@ -2302,16 +2302,21 @@ struct GenTreeArgList: public GenTreeOp
     GenTreeArgList() : GenTreeOp() {}
 #endif
 
-    GenTreeArgList(GenTreePtr arg ) : 
-        GenTreeOp(GT_LIST, TYP_VOID, arg, NULL) 
-        {}
+    GenTreeArgList(GenTreePtr arg) :
+        GenTreeArgList(arg, nullptr) {}
       
     GenTreeArgList(GenTreePtr arg, GenTreeArgList* rest) : 
         GenTreeOp(GT_LIST, TYP_VOID, arg, rest) 
     {
-        assert (arg != NULL);
+        // With structs passed in multiple args we could have an arg
+        // GT_LIST containing a list of LCL_FLDs, see IsListForMultiRegArg()
+        //
+        assert((arg != nullptr) && ((!arg->IsList()) || (arg->IsListForMultiRegArg())));
         gtFlags |=  arg->gtFlags & GTF_ALL_EFFECT;
-        if (rest != NULL) gtFlags |= rest->gtFlags & GTF_ALL_EFFECT;
+        if (rest != NULL)
+        {
+            gtFlags |= rest->gtFlags & GTF_ALL_EFFECT;
+        }
     }
 };
 
@@ -3680,18 +3685,43 @@ inline GenTreePtr GenTree::MoveNext()
 }
 
 #ifdef DEBUG
-inline bool GenTree::IsListOfLclFlds()
-
+inline bool GenTree::IsListForMultiRegArg()
 {
     if (!IsList())
     {
         return false;
     }
 
+#if FEATURE_MULTIREG_ARGS
+    // We allow a GT_LIST of some nodes as an argument 
     GenTree* gtListPtr = this;
-    while (gtListPtr->Current() != nullptr)
+    while (gtListPtr != nullptr) 
     {
-        if (gtListPtr->Current()->OperGet() != GT_LCL_FLD)
+        bool allowed = false;
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
+        // ToDo: fix UNIX_AMD64 so that we do not generate this kind of a List
+        if (gtListPtr->Current() == nullptr)
+            break;
+
+        // Only a list of GT_LCL_FLDs is allowed
+        if (gtListPtr->Current()->OperGet() == GT_LCL_FLD)
+        {
+            allowed = true;
+        }
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#ifdef _TARGET_ARM64_
+        // A list of GT_LCL_VARs is allowed
+        if (gtListPtr->Current()->OperGet() == GT_LCL_VAR)
+        {
+            allowed = true;
+        }
+        // A list of GT_LCL_FLDs is allowed
+        else if (gtListPtr->Current()->OperGet() == GT_LCL_FLD)
+        {
+            allowed = true;
+        }
+#endif
+        if (!allowed)
         {
             return false;
         }
@@ -3700,6 +3730,10 @@ inline bool GenTree::IsListOfLclFlds()
     }
 
     return true;
+#else // FEATURE_MULTIREG_ARGS
+    // Not allowed to have a GT_LIST here unless we have FEATURE_MULTIREG_ARGS
+    return false;
+#endif
 }
 #endif // DEBUG
 
index cf20713..9948188 100644 (file)
@@ -51,13 +51,7 @@ extern  "C"
 void    __cdecl     assertAbort(const char *why, const char *file, unsigned line);
 
 #undef  assert
-// TODO-ARM64-NYI: Temporarily make all asserts in the JIT use the NYI code path
-#ifdef _TARGET_ARM64_
-extern void notYetImplemented(const char * msg, const char * file, unsigned line);
-#define assert(p)   (void)((p) || (notYetImplemented("assert: " #p, __FILE__, __LINE__),0))
-#else
 #define assert(p)   (void)((p) || (assertAbort(#p, __FILE__, __LINE__),0))
-#endif
 
 #else // DEBUG
 
index 35810d1..e6956cf 100644 (file)
@@ -1819,7 +1819,7 @@ unsigned   Compiler::lvaGetFieldLocal(LclVarDsc *  varDsc, unsigned int fldOffse
         }
     }
 
-    noway_assert(!"Cannot find field local.");
+    // This is the not-found error return path, the caller should check for BAD_VAR_NUM
     return BAD_VAR_NUM;
 }
 
@@ -2770,9 +2770,9 @@ void                LclVarDsc::lvaDisqualifyVar()
 #endif // ASSERTION_PROP
 
 #ifndef LEGACY_BACKEND
-/********************************************************************************** 
- * Get type of a variable when passed as an argument.
- */
+/**********************************************************************************
+* Get type of a variable when passed as an argument.
+*/
 var_types           LclVarDsc::lvaArgType()
 {
     var_types type = TypeGet();
@@ -2782,29 +2782,33 @@ var_types           LclVarDsc::lvaArgType()
     {
         switch (lvExactSize)
         {
-           case 1: type = TYP_BYTE;  break;
-           case 2: type = TYP_SHORT; break;
-           case 4: type = TYP_INT;   break;
-           case 8:
-              switch (*lvGcLayout)
-              {
-                 case TYPE_GC_NONE:
-                    type = TYP_I_IMPL;
-                    break;
-                 case TYPE_GC_REF:
-                    type = TYP_REF;
-                    break;
-                 case TYPE_GC_BYREF:
-                    type = TYP_BYREF;
-                    break;
-                 default:
-                    unreached();
-              }
-              break;
-
-           default:
-               type = TYP_BYREF;
-               break;
+        case 1: type = TYP_BYTE;  break;
+        case 2: type = TYP_SHORT; break;
+        case 4: type = TYP_INT;   break;
+        case 8:
+            switch (*lvGcLayout)
+            {
+            case TYPE_GC_NONE:
+                type = TYP_I_IMPL;
+                break;
+
+            case TYPE_GC_REF:
+                type = TYP_REF;
+                break;
+
+            case TYPE_GC_BYREF:
+                type = TYP_BYREF;
+                break;
+
+            default:
+                unreached();
+            }
+            break;
+
+        default:
+            type = TYP_BYREF;
+            break;
+
         }
     }
 #else
index 6e228a2..4e5eb59 100644 (file)
@@ -1097,7 +1097,7 @@ void Lowering::SpliceInUnary(GenTreePtr parent, GenTreePtr* ppChild, GenTreePtr
 // Arguments:
 //    call - the call whose arg is being rewritten.
 //    arg  - the arg being rewritten.
-//    fp   - the ArgTabEntry for the argument.
+//    info - the ArgTabEntry information for the argument.
 //    type - the type of the argument.
 //
 // Return Value:
@@ -1105,7 +1105,7 @@ void Lowering::SpliceInUnary(GenTreePtr parent, GenTreePtr* ppChild, GenTreePtr
 //    or the incoming arg if the arg tree was not rewritten.
 //
 // Assumptions:
-//    call, arg, and fp must be non-null.
+//    call, arg, and info must be non-null.
 //
 // Notes:
 //    For System V systems with native struct passing (i.e. FEATURE_UNIX_AMD64_STRUCT_PASSING defined)
@@ -1117,11 +1117,11 @@ void Lowering::SpliceInUnary(GenTreePtr parent, GenTreePtr* ppChild, GenTreePtr
 //    layout object, so the codegen of the GT_PUTARG_STK could use this for optimizing copying to the stack by value.
 //    (using block copy primitives for non GC pointers and a single TARGET_POINTER_SIZE copy with recording GC info.)
 //
-GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryPtr fp, var_types type)
+GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryPtr info, var_types type)
 {
     assert(call != nullptr);
     assert(arg != nullptr);
-    assert(fp != nullptr);
+    assert(info != nullptr);
 
     GenTreePtr putArg = nullptr;
     bool updateArgTable = true;
@@ -1140,27 +1140,28 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
     if (varTypeIsStruct(type))
     {
-        isOnStack = !fp->structDesc.passedInRegisters;
+        isOnStack = !info->structDesc.passedInRegisters;
     }
     else
     {
-        isOnStack = fp->regNum == REG_STK;
+        isOnStack = info->regNum == REG_STK;
     }
 #else // !FEATURE_UNIX_AMD64_STRUCT_PASSING
-    isOnStack = fp->regNum == REG_STK; 
+    isOnStack = info->regNum == REG_STK; 
 #endif // !FEATURE_UNIX_AMD64_STRUCT_PASSING
 
     if (!isOnStack)
     {
 #ifdef FEATURE_SIMD
         // TYP_SIMD8 is passed in an integer register.  We need the putArg node to be of the int type.
-        if (type == TYP_SIMD8 && genIsValidIntReg(fp->regNum))
+        if (type == TYP_SIMD8 && genIsValidIntReg(info->regNum))
         {
             type = TYP_LONG;
         }
 #endif //FEATURE_SIMD
+
 #if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
-        if (fp->isStruct)
+        if (info->isStruct)
         {
             // The following code makes sure a register passed struct arg is moved to
             // the register before the call is made.
@@ -1173,9 +1174,9 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
             //    The code creates a GT_PUTARG_REG node for each GT_LCL_FLD in the GT_LIST
             //    and splices it in the list with the corresponding original GT_LCL_FLD tree as op1.
 
-            assert(fp->structDesc.eightByteCount != 0);
+            assert(info->structDesc.eightByteCount != 0);
 
-            if (fp->structDesc.eightByteCount == 1)
+            if (info->structDesc.eightByteCount == 1)
             {
                 // Case 1 above: Create a GT_PUTARG_REG node with op1 of the original tree.
                 //
@@ -1207,17 +1208,17 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
 
                 putArg = comp->gtNewOperNode(GT_PUTARG_REG, type, arg);
             }
-            else if (fp->structDesc.eightByteCount == 2)
+            else if (info->structDesc.eightByteCount == 2)
             {
                 // Case 2 above: Convert the LCL_FLDs to PUTARG_REG
                 //
                 // lowering call :
-                //     N001(3, 2)[000025] ------ - N----Source / --*  &lclVar   byref  V01 loc1
-                //     N003(3, 2)[000056] ------ - N----Destination + --*  &lclVar   byref  V03 tmp1
-                //     N006(1, 1)[000058] ------------ + --*  const     int    16
+                //     N001(3, 2)  [000025] ------ - N----Source / --*  &lclVar   byref  V01 loc1
+                //     N003(3, 2)  [000056] ------ - N----Destination + --*  &lclVar   byref  V03 tmp1
+                //     N006(1, 1)  [000058] ------------ + --*  const     int    16
                 //     N007(12, 12)[000059] - A--G---- - L - arg0 SETUP / --*  copyBlk   void
-                //     N009(3, 4)[000061] ------ - N----arg0 in rdi + --*  lclFld    long   V03 tmp1[+0]
-                //     N010(3, 4)[000063] ------------arg0 in rsi + --*  lclFld    long   V03 tmp1[+8](last use)
+                //     N009(3, 4)  [000061] ------ - N----arg0 in rdi + --*  lclFld    long   V03 tmp1[+0]
+                //     N010(3, 4)  [000063] ------------arg0 in rsi + --*  lclFld    long   V03 tmp1[+8](last use)
                 //     N014(40, 31)[000026] --CXG------ - *call      void   Test.Foo.test2
                 //
                 // args :
@@ -1240,13 +1241,13 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
 
                 assert(arg->OperGet() == GT_LIST);
                 GenTreeArgList* argListPtr = arg->AsArgList();
-                
+
                 for (unsigned ctr = 0; argListPtr != nullptr; argListPtr = argListPtr->Rest(), ctr++)
                 {
                     // Create a new GT_PUTARG_REG node with op1 the original GT_LCL_FLD.
                     GenTreePtr newOper = comp->gtNewOperNode(
                         GT_PUTARG_REG,
-                        comp->GetTypeFromClassificationAndSizes(fp->structDesc.eightByteClassifications[ctr], fp->structDesc.eightByteSizes[ctr]),
+                        comp->GetTypeFromClassificationAndSizes(info->structDesc.eightByteClassifications[ctr], info->structDesc.eightByteSizes[ctr]),
                         argListPtr->gtOp.gtOp1);
 
                     // CopyCosts
@@ -1263,11 +1264,12 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
             else
             {
                 assert(false && "Illegal count of eightbytes for the CLR type system"); // No more than 2 eightbytes for the CLR.
-                
+
             }
         }
         else
 #endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+
         {
             putArg = comp->gtNewOperNode(GT_PUTARG_REG, type, arg);
         }
@@ -1278,24 +1280,24 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
         // This provides the info to put this argument in in-coming arg area slot 
         // instead of in out-going arg area slot.
 
-        FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY(assert(fp->isStruct == varTypeIsStruct(type))); // Make sure state is correct
+        FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY(assert(info->isStruct == varTypeIsStruct(type))); // Make sure state is correct
 
 #if FEATURE_FASTTAILCALL
         putArg = new (comp, GT_PUTARG_STK) GenTreePutArgStk(GT_PUTARG_STK,
                                                             type,
                                                             arg, 
-                                                            fp->slotNum
-                                                            FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(fp->numSlots)
-                                                            FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(fp->isStruct),
+                                                            info->slotNum
+                                                            FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(info->numSlots)
+                                                            FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(info->isStruct),
                                                             call->IsFastTailCall() 
                                                             DEBUG_ARG(call));
 #else
         putArg = new (comp, GT_PUTARG_STK) GenTreePutArgStk(GT_PUTARG_STK,
                                                             type, 
                                                             arg, 
-                                                            fp->slotNum
-                                                            FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(fp->numSlots)
-                                                            FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(fp->isStruct)
+                                                            info->slotNum
+                                                            FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(info->numSlots)
+                                                            FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(info->isStruct)
                                                             DEBUG_ARG(call));
 #endif
 
@@ -1307,10 +1309,10 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
         // to be done (only for reference slots), so gcinfo is emitted.
         // For non-reference slots faster/smaller size instructions are used - 
         // pair copying using XMM registers or rep mov instructions.
-        if (fp->isStruct)
+        if (info->isStruct)
         {
             unsigned numRefs = 0;
-            BYTE* gcLayout = new (comp, CMK_Codegen) BYTE[fp->numSlots];
+            BYTE* gcLayout = new (comp, CMK_Codegen) BYTE[info->numSlots];
             // We use GT_OBJ for non-SIMD struct arguments. However, for
             // SIMD arguments the GT_OBJ has already been transformed.
             if (arg->gtOper != GT_OBJ)
@@ -1335,9 +1337,9 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
         putArg->SetInReg();
     }
 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
-    else if (fp->isStruct)
+    else if (info->isStruct)
     {
-        if (fp->structDesc.passedInRegisters)
+        if (info->structDesc.passedInRegisters)
         {
             putArg->SetInReg();
         }
@@ -1354,7 +1356,7 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
     }
     else if (updateArgTable)
     {
-        fp->node = putArg;
+        info->node = putArg;
     }
     return putArg;
 }
@@ -1386,9 +1388,9 @@ void Lowering::LowerArg(GenTreeCall* call, GenTreePtr* ppArg)
 #endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
         !arg->OperIsCopyBlkOp()) // these are de facto placeholders (apparently)
     {
-        fgArgTabEntryPtr fp = comp->gtArgEntryByNode(call, arg);
-        assert(fp->node == arg);
-        bool isReg = (fp->regNum != REG_STK);
+        fgArgTabEntryPtr info = comp->gtArgEntryByNode(call, arg);
+        assert(info->node == arg);
+        bool isReg = (info->regNum != REG_STK);
         var_types type = arg->TypeGet();
 
         if (varTypeIsSmall(type))
@@ -1417,8 +1419,8 @@ void Lowering::LowerArg(GenTreeCall* call, GenTreePtr* ppArg)
             GenTreePtr argLo = arg->gtGetOp1();
             GenTreePtr argHi = arg->gtGetOp2();
 
-            GenTreePtr putArgLo = NewPutArg(call, argLo, fp, type);
-            GenTreePtr putArgHi = NewPutArg(call, argHi, fp, type);
+            GenTreePtr putArgLo = NewPutArg(call, argLo, info, type);
+            GenTreePtr putArgHi = NewPutArg(call, argHi, info, type);
 
             arg->gtOp.gtOp1 = putArgLo;
             arg->gtOp.gtOp2 = putArgHi;
@@ -1456,7 +1458,7 @@ void Lowering::LowerArg(GenTreeCall* call, GenTreePtr* ppArg)
         else
 #endif // !defined(_TARGET_64BIT_)
         {
-            putArg = NewPutArg(call, arg, fp, type);
+            putArg = NewPutArg(call, arg, info, type);
 
             // In the case of register passable struct (in one or two registers)
             // the NewPutArg returns a new node (GT_PUTARG_REG or a GT_LIST with two GT_PUTARG_REGs.)
index 128a3b7..232c7b2 100644 (file)
@@ -77,7 +77,7 @@ private:
     GenTree* LowerVirtualVtableCall   (GenTreeCall* call);
     GenTree* LowerVirtualStubCall     (GenTreeCall* call);
     void     LowerArgsForCall         (GenTreeCall* call);
-    GenTree* NewPutArg                (GenTreeCall* call, GenTreePtr arg, fgArgTabEntryPtr fp, var_types type);
+    GenTree* NewPutArg                (GenTreeCall* call, GenTreePtr arg, fgArgTabEntryPtr info, var_types type);
     void     LowerArg                 (GenTreeCall* call, GenTreePtr *ppTree);
     void     InsertPInvokeCallProlog  (GenTreeCall* call);
     void     InsertPInvokeCallEpilog  (GenTreeCall* call);
index 78340f3..cc642ec 100644 (file)
@@ -2932,7 +2932,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
         unsigned argAlign = 1;
 
 #ifdef _TARGET_ARM_
-
         var_types hfaType = GetHfaType(argx);
         bool isHfaArg = varTypeIsFloating(hfaType);
 #endif // _TARGET_ARM_
@@ -4067,7 +4066,7 @@ void Compiler::fgMorphSystemVStructArgs(GenTreeCall* call, bool hasStructArgumen
                     arg->gtOp.gtOp1->AsLclVarCommon() : arg->AsLclVarCommon();
                 if (fgEntryPtr->structDesc.passedInRegisters)
                 {
-                    if (fgEntryPtr->structDesc.eightByteCount == 1) 
+                    if (fgEntryPtr->structDesc.eightByteCount == 1)
                     {
                         // Change the type and below the code will change the LclVar to a LCL_FLD
                         type = GetTypeFromClassificationAndSizes(fgEntryPtr->structDesc.eightByteClassifications[0], fgEntryPtr->structDesc.eightByteSizes[0]);
@@ -4084,6 +4083,7 @@ void Compiler::fgMorphSystemVStructArgs(GenTreeCall* call, bool hasStructArgumen
                                 fgEntryPtr->structDesc.eightByteSizes[1]),
                             lclCommon->gtLclNum,
                             fgEntryPtr->structDesc.eightByteOffsets[1]);
+                        // Note this should actually be: secondNode = gtNewArgList(newLclField)
                         GenTreeArgList* secondNode = gtNewListNode(newLclField, nullptr);
                         secondNode->gtType = originalType; // Preserve the type. It is a special case.
                         newLclField->gtFieldSeq = FieldSeqStore::NotAField();
@@ -11054,7 +11054,7 @@ CM_ADD_OP:
                 }
 
                 // We will turn a GT_LCL_VAR into a GT_LCL_FLD with an gtLclOffs of 'ival'
-                // ot if we already have a GT_LCL_FLD we will adjust the gtLclOffs by adding 'ival'
+                // or if we already have a GT_LCL_FLD we will adjust the gtLclOffs by adding 'ival'
                 // Then we change the type of the GT_LCL_FLD to match the orginal GT_IND type.
                 //
                 if (temp->OperGet() == GT_LCL_FLD)
@@ -15255,7 +15255,7 @@ void                Compiler::fgPromoteStructs()
                 {
                     if (structPromotionInfo.fieldCnt != 1)
                     {
-                        JITDUMP("Not promoting promotable struct local V%02u, because lvIsParam are true and #fields = %d.\n",
+                        JITDUMP("Not promoting promotable struct local V%02u, because lvIsParam is true and #fields = %d.\n",
                                 lclNum, structPromotionInfo.fieldCnt);
                         continue;
                     }
@@ -15333,6 +15333,7 @@ Compiler::fgWalkResult      Compiler::fgMorphStructField(GenTreePtr tree, fgWalk
                         // Promoted struct
                         unsigned fldOffset     = tree->gtField.gtFldOffset;
                         unsigned fieldLclIndex = lvaGetFieldLocal(varDsc, fldOffset);
+                        noway_assert(fieldLclIndex != BAD_VAR_NUM);
 
                         tree->SetOper(GT_LCL_VAR);
                         tree->gtLclVarCommon.SetLclNum(fieldLclIndex);
@@ -15434,6 +15435,7 @@ Compiler::fgWalkResult      Compiler::fgMorphLocalField(GenTreePtr tree, fgWalkD
         if (fldOffset != BAD_VAR_NUM)
         {
             fieldLclIndex = lvaGetFieldLocal(varDsc, fldOffset);
+            noway_assert(fieldLclIndex != BAD_VAR_NUM);
             fldVarDsc = &lvaTable[fieldLclIndex];
         }