[RyuJit] Delete contained workaround. (#15257)
authorSergey Andreenko <seandree@microsoft.com>
Thu, 30 Nov 2017 02:37:26 +0000 (18:37 -0800)
committerGitHub <noreply@github.com>
Thu, 30 Nov 2017 02:37:26 +0000 (18:37 -0800)
* Move CodeGen::indirForm and IntForm to common.

* GenTreeFieldList: SetContained only for the head.

* delete the workaround.

* move check from isContained to CheckLIR

`isContained` can't determinate does node has user or not. Move this check to the appropriate place.

* check that SetContained and IsContained are consistent.

src/jit/codegenarmarch.cpp
src/jit/codegencommon.cpp
src/jit/codegenxarch.cpp
src/jit/gentree.cpp
src/jit/gentree.h
src/jit/lir.cpp
src/jit/lowerxarch.cpp

index e3fab8a..d740d18 100644 (file)
@@ -1539,35 +1539,6 @@ void CodeGen::genCodeForArrOffset(GenTreeArrOffs* arrOffset)
 }
 
 //------------------------------------------------------------------------
-// indirForm: Make a temporary indir we can feed to pattern matching routines
-//    in cases where we don't want to instantiate all the indirs that happen.
-//
-GenTreeIndir CodeGen::indirForm(var_types type, GenTree* base)
-{
-    GenTreeIndir i(GT_IND, type, base, nullptr);
-    i.gtRegNum = REG_NA;
-    i.SetContained();
-    // has to be nonnull (because contained nodes can't be the last in block)
-    // but don't want it to be a valid pointer
-    i.gtNext = (GenTree*)(-1);
-    return i;
-}
-
-//------------------------------------------------------------------------
-// intForm: Make a temporary int we can feed to pattern matching routines
-//    in cases where we don't want to instantiate.
-//
-GenTreeIntCon CodeGen::intForm(var_types type, ssize_t value)
-{
-    GenTreeIntCon i(type, value);
-    i.gtRegNum = REG_NA;
-    // has to be nonnull (because contained nodes can't be the last in block)
-    // but don't want it to be a valid pointer
-    i.gtNext = (GenTree*)(-1);
-    return i;
-}
-
-//------------------------------------------------------------------------
 // genCodeForShift: Generates the code sequence for a GenTree node that
 // represents a bit shift or rotate operation (<<, >>, >>>, rol, ror).
 //
@@ -1693,7 +1664,6 @@ void CodeGen::genCodeForIndexAddr(GenTreeIndexAddr* node)
         GenTreeAddrMode arrLenAddr(base->TypeGet(), base, nullptr, 0, static_cast<unsigned>(node->gtLenOffset));
         arrLenAddr.gtRegNum = REG_NA;
         arrLenAddr.SetContained();
-        arrLenAddr.gtNext = (GenTree*)(-1);
 
         GenTreeIndir arrLen = indirForm(TYP_INT, &arrLenAddr);
         arrLen.gtRegNum     = tmpReg;
index 4b1de0e..e4db444 100644 (file)
@@ -12606,3 +12606,30 @@ const char* CodeGen::siStackVarName(size_t offs, size_t size, unsigned reg, unsi
 #endif // !defined(DEBUG)
 #endif // defined(LATE_DISASM)
 /*****************************************************************************/
+
+#ifndef LEGACY_BACKEND
+
+//------------------------------------------------------------------------
+// indirForm: Make a temporary indir we can feed to pattern matching routines
+//    in cases where we don't want to instantiate all the indirs that happen.
+//
+GenTreeIndir CodeGen::indirForm(var_types type, GenTree* base)
+{
+    GenTreeIndir i(GT_IND, type, base, nullptr);
+    i.gtRegNum = REG_NA;
+    i.SetContained();
+    return i;
+}
+
+//------------------------------------------------------------------------
+// intForm: Make a temporary int we can feed to pattern matching routines
+//    in cases where we don't want to instantiate.
+//
+GenTreeIntCon CodeGen::intForm(var_types type, ssize_t value)
+{
+    GenTreeIntCon i(type, value);
+    i.gtRegNum = REG_NA;
+    return i;
+}
+
+#endif // !LEGACY_BACKEND
index 01121bc..df93834 100644 (file)
@@ -4032,33 +4032,6 @@ void CodeGen::genCodeForArrOffset(GenTreeArrOffs* arrOffset)
     genProduceReg(arrOffset);
 }
 
-// make a temporary indir we can feed to pattern matching routines
-// in cases where we don't want to instantiate all the indirs that happen
-//
-GenTreeIndir CodeGen::indirForm(var_types type, GenTree* base)
-{
-    GenTreeIndir i(GT_IND, type, base, nullptr);
-    i.gtRegNum = REG_NA;
-    i.SetContained();
-    // has to be nonnull (because contained nodes can't be the last in block)
-    // but don't want it to be a valid pointer
-    i.gtNext = (GenTree*)(-1);
-    return i;
-}
-
-// make a temporary int we can feed to pattern matching routines
-// in cases where we don't want to instantiate
-//
-GenTreeIntCon CodeGen::intForm(var_types type, ssize_t value)
-{
-    GenTreeIntCon i(type, value);
-    i.gtRegNum = REG_NA;
-    // has to be nonnull (because contained nodes can't be the last in block)
-    // but don't want it to be a valid pointer
-    i.gtNext = (GenTree*)(-1);
-    return i;
-}
-
 instruction CodeGen::genGetInsForOper(genTreeOps oper, var_types type)
 {
     instruction ins;
@@ -4581,7 +4554,6 @@ void CodeGen::genCodeForIndexAddr(GenTreeIndexAddr* node)
         GenTreeAddrMode arrLenAddr(base->TypeGet(), base, nullptr, 0, node->gtLenOffset);
         arrLenAddr.gtRegNum = REG_NA;
         arrLenAddr.SetContained();
-        arrLenAddr.gtNext = (GenTree*)(-1);
 
         GenTreeIndir arrLen = indirForm(TYP_INT, &arrLenAddr);
 
@@ -4603,7 +4575,6 @@ void CodeGen::genCodeForIndexAddr(GenTreeIndexAddr* node)
 
             arrLen.gtRegNum = REG_NA;
             arrLen.SetContained();
-            arrLen.gtNext = (GenTree*)(-1);
         }
 
         // Generate the range check.
index 98af021..34d356c 100644 (file)
@@ -16514,10 +16514,10 @@ bool GenTree::isContained() const
         assert(!isMarkedContained);
     }
 
-    // if it's contained it better have a user
+    // if it's contained it can't be unused.
     if (isMarkedContained)
     {
-        assert(gtNext != nullptr);
+        assert(!IsUnusedValue());
     }
 #endif // DEBUG
     return isMarkedContained;
index 9f17452..86f1ffc 100644 (file)
@@ -2067,6 +2067,7 @@ public:
     {
         assert(IsValue());
         gtFlags |= GTF_CONTAINED;
+        assert(isContained());
     }
 
     void ClearContained()
@@ -3182,16 +3183,16 @@ struct GenTreeFieldList : public GenTreeArgList
         if (prevList == nullptr)
         {
             gtFlags |= GTF_FIELD_LIST_HEAD;
+#ifndef LEGACY_BACKEND
+            // A GT_FIELD_LIST head is always contained. Other nodes return false from IsValue()
+            // and should not be marked as contained.
+            SetContained();
+#endif
         }
         else
         {
             prevList->gtOp2 = this;
         }
-#ifndef LEGACY_BACKEND
-        // A GT_FIELD_LIST is always contained. Note that this should only matter for the head node, but
-        // the list may be reordered.
-        gtFlags |= GTF_CONTAINED;
-#endif
     }
 };
 
index 80b9c34..3f716cf 100644 (file)
@@ -1664,6 +1664,7 @@ bool LIR::Range::CheckLIR(Compiler* compiler, bool checkUnusedValues) const
         {
             GenTree* node = kvp.Key();
             assert(node->IsUnusedValue() && "found an unmarked unused value");
+            assert(!node->isContained() && "a contained node should have a user");
         }
     }
 
index 65a1ef3..970793d 100644 (file)
@@ -463,6 +463,9 @@ void Lowering::LowerPutArgStk(GenTreePutArgStk* putArgStk)
         if (head != fieldList)
         {
             head->gtFlags |= GTF_FIELD_LIST_HEAD;
+            head->SetContained();
+
+            fieldList->ClearContained();
             fieldList->gtFlags &= ~GTF_FIELD_LIST_HEAD;
 
 #ifdef DEBUG