@@ -554,14 +554,14 @@ void Compiler::optAssertionInit(bool isLocalProp)
554
554
555
555
optLocalAssertionProp = isLocalProp;
556
556
optAssertionTabPrivate = new (this , CMK_AssertionProp) AssertionDsc[optMaxAssertionCount];
557
- optComplementaryAssertionMap =
558
- new (this , CMK_AssertionProp) AssertionIndex[optMaxAssertionCount + 1 ](); // zero-inited (NO_ASSERTION_INDEX)
559
557
assert (NO_ASSERTION_INDEX == 0 );
560
558
561
559
if (!isLocalProp)
562
560
{
563
561
optValueNumToAsserts =
564
562
new (getAllocator (CMK_AssertionProp)) ValueNumToAssertsMap (getAllocator (CMK_AssertionProp));
563
+ optComplementaryAssertionMap = new (this , CMK_AssertionProp)
564
+ AssertionIndex[optMaxAssertionCount + 1 ](); // zero-inited (NO_ASSERTION_INDEX)
565
565
}
566
566
567
567
if (optAssertionDep == nullptr )
@@ -572,6 +572,7 @@ void Compiler::optAssertionInit(bool isLocalProp)
572
572
573
573
optAssertionTraitsInit (optMaxAssertionCount);
574
574
optAssertionCount = 0 ;
575
+ optAssertionOverflow = 0 ;
575
576
optAssertionPropagated = false ;
576
577
bbJtrueAssertionOut = nullptr ;
577
578
optCanPropLclVar = false ;
@@ -1607,6 +1608,7 @@ AssertionIndex Compiler::optAddAssertion(AssertionDsc* newAssertion)
1607
1608
// Check if we are within max count.
1608
1609
if (optAssertionCount >= optMaxAssertionCount)
1609
1610
{
1611
+ optAssertionOverflow++;
1610
1612
return NO_ASSERTION_INDEX;
1611
1613
}
1612
1614
@@ -2370,8 +2372,7 @@ void Compiler::optAssertionGen(GenTree* tree)
2370
2372
break ;
2371
2373
}
2372
2374
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)
2375
2376
{
2376
2377
tree->SetAssertionInfo (assertionInfo);
2377
2378
}
@@ -2459,9 +2460,7 @@ AssertionIndex Compiler::optAssertionIsSubrange(GenTree* tree, IntegralRange ran
2459
2460
for (AssertionIndex index = 1 ; index <= optAssertionCount; index ++)
2460
2461
{
2461
2462
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 ())
2465
2464
{
2466
2465
// For local assertion prop use comparison on locals, and use comparison on vns for global prop.
2467
2466
bool isEqual = optLocalAssertionProp
@@ -2493,13 +2492,13 @@ AssertionIndex Compiler::optAssertionIsSubrange(GenTree* tree, IntegralRange ran
2493
2492
*/
2494
2493
AssertionIndex Compiler::optAssertionIsSubtype (GenTree* tree, GenTree* methodTableArg, ASSERT_VALARG_TP assertions)
2495
2494
{
2496
- if (!optLocalAssertionProp && BitVecOps::IsEmpty (apTraits, assertions))
2495
+ if (BitVecOps::IsEmpty (apTraits, assertions))
2497
2496
{
2498
2497
return NO_ASSERTION_INDEX;
2499
2498
}
2500
2499
for (AssertionIndex index = 1 ; index <= optAssertionCount; index ++)
2501
2500
{
2502
- if (!optLocalAssertionProp && ! BitVecOps::IsMember (apTraits, assertions, index - 1 ))
2501
+ if (!BitVecOps::IsMember (apTraits, assertions, index - 1 ))
2503
2502
{
2504
2503
continue ;
2505
2504
}
@@ -3594,15 +3593,15 @@ AssertionIndex Compiler::optLocalAssertionIsEqualOrNotEqual(
3594
3593
{
3595
3594
noway_assert ((op1Kind == O1K_LCLVAR) || (op1Kind == O1K_EXACT_TYPE) || (op1Kind == O1K_SUBTYPE));
3596
3595
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))
3598
3597
{
3599
3598
return NO_ASSERTION_INDEX;
3600
3599
}
3601
3600
3602
3601
for (AssertionIndex index = 1 ; index <= optAssertionCount; ++index )
3603
3602
{
3604
3603
AssertionDsc* curAssertion = optGetAssertion (index );
3605
- if (optLocalAssertionProp || BitVecOps::IsMember (apTraits, assertions, index - 1 ))
3604
+ if (BitVecOps::IsMember (apTraits, assertions, index - 1 ))
3606
3605
{
3607
3606
if ((curAssertion->assertionKind != OAK_EQUAL) && (curAssertion->assertionKind != OAK_NOT_EQUAL))
3608
3607
{
@@ -4386,17 +4385,27 @@ AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTree* op,
4386
4385
}
4387
4386
else
4388
4387
{
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 ))
4392
4399
{
4393
- AssertionDsc* curAssertion = optGetAssertion (index );
4400
+ AssertionIndex assertionIndex = GetAssertionIndex (index );
4401
+ AssertionDsc* curAssertion = optGetAssertion (assertionIndex);
4402
+
4394
4403
if ((curAssertion->assertionKind == OAK_NOT_EQUAL) && // kind
4395
4404
(curAssertion->op1 .kind == O1K_LCLVAR) && // op1
4396
4405
(curAssertion->op2 .kind == O2K_CONST_INT) && // op2
4397
4406
(curAssertion->op1 .lcl .lclNum == lclNum) && (curAssertion->op2 .u1 .iconVal == 0 ))
4398
4407
{
4399
- return index ;
4408
+ return assertionIndex ;
4400
4409
}
4401
4410
}
4402
4411
}
0 commit comments