{
if (tree->gtOper == GT_JTRUE)
{
+ // A GT_TRUE is always the last node in a tree, so we can break here
assert((tree->gtNext == nullptr) && (stmt->gtNext == nullptr));
jtrue = tree;
break;
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/complementary assertions, there aren't any for OAK_NO_THROW
+ // Don't bother with implied assertions, there aren't any for OAK_NO_THROW
BitVecOps::AddElemD(apTraits, valueGen, index - 1);
}
else
{
+ // If GT_JTRUE, and true path, update jumpDestValueGen.
optImpliedAssertions(index, jumpDestValueGen);
BitVecOps::AddElemD(apTraits, jumpDestValueGen, index - 1);
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 (tree->OperIs(GT_JTRUE))
{
+ // A GT_TRUE is always the last node in a tree, so we can break here
assert((tree->gtNext == nullptr) && (stmt->gtNext == nullptr));
break;
}
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)
#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
bool HasAssertion() const
}
//------------------------------------------------------------------------
-// IsVNArrLenUnsignedBound: Checks if the specified vn represents an
-// expression such as "(uint)i < (uint)a.len" that imply that the
-// array index is valid (0 <= i && i < a.len).
+// IsVNArrLenUnsignedBound: Checks if the specified vn represents an expression
+// such as "(uint)i < (uint)a.len" that implies that the array index is valid
+// (0 <= i && i < a.len).
//
// Arguments:
// vn - Value number to query
-// info - Pointer to a ArrLenUnsignedBoundInfo object to return
-// information about the expression. Not populated if the
-// vn expression isn't suitable (e.g. i <= a.len)
+// info - Pointer to an ArrLenUnsignedBoundInfo object to return information about
+// the expression. Not populated if the vn expression isn't suitable (e.g. i <= a.len).
+// This enables optCreateJTrueBoundAssertion to immediatly create an OAK_NO_THROW
+// assertion instead of the OAK_EQUAL/NOT_EQUAL assertions created by signed compares
+// (IsVNArrLenBound, IsVNArrLenArithBound) that require further processing.
bool ValueNumStore::IsVNArrLenUnsignedBound(ValueNum vn, ArrLenUnsignedBoundInfo* info)
{