diff options
author | Mike Danes <onemihaid@hotmail.com> | 2017-03-11 11:04:04 +0200 |
---|---|---|
committer | Mike Danes <onemihaid@hotmail.com> | 2017-03-20 23:26:27 +0200 |
commit | d6b17aa51b29f756a7aa4061d171636d6da3d030 (patch) | |
tree | a2b3f44e50c215bfbd62087aed54d210f9c5188e /src/jit/assertionprop.cpp | |
parent | 671701167d2dc8f0297f08c67482b565684d8c79 (diff) | |
download | coreclr-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.cpp | 141 |
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); } } |