summaryrefslogtreecommitdiff
path: root/src/jit/assertionprop.cpp
diff options
context:
space:
mode:
authorMike Danes <onemihaid@hotmail.com>2017-03-11 11:04:04 +0200
committerMike Danes <onemihaid@hotmail.com>2017-03-20 23:26:27 +0200
commitd6b17aa51b29f756a7aa4061d171636d6da3d030 (patch)
treea2b3f44e50c215bfbd62087aed54d210f9c5188e /src/jit/assertionprop.cpp
parent671701167d2dc8f0297f08c67482b565684d8c79 (diff)
downloadcoreclr-d6b17aa51b29f756a7aa4061d171636d6da3d030.tar.gz
coreclr-d6b17aa51b29f756a7aa4061d171636d6da3d030.tar.bz2
coreclr-d6b17aa51b29f756a7aa4061d171636d6da3d030.zip
Refactor GenTree assertion information storage
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).
Diffstat (limited to 'src/jit/assertionprop.cpp')
-rw-r--r--src/jit/assertionprop.cpp141
1 files changed, 71 insertions, 70 deletions
diff --git a/src/jit/assertionprop.cpp b/src/jit/assertionprop.cpp
index 599cdf3055..0c5b8f3055 100644
--- a/src/jit/assertionprop.cpp
+++ b/src/jit/assertionprop.cpp
@@ -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);
}
}