@@ -13780,10 +13780,78 @@ void Compiler::fgMorphBlock(BasicBlock* block)
13780
13780
13781
13781
if (optLocalAssertionProp)
13782
13782
{
13783
- // For now, each block starts with an empty table, and no available assertions
13783
+ // Determine if this block can leverage assertions from its pred blocks.
13784
13784
//
13785
- optAssertionReset(0);
13786
- apLocal = BitVecOps::MakeEmpty(apTraits);
13785
+ // Some blocks are ineligible.
13786
+ //
13787
+ bool canUsePredAssertions = ((block->bbFlags & BBF_CAN_ADD_PRED) == 0) && !bbIsHandlerBeg(block);
13788
+
13789
+ #ifdef DEBUG
13790
+ // Optionally suppress via config
13791
+ //
13792
+ if (JitConfig.JitDoCrossBlockLocalAssertionProp() == 0)
13793
+ {
13794
+ canUsePredAssertions = false;
13795
+ }
13796
+ #endif
13797
+
13798
+ // Validate all preds have valid info
13799
+ //
13800
+ if (canUsePredAssertions)
13801
+ {
13802
+ bool hasPred = false;
13803
+
13804
+ for (BasicBlock* const pred : block->PredBlocks())
13805
+ {
13806
+ // A higher postorder number means the block appears earlier in
13807
+ // the postorder. Use this to detect if a pred's assertion info is available.
13808
+ //
13809
+ if (pred->bbPostorderNum > block->bbPostorderNum)
13810
+ {
13811
+ // Yes, available. If this is the first pred, copy.
13812
+ // If this is a subsequent pred, intersect.
13813
+ //
13814
+ if (!hasPred)
13815
+ {
13816
+ apLocal = BitVecOps::MakeCopy(apTraits, pred->bbAssertionOut);
13817
+ hasPred = true;
13818
+ }
13819
+ else
13820
+ {
13821
+ BitVecOps::IntersectionD(apTraits, apLocal, pred->bbAssertionOut);
13822
+ }
13823
+
13824
+ continue;
13825
+ }
13826
+
13827
+ // No, not available.
13828
+ //
13829
+ JITDUMP(FMT_BB " pred " FMT_BB " not processed; clearing assertions in\n", block->bbNum, pred->bbNum);
13830
+ canUsePredAssertions = false;
13831
+ }
13832
+
13833
+ // If there were no preds, there are no asserions in.
13834
+ //
13835
+ if (!hasPred)
13836
+ {
13837
+ JITDUMP(FMT_BB " has no preds, so no assertions in\n", block->bbNum);
13838
+ canUsePredAssertions = false;
13839
+ }
13840
+
13841
+ if (canUsePredAssertions)
13842
+ {
13843
+ JITDUMPEXEC(optDumpAssertionIndices("Assertions in: ", apLocal));
13844
+ }
13845
+ }
13846
+ else
13847
+ {
13848
+ JITDUMP(FMT_BB " ineligible for cross-block; clearing assertions in\n", block->bbNum);
13849
+ }
13850
+
13851
+ if (!canUsePredAssertions)
13852
+ {
13853
+ apLocal = BitVecOps::MakeEmpty(apTraits);
13854
+ }
13787
13855
}
13788
13856
13789
13857
// Make the current basic block address available globally.
@@ -13801,6 +13869,11 @@ void Compiler::fgMorphBlock(BasicBlock* block)
13801
13869
}
13802
13870
}
13803
13871
13872
+ if (optLocalAssertionProp && (block->NumSucc() > 0))
13873
+ {
13874
+ block->bbAssertionOut = BitVecOps::MakeCopy(apTraits, apLocal);
13875
+ }
13876
+
13804
13877
compCurBB = nullptr;
13805
13878
}
13806
13879
0 commit comments