@@ -554,14 +554,14 @@ void Compiler::optAssertionInit(bool isLocalProp)
554554
555555 optLocalAssertionProp = isLocalProp;
556556 optAssertionTabPrivate = new (this , CMK_AssertionProp) AssertionDsc[optMaxAssertionCount];
557- optComplementaryAssertionMap =
558- new (this , CMK_AssertionProp) AssertionIndex[optMaxAssertionCount + 1 ](); // zero-inited (NO_ASSERTION_INDEX)
559557 assert (NO_ASSERTION_INDEX == 0 );
560558
561559 if (!isLocalProp)
562560 {
563561 optValueNumToAsserts =
564562 new (getAllocator (CMK_AssertionProp)) ValueNumToAssertsMap (getAllocator (CMK_AssertionProp));
563+ optComplementaryAssertionMap = new (this , CMK_AssertionProp)
564+ AssertionIndex[optMaxAssertionCount + 1 ](); // zero-inited (NO_ASSERTION_INDEX)
565565 }
566566
567567 if (optAssertionDep == nullptr )
@@ -572,6 +572,7 @@ void Compiler::optAssertionInit(bool isLocalProp)
572572
573573 optAssertionTraitsInit (optMaxAssertionCount);
574574 optAssertionCount = 0 ;
575+ optAssertionOverflow = 0 ;
575576 optAssertionPropagated = false ;
576577 bbJtrueAssertionOut = nullptr ;
577578 optCanPropLclVar = false ;
@@ -1607,6 +1608,7 @@ AssertionIndex Compiler::optAddAssertion(AssertionDsc* newAssertion)
16071608 // Check if we are within max count.
16081609 if (optAssertionCount >= optMaxAssertionCount)
16091610 {
1611+ optAssertionOverflow++;
16101612 return NO_ASSERTION_INDEX;
16111613 }
16121614
@@ -2370,8 +2372,7 @@ void Compiler::optAssertionGen(GenTree* tree)
23702372 break ;
23712373 }
23722374
2373- // For global assertion prop we must store the assertion number in the tree node
2374- if (assertionInfo.HasAssertion () && assertionProven && !optLocalAssertionProp)
2375+ if (assertionInfo.HasAssertion () && assertionProven)
23752376 {
23762377 tree->SetAssertionInfo (assertionInfo);
23772378 }
@@ -2459,9 +2460,7 @@ AssertionIndex Compiler::optAssertionIsSubrange(GenTree* tree, IntegralRange ran
24592460 for (AssertionIndex index = 1 ; index <= optAssertionCount; index++)
24602461 {
24612462 AssertionDsc* curAssertion = optGetAssertion (index);
2462- if ((optLocalAssertionProp ||
2463- BitVecOps::IsMember (apTraits, assertions, index - 1 )) && // either local prop or use propagated assertions
2464- curAssertion->CanPropSubRange ())
2463+ if (BitVecOps::IsMember (apTraits, assertions, index - 1 ) && curAssertion->CanPropSubRange ())
24652464 {
24662465 // For local assertion prop use comparison on locals, and use comparison on vns for global prop.
24672466 bool isEqual = optLocalAssertionProp
@@ -2493,13 +2492,13 @@ AssertionIndex Compiler::optAssertionIsSubrange(GenTree* tree, IntegralRange ran
24932492 */
24942493AssertionIndex Compiler::optAssertionIsSubtype (GenTree* tree, GenTree* methodTableArg, ASSERT_VALARG_TP assertions)
24952494{
2496- if (!optLocalAssertionProp && BitVecOps::IsEmpty (apTraits, assertions))
2495+ if (BitVecOps::IsEmpty (apTraits, assertions))
24972496 {
24982497 return NO_ASSERTION_INDEX;
24992498 }
25002499 for (AssertionIndex index = 1 ; index <= optAssertionCount; index++)
25012500 {
2502- if (!optLocalAssertionProp && ! BitVecOps::IsMember (apTraits, assertions, index - 1 ))
2501+ if (!BitVecOps::IsMember (apTraits, assertions, index - 1 ))
25032502 {
25042503 continue ;
25052504 }
@@ -3594,15 +3593,15 @@ AssertionIndex Compiler::optLocalAssertionIsEqualOrNotEqual(
35943593{
35953594 noway_assert ((op1Kind == O1K_LCLVAR) || (op1Kind == O1K_EXACT_TYPE) || (op1Kind == O1K_SUBTYPE));
35963595 noway_assert ((op2Kind == O2K_CONST_INT) || (op2Kind == O2K_IND_CNS_INT) || (op2Kind == O2K_ZEROOBJ));
3597- if (!optLocalAssertionProp && BitVecOps::IsEmpty (apTraits, assertions))
3596+ if (BitVecOps::IsEmpty (apTraits, assertions))
35983597 {
35993598 return NO_ASSERTION_INDEX;
36003599 }
36013600
36023601 for (AssertionIndex index = 1 ; index <= optAssertionCount; ++index)
36033602 {
36043603 AssertionDsc* curAssertion = optGetAssertion (index);
3605- if (optLocalAssertionProp || BitVecOps::IsMember (apTraits, assertions, index - 1 ))
3604+ if (BitVecOps::IsMember (apTraits, assertions, index - 1 ))
36063605 {
36073606 if ((curAssertion->assertionKind != OAK_EQUAL) && (curAssertion->assertionKind != OAK_NOT_EQUAL))
36083607 {
@@ -4386,17 +4385,27 @@ AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTree* op,
43864385 }
43874386 else
43884387 {
4389- unsigned lclNum = op->AsLclVarCommon ()->GetLclNum ();
4390- // Check each assertion to find if we have a variable == or != null assertion.
4391- for (AssertionIndex index = 1 ; index <= optAssertionCount; index++)
4388+ // Find live assertions related to lclNum
4389+ //
4390+ unsigned const lclNum = op->AsLclVarCommon ()->GetLclNum ();
4391+ ASSERT_TP apDependent = GetAssertionDep (lclNum);
4392+ BitVecOps::IntersectionD (apTraits, apDependent, apLocal);
4393+
4394+ // Scan those looking for a suitable assertion
4395+ //
4396+ BitVecOps::Iter iter (apTraits, assertions);
4397+ unsigned index = 0 ;
4398+ while (iter.NextElem (&index))
43924399 {
4393- AssertionDsc* curAssertion = optGetAssertion (index);
4400+ AssertionIndex assertionIndex = GetAssertionIndex (index);
4401+ AssertionDsc* curAssertion = optGetAssertion (assertionIndex);
4402+
43944403 if ((curAssertion->assertionKind == OAK_NOT_EQUAL) && // kind
43954404 (curAssertion->op1 .kind == O1K_LCLVAR) && // op1
43964405 (curAssertion->op2 .kind == O2K_CONST_INT) && // op2
43974406 (curAssertion->op1 .lcl .lclNum == lclNum) && (curAssertion->op2 .u1 .iconVal == 0 ))
43984407 {
4399- return index ;
4408+ return assertionIndex ;
44004409 }
44014410 }
44024411 }
0 commit comments