Refactor GenTree assertion information storage
authorMike Danes <onemihaid@hotmail.com>
Sat, 11 Mar 2017 09:04:04 +0000 (11:04 +0200)
committerMike Danes <onemihaid@hotmail.com>
Mon, 20 Mar 2017 21:26:27 +0000 (23:26 +0200)
Stealing a bit from gtAssertionNum is ugly  and error prone (e.g. bool HasAssertion() { return gtAssertionNum != 0; } is incorrect if the edge bit is set).

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

src/coreclr/src/jit/assertionprop.cpp
src/coreclr/src/jit/compiler.h
src/coreclr/src/jit/gentree.cpp
src/coreclr/src/jit/gentree.h
src/coreclr/src/jit/rangecheck.cpp

index 599cdf3..0c5b8f3 100644 (file)
@@ -828,7 +828,7 @@ Compiler::AssertionDsc* Compiler::optGetAssertion(AssertionIndex assertIndex)
  * if they don't care about it. Refer overloaded method optCreateAssertion.
  *
  */
-Compiler::AssertionIndex Compiler::optCreateAssertion(GenTreePtr op1, GenTreePtr op2, optAssertionKind assertionKind)
+AssertionIndex Compiler::optCreateAssertion(GenTreePtr op1, GenTreePtr op2, optAssertionKind assertionKind)
 {
     AssertionDsc assertionDsc;
     return optCreateAssertion(op1, op2, assertionKind, &assertionDsc);
@@ -850,10 +850,10 @@ Compiler::AssertionIndex Compiler::optCreateAssertion(GenTreePtr op1, GenTreePtr
  *  NO_ASSERTION_INDEX and we could not create the assertion.
  *
  */
-Compiler::AssertionIndex Compiler::optCreateAssertion(GenTreePtr       op1,
-                                                      GenTreePtr       op2,
-                                                      optAssertionKind assertionKind,
-                                                      AssertionDsc*    assertion)
+AssertionIndex Compiler::optCreateAssertion(GenTreePtr       op1,
+                                            GenTreePtr       op2,
+                                            optAssertionKind assertionKind,
+                                            AssertionDsc*    assertion)
 {
     memset(assertion, 0, sizeof(AssertionDsc));
     //
@@ -1538,7 +1538,7 @@ bool Compiler::optAssertionVnInvolvesNan(AssertionDsc* assertion)
  *  we use to refer to this element.
  *  If we need to add to the table and the table is full return the value zero
  */
-Compiler::AssertionIndex Compiler::optAddAssertion(AssertionDsc* newAssertion)
+AssertionIndex Compiler::optAddAssertion(AssertionDsc* newAssertion)
 {
     noway_assert(newAssertion->assertionKind != OAK_INVALID);
 
@@ -1745,9 +1745,9 @@ void Compiler::optCreateComplementaryAssertion(AssertionIndex assertionIndex, Ge
  * for the operands.
  */
 
-Compiler::AssertionIndex Compiler::optCreateJtrueAssertions(GenTreePtr                 op1,
-                                                            GenTreePtr                 op2,
-                                                            Compiler::optAssertionKind assertionKind)
+AssertionIndex Compiler::optCreateJtrueAssertions(GenTreePtr                 op1,
+                                                  GenTreePtr                 op2,
+                                                  Compiler::optAssertionKind assertionKind)
 {
     AssertionDsc   candidateAssertion;
     AssertionIndex assertionIndex = optCreateAssertion(op1, op2, assertionKind, &candidateAssertion);
@@ -1760,7 +1760,7 @@ Compiler::AssertionIndex Compiler::optCreateJtrueAssertions(GenTreePtr
     return assertionIndex;
 }
 
-Compiler::AssertionIndex Compiler::optCreateJTrueBoundsAssertion(GenTreePtr tree)
+AssertionInfo Compiler::optCreateJTrueBoundsAssertion(GenTreePtr tree)
 {
     GenTreePtr relop = tree->gtGetOp1();
     if ((relop->OperKind() & GTK_RELOP) == 0)
@@ -1846,11 +1846,11 @@ Compiler::AssertionIndex Compiler::optCreateJTrueBoundsAssertion(GenTreePtr tree
         dsc.op2.vn        = ValueNumStore::NoVN;
 
         AssertionIndex index = optAddAssertion(&dsc);
-        if ((arrLenUnsignedBnd.cmpOper == VNF_GE_UN) && (index != NO_ASSERTION_INDEX))
+        if (arrLenUnsignedBnd.cmpOper == VNF_GE_UN)
         {
             // By default JTRUE generated assertions hold on the "jump" edge. We have i >= a.len but we're really
             // after i < a.len so we need to change the assertion edge to "next".
-            index |= OAE_NEXT_EDGE;
+            return AssertionInfo::ForNextEdge(index);
         }
         return index;
     }
@@ -1898,7 +1898,7 @@ Compiler::AssertionIndex Compiler::optCreateJTrueBoundsAssertion(GenTreePtr tree
  *
  *  Compute assertions for the JTrue node.
  */
-Compiler::AssertionIndex Compiler::optAssertionGenJtrue(GenTreePtr tree)
+AssertionInfo Compiler::optAssertionGenJtrue(GenTreePtr tree)
 {
     // Only create assertions for JTRUE when we are in the global phase
     if (optLocalAssertionProp)
@@ -1917,10 +1917,10 @@ Compiler::AssertionIndex Compiler::optAssertionGenJtrue(GenTreePtr tree)
     GenTreePtr op1 = relop->gtOp.gtOp1;
     GenTreePtr op2 = relop->gtOp.gtOp2;
 
-    AssertionIndex index = optCreateJTrueBoundsAssertion(tree);
-    if (index != NO_ASSERTION_INDEX)
+    AssertionInfo info = optCreateJTrueBoundsAssertion(tree);
+    if (info.HasAssertion())
     {
-        return index;
+        return info;
     }
 
     // Find assertion kind.
@@ -2002,7 +2002,7 @@ Compiler::AssertionIndex Compiler::optAssertionGenJtrue(GenTreePtr tree)
  *  from all of the constituent phi operands.
  *
  */
-Compiler::AssertionIndex Compiler::optAssertionGenPhiDefn(GenTreePtr tree)
+AssertionIndex Compiler::optAssertionGenPhiDefn(GenTreePtr tree)
 {
     if (!tree->IsPhiDefn())
     {
@@ -2051,19 +2051,19 @@ void Compiler::optAssertionGen(GenTreePtr tree)
 
     // For most of the assertions that we create below
     // the assertion is true after the tree is processed
-    bool           assertionProven = true;
-    AssertionIndex assertionIndex  = NO_ASSERTION_INDEX;
+    bool          assertionProven = true;
+    AssertionInfo assertionInfo;
     switch (tree->gtOper)
     {
         case GT_ASG:
             // VN takes care of non local assertions for assignments and data flow.
             if (optLocalAssertionProp)
             {
-                assertionIndex = optCreateAssertion(tree->gtOp.gtOp1, tree->gtOp.gtOp2, OAK_EQUAL);
+                assertionInfo = optCreateAssertion(tree->gtOp.gtOp1, tree->gtOp.gtOp2, OAK_EQUAL);
             }
             else
             {
-                assertionIndex = optAssertionGenPhiDefn(tree);
+                assertionInfo = optAssertionGenPhiDefn(tree);
             }
             break;
 
@@ -2073,24 +2073,24 @@ void Compiler::optAssertionGen(GenTreePtr tree)
         case GT_IND:
         case GT_NULLCHECK:
             // All indirections create non-null assertions
-            assertionIndex = optCreateAssertion(tree->AsIndir()->Addr(), nullptr, OAK_NOT_EQUAL);
+            assertionInfo = optCreateAssertion(tree->AsIndir()->Addr(), nullptr, OAK_NOT_EQUAL);
             break;
 
         case GT_ARR_LENGTH:
             // An array length is an indirection (but doesn't derive from GenTreeIndir).
-            assertionIndex = optCreateAssertion(tree->AsArrLen()->ArrRef(), nullptr, OAK_NOT_EQUAL);
+            assertionInfo = optCreateAssertion(tree->AsArrLen()->ArrRef(), nullptr, OAK_NOT_EQUAL);
             break;
 
         case GT_ARR_BOUNDS_CHECK:
             if (!optLocalAssertionProp)
             {
-                assertionIndex = optCreateAssertion(tree, nullptr, OAK_NO_THROW);
+                assertionInfo = optCreateAssertion(tree, nullptr, OAK_NO_THROW);
             }
             break;
 
         case GT_ARR_ELEM:
             // An array element reference can create a non-null assertion
-            assertionIndex = optCreateAssertion(tree->gtArrElem.gtArrObj, nullptr, OAK_NOT_EQUAL);
+            assertionInfo = optCreateAssertion(tree->gtArrElem.gtArrObj, nullptr, OAK_NOT_EQUAL);
             break;
 
         case GT_CALL:
@@ -2110,7 +2110,7 @@ void Compiler::optAssertionGen(GenTreePtr tree)
                 }
 #endif // _TARGET_X86_ || _TARGET_AMD64_ || _TARGET_ARM_
                 noway_assert(thisArg != nullptr);
-                assertionIndex = optCreateAssertion(thisArg, nullptr, OAK_NOT_EQUAL);
+                assertionInfo = optCreateAssertion(thisArg, nullptr, OAK_NOT_EQUAL);
             }
             break;
 
@@ -2121,13 +2121,13 @@ void Compiler::optAssertionGen(GenTreePtr tree)
                 // This represets an assertion that we would like to prove to be true. It is not actually a true
                 // assertion.
                 // If we can prove this assertion true then we can eliminate this cast.
-                assertionIndex  = optCreateAssertion(tree->gtOp.gtOp1, tree, OAK_SUBRANGE);
+                assertionInfo   = optCreateAssertion(tree->gtOp.gtOp1, tree, OAK_SUBRANGE);
                 assertionProven = false;
             }
             break;
 
         case GT_JTRUE:
-            assertionIndex = optAssertionGenJtrue(tree);
+            assertionInfo = optAssertionGenJtrue(tree);
             break;
 
         default:
@@ -2136,9 +2136,9 @@ void Compiler::optAssertionGen(GenTreePtr tree)
     }
 
     // For global assertion prop we must store the assertion number in the tree node
-    if ((assertionIndex != NO_ASSERTION_INDEX) && assertionProven && !optLocalAssertionProp)
+    if (assertionInfo.HasAssertion() && assertionProven && !optLocalAssertionProp)
     {
-        tree->SetAssertion(assertionIndex);
+        tree->SetAssertionInfo(assertionInfo);
     }
 }
 
@@ -2162,7 +2162,7 @@ void Compiler::optMapComplementary(AssertionIndex assertionIndex, AssertionIndex
  *  Given an assertion index, return the assertion index of the complementary
  *  assertion or 0 if one does not exist.
  */
-Compiler::AssertionIndex Compiler::optFindComplementary(AssertionIndex assertIndex)
+AssertionIndex Compiler::optFindComplementary(AssertionIndex assertIndex)
 {
     if (assertIndex == NO_ASSERTION_INDEX)
     {
@@ -2205,9 +2205,7 @@ Compiler::AssertionIndex Compiler::optFindComplementary(AssertionIndex assertInd
  *  if one such assertion could not be found in "assertions."
  */
 
-Compiler::AssertionIndex Compiler::optAssertionIsSubrange(GenTreePtr       tree,
-                                                          var_types        toType,
-                                                          ASSERT_VALARG_TP assertions)
+AssertionIndex Compiler::optAssertionIsSubrange(GenTreePtr tree, var_types toType, ASSERT_VALARG_TP assertions)
 {
     if (!optLocalAssertionProp && BitVecOps::IsEmpty(apTraits, assertions))
     {
@@ -2273,9 +2271,7 @@ Compiler::AssertionIndex Compiler::optAssertionIsSubrange(GenTreePtr       tree,
  * could not be found, then it returns NO_ASSERTION_INDEX.
  *
  */
-Compiler::AssertionIndex Compiler::optAssertionIsSubtype(GenTreePtr       tree,
-                                                         GenTreePtr       methodTableArg,
-                                                         ASSERT_VALARG_TP assertions)
+AssertionIndex Compiler::optAssertionIsSubtype(GenTreePtr tree, GenTreePtr methodTableArg, ASSERT_VALARG_TP assertions)
 {
     if (!optLocalAssertionProp && BitVecOps::IsEmpty(apTraits, assertions))
     {
@@ -2933,7 +2929,7 @@ GenTreePtr Compiler::optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, const
  *  op1Kind and lclNum, op2Kind and the constant value and is either equal or
  *  not equal assertion.
  */
-Compiler::AssertionIndex Compiler::optLocalAssertionIsEqualOrNotEqual(
+AssertionIndex Compiler::optLocalAssertionIsEqualOrNotEqual(
     optOp1Kind op1Kind, unsigned lclNum, optOp2Kind op2Kind, ssize_t cnsVal, ASSERT_VALARG_TP assertions)
 {
     noway_assert((op1Kind == O1K_LCLVAR) || (op1Kind == O1K_EXACT_TYPE) || (op1Kind == O1K_SUBTYPE));
@@ -2975,9 +2971,9 @@ Compiler::AssertionIndex Compiler::optLocalAssertionIsEqualOrNotEqual(
  *  "op1" == "op2" or "op1" != "op2." Does a value number based comparison.
  *
  */
-Compiler::AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP assertions,
-                                                                       GenTreePtr       op1,
-                                                                       GenTreePtr       op2)
+AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP assertions,
+                                                             GenTreePtr       op1,
+                                                             GenTreePtr       op2)
 {
     if (BitVecOps::IsEmpty(apTraits, assertions))
     {
@@ -3531,7 +3527,7 @@ bool Compiler::optAssertionIsNonNull(GenTreePtr       op,
  *  from the set of "assertions."
  *
  */
-Compiler::AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTreePtr op, ASSERT_VALARG_TP assertions)
+AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTreePtr op, ASSERT_VALARG_TP assertions)
 {
     // If local assertion prop use lcl comparison, else use VN comparison.
     if (!optLocalAssertionProp)
@@ -4472,11 +4468,11 @@ ASSERT_TP* Compiler::optComputeAssertionGen()
                     break;
                 }
 
-                AssertionIndex index = tree->GetAssertion();
-                if (index != NO_ASSERTION_INDEX)
+                if (tree->GeneratesAssertion())
                 {
-                    optImpliedAssertions(index, valueGen);
-                    BitVecOps::AddElemD(apTraits, valueGen, index - 1);
+                    AssertionInfo info = tree->GetAssertionInfo();
+                    optImpliedAssertions(info.GetAssertionIndex(), valueGen);
+                    BitVecOps::AddElemD(apTraits, valueGen, info.GetAssertionIndex() - 1);
                 }
             }
         }
@@ -4486,30 +4482,35 @@ ASSERT_TP* Compiler::optComputeAssertionGen()
             // Copy whatever we have accumulated into jumpDest edge's valueGen.
             ASSERT_TP jumpDestValueGen = BitVecOps::MakeCopy(apTraits, valueGen);
 
-            AssertionIndex index = jtrue->GetAssertion();
-            if ((index & OAE_INDEX_MASK) != NO_ASSERTION_INDEX)
+            if (jtrue->GeneratesAssertion())
             {
-                if ((index & OAE_NEXT_EDGE) != 0)
+                AssertionInfo  info = jtrue->GetAssertionInfo();
+                AssertionIndex valueAssertionIndex;
+                AssertionIndex jumpDestAssertionIndex;
+
+                if (info.IsNextEdgeAssertion())
                 {
-                    index &= OAE_INDEX_MASK;
-                    // Currently OAE_NEXT_EDGE is only used with OAK_NO_THROW assertions
-                    assert(optGetAssertion(index)->assertionKind == OAK_NO_THROW);
-                    // Don't bother with implied assertions, there aren't any for OAK_NO_THROW
-                    BitVecOps::AddElemD(apTraits, valueGen, index - 1);
+                    valueAssertionIndex    = info.GetAssertionIndex();
+                    jumpDestAssertionIndex = optFindComplementary(info.GetAssertionIndex());
                 }
-                else
+                else // is jump edge assertion
                 {
-                    // If GT_JTRUE, and true path, update jumpDestValueGen.
-                    optImpliedAssertions(index, jumpDestValueGen);
-                    BitVecOps::AddElemD(apTraits, jumpDestValueGen, index - 1);
+                    valueAssertionIndex    = optFindComplementary(info.GetAssertionIndex());
+                    jumpDestAssertionIndex = info.GetAssertionIndex();
+                }
 
-                    index = optFindComplementary(index);
-                    if (index != NO_ASSERTION_INDEX)
-                    {
-                        // If GT_JTRUE, and false path and we have a complementary assertion available update valueGen
-                        optImpliedAssertions(index, valueGen);
-                        BitVecOps::AddElemD(apTraits, valueGen, index - 1);
-                    }
+                if (valueAssertionIndex != NO_ASSERTION_INDEX)
+                {
+                    // Update valueGen if we have an assertion for the bbNext edge
+                    optImpliedAssertions(valueAssertionIndex, valueGen);
+                    BitVecOps::AddElemD(apTraits, valueGen, valueAssertionIndex - 1);
+                }
+
+                if (jumpDestAssertionIndex != NO_ASSERTION_INDEX)
+                {
+                    // Update jumpDestValueGen if we have an assertion for the bbJumpDest edge
+                    optImpliedAssertions(jumpDestAssertionIndex, jumpDestValueGen);
+                    BitVecOps::AddElemD(apTraits, jumpDestValueGen, jumpDestAssertionIndex - 1);
                 }
             }
 
@@ -5122,7 +5123,7 @@ void Compiler::optAssertionPropMain()
 
                 JITDUMP("Propagating %s assertions for BB%02d, stmt [%06d], tree [%06d], tree -> %d\n",
                         BitVecOps::ToString(apTraits, assertions), block->bbNum, dspTreeID(stmt), dspTreeID(tree),
-                        tree->GetAssertion());
+                        tree->GetAssertionInfo().GetAssertionIndex());
 
                 GenTreePtr newTree = optAssertionProp(assertions, tree, stmt);
                 if (newTree)
@@ -5132,11 +5133,11 @@ void Compiler::optAssertionPropMain()
                 }
 
                 // If this tree makes an assertion - make it available.
-                AssertionIndex index = tree->GetAssertion();
-                if (index != NO_ASSERTION_INDEX)
+                if (tree->GeneratesAssertion())
                 {
-                    optImpliedAssertions(index, assertions);
-                    BitVecOps::AddElemD(apTraits, assertions, index - 1);
+                    AssertionInfo info = tree->GetAssertionInfo();
+                    optImpliedAssertions(info.GetAssertionIndex(), assertions);
+                    BitVecOps::AddElemD(apTraits, assertions, info.GetAssertionIndex() - 1);
                 }
             }
 
index 07ce772..8d2f85e 100644 (file)
@@ -5906,21 +5906,6 @@ public:
         }
     };
 
-    typedef unsigned short AssertionIndex;
-
-    // By default the assertion generated by a GT_JTRUE node holds on the true (bbJumpDest) edge.
-    // If the OAE_NEXT_EDGE bit of the assertion index is set then the assertion holds on the false (bbNext) edge
-    // and the OAE_NEXT_EDGE bit needs to be masked to obtain the real assertion index.
-    // Currently this is used by OAK_NO_THROW assertions but it may also be useful for other kinds of assertions
-    // by removing the need to create unnecessary complementary assertions. However, this bit twiddling mechanism
-    // is fragile and should be replaced with something cleaner (e.g. struct + bitfield).
-    enum optAssertionEdge : AssertionIndex
-    {
-        // OAE_JUMP_EDGE  = 0x0000, // assertion holds for bbJumpDest (default)
-        OAE_NEXT_EDGE  = 0x8000, // assertion holds for bbNext
-        OAE_INDEX_MASK = 0x7fff
-    };
-
 protected:
     static fgWalkPreFn optAddCopiesCallback;
     static fgWalkPreFn optVNAssertionPropCurStmtVisitor;
@@ -5957,8 +5942,6 @@ public:
                           ValueNumToAssertsMap;
     ValueNumToAssertsMap* optValueNumToAsserts;
 
-    static const AssertionIndex NO_ASSERTION_INDEX = 0;
-
     // Assertion prop helpers.
     ASSERT_TP& GetAssertionDep(unsigned lclNum);
     AssertionDsc* optGetAssertion(AssertionIndex assertIndex);
@@ -5979,8 +5962,8 @@ public:
     // Assertion Gen functions.
     void optAssertionGen(GenTreePtr tree);
     AssertionIndex optAssertionGenPhiDefn(GenTreePtr tree);
-    AssertionIndex optCreateJTrueBoundsAssertion(GenTreePtr tree);
-    AssertionIndex optAssertionGenJtrue(GenTreePtr tree);
+    AssertionInfo optCreateJTrueBoundsAssertion(GenTreePtr tree);
+    AssertionInfo optAssertionGenJtrue(GenTreePtr tree);
     AssertionIndex optCreateJtrueAssertions(GenTreePtr op1, GenTreePtr op2, Compiler::optAssertionKind assertionKind);
     AssertionIndex optFindComplementary(AssertionIndex assertionIndex);
     void optMapComplementary(AssertionIndex assertionIndex, AssertionIndex index);
index 9007d1e..1f6f5aa 100644 (file)
@@ -8800,8 +8800,8 @@ void GenTree::CopyTo(class Compiler* comp, const GenTree& gt)
 {
     SetOperRaw(gt.OperGet());
 
-    gtType         = gt.gtType;
-    gtAssertionNum = gt.gtAssertionNum;
+    gtType          = gt.gtType;
+    gtAssertionInfo = gt.gtAssertionInfo;
 
     gtRegNum = gt.gtRegNum; // one union member.
     CopyCosts(&gt);
index aac1958..d910ca4 100644 (file)
@@ -149,6 +149,61 @@ struct BasicBlock;
 
 struct InlineCandidateInfo;
 
+typedef unsigned short AssertionIndex;
+
+static const AssertionIndex NO_ASSERTION_INDEX = 0;
+
+class AssertionInfo
+{
+    // true if the assertion holds on the bbNext edge instead of the bbJumpDest edge (for GT_JTRUE nodes)
+    unsigned short m_isNextEdgeAssertion : 1;
+    // 1-based index of the assertion
+    unsigned short m_assertionIndex : 15;
+
+    AssertionInfo(bool isNextEdgeAssertion, AssertionIndex assertionIndex)
+        : m_isNextEdgeAssertion(isNextEdgeAssertion), m_assertionIndex(assertionIndex)
+    {
+        assert(m_assertionIndex == assertionIndex);
+    }
+
+public:
+    AssertionInfo() : AssertionInfo(false, 0)
+    {
+    }
+
+    AssertionInfo(AssertionIndex assertionIndex) : AssertionInfo(false, assertionIndex)
+    {
+    }
+
+    static AssertionInfo ForNextEdge(AssertionIndex assertionIndex)
+    {
+        // Ignore the edge information if there's no assertion
+        bool isNextEdge = (assertionIndex != NO_ASSERTION_INDEX);
+        return AssertionInfo(isNextEdge, assertionIndex);
+    }
+
+    void Clear()
+    {
+        m_isNextEdgeAssertion = 0;
+        m_assertionIndex      = NO_ASSERTION_INDEX;
+    }
+
+    bool HasAssertion() const
+    {
+        return m_assertionIndex != NO_ASSERTION_INDEX;
+    }
+
+    AssertionIndex GetAssertionIndex() const
+    {
+        return m_assertionIndex;
+    }
+
+    bool IsNextEdgeAssertion() const
+    {
+        return m_isNextEdgeAssertion;
+    }
+};
+
 /*****************************************************************************/
 
 // GT_FIELD nodes will be lowered into more "code-gen-able" representations, like
@@ -396,29 +451,27 @@ struct GenTree
     unsigned char gtLIRFlags; // Used for nodes that are in LIR. See LIR::Flags in lir.h for the various flags.
 
 #if ASSERTION_PROP
-    unsigned short gtAssertionNum; // 0 or Assertion table index
-                                   // possibly ORed with optAssertionEdge::OAE_NEXT_EDGE
-                                   // valid only for non-GT_STMT nodes
+    AssertionInfo gtAssertionInfo; // valid only for non-GT_STMT nodes
 
-    bool HasAssertion() const
+    bool GeneratesAssertion() const
     {
-        return gtAssertionNum != 0;
+        return gtAssertionInfo.HasAssertion();
     }
+
     void ClearAssertion()
     {
-        gtAssertionNum = 0;
+        gtAssertionInfo.Clear();
     }
 
-    unsigned short GetAssertion() const
+    AssertionInfo GetAssertionInfo() const
     {
-        return gtAssertionNum;
+        return gtAssertionInfo;
     }
-    void SetAssertion(unsigned short value)
+
+    void SetAssertionInfo(AssertionInfo info)
     {
-        assert((unsigned short)value == value);
-        gtAssertionNum = (unsigned short)value;
+        gtAssertionInfo = info;
     }
-
 #endif
 
 #if FEATURE_STACK_FP_X87
index 22b5328..91ae81e 100644 (file)
@@ -506,7 +506,7 @@ void RangeCheck::MergeEdgeAssertions(GenTreePtr tree, const ASSERT_VALARG_TP ass
     {
         index++;
 
-        Compiler::AssertionDsc* curAssertion = m_pCompiler->optGetAssertion((Compiler::AssertionIndex)index);
+        Compiler::AssertionDsc* curAssertion = m_pCompiler->optGetAssertion((AssertionIndex)index);
 
         // Current assertion is about array length.
         if (!curAssertion->IsArrLenArithBound() && !curAssertion->IsArrLenBound() && !curAssertion->IsConstantBound())
@@ -517,7 +517,7 @@ void RangeCheck::MergeEdgeAssertions(GenTreePtr tree, const ASSERT_VALARG_TP ass
 #ifdef DEBUG
         if (m_pCompiler->verbose)
         {
-            m_pCompiler->optPrintAssertion(curAssertion, (Compiler::AssertionIndex)index);
+            m_pCompiler->optPrintAssertion(curAssertion, (AssertionIndex)index);
         }
 #endif
 
@@ -617,7 +617,7 @@ void RangeCheck::MergeEdgeAssertions(GenTreePtr tree, const ASSERT_VALARG_TP ass
 #ifdef DEBUG
         if (m_pCompiler->verbose)
         {
-            m_pCompiler->optPrintAssertion(curAssertion, (Compiler::AssertionIndex)index);
+            m_pCompiler->optPrintAssertion(curAssertion, (AssertionIndex)index);
         }
 #endif