@@ -763,59 +763,87 @@ bool Compiler::fgRemoveDeadBlocks()
763
763
764
764
// -------------------------------------------------------------
765
765
// fgDfsReversePostorder: Depth first search to establish block
766
- // preorder and reverse postorder numbers, plus a reverse postorder for blocks.
766
+ // preorder and reverse postorder numbers, plus a reverse postorder for blocks,
767
+ // using all entry blocks and EH handler blocks as start blocks.
767
768
//
768
769
// Notes:
769
- // Assumes caller has computed the fgEnterBlks set.
770
- //
771
770
// Each block's `bbPreorderNum` and `bbPostorderNum` is set.
772
- //
773
771
// The `fgBBReversePostorder` array is filled in with the `BasicBlock*` in reverse post-order.
774
- //
775
772
// This algorithm only pays attention to the actual blocks. It ignores any imaginary entry block.
776
773
//
777
- void Compiler::fgDfsReversePostorder ()
774
+ // Unreachable blocks will have higher pre and post order numbers than reachable blocks.
775
+ // Hence they will appear at lower indices in the fgBBReversePostorder array.
776
+ //
777
+ unsigned Compiler::fgDfsReversePostorder ()
778
778
{
779
779
assert (fgBBcount == fgBBNumMax);
780
780
assert (BasicBlockBitSetTraits::GetSize (this ) == fgBBNumMax + 1 );
781
-
782
- // Make sure fgEnterBlks are still there in startNodes, even if they participate in a loop (i.e., there is
783
- // an incoming edge into the block).
784
- assert (fgEnterBlksSetValid);
785
-
786
781
fgBBReversePostorder = new (this , CMK_DominatorMemory) BasicBlock*[fgBBNumMax + 1 ]{};
787
-
788
- // visited : Once we run the DFS post order sort recursive algorithm, we mark the nodes we visited to avoid
789
- // backtracking.
790
782
BlockSet visited (BlockSetOps::MakeEmpty (this ));
791
783
792
- // We begin by figuring out which basic blocks don't have incoming edges and mark them as
793
- // start nodes. Later on we run the recursive algorithm for each node that we
794
- // mark in this step.
795
- BlockSet_ValRet_T startNodes = fgDomFindStartNodes ();
796
-
797
- BlockSetOps::UnionD (this , startNodes, fgEnterBlks);
798
- assert (BlockSetOps::IsMember (this , startNodes, fgFirstBB->bbNum ));
799
-
800
- // Call the flowgraph DFS traversal helper.
801
784
unsigned preorderIndex = 1 ;
802
785
unsigned postorderIndex = 1 ;
803
- for (BasicBlock* const block : Blocks ())
786
+
787
+ // Walk from our primary root.
788
+ //
789
+ fgDfsReversePostorderHelper (fgFirstBB, visited, preorderIndex, postorderIndex);
790
+
791
+ // If we didn't end up visiting everything, try the EH roots.
792
+ //
793
+ if (preorderIndex != fgBBcount + 1 )
804
794
{
805
- // If the block has no predecessors, and we haven't already visited it (because it's in fgEnterBlks but also
806
- // reachable from the first block), go ahead and traverse starting from this block.
807
- if (BlockSetOps::IsMember (this , startNodes, block->bbNum ) &&
808
- !BlockSetOps::IsMember (this , visited, block->bbNum ))
795
+ for (EHblkDsc* const HBtab : EHClauses (this ))
809
796
{
810
- fgDfsReversePostorderHelper (block, visited, preorderIndex, postorderIndex);
797
+ if (HBtab->HasFilter ())
798
+ {
799
+ BasicBlock* const filterBlock = HBtab->ebdFilter ;
800
+ if (!BlockSetOps::IsMember (this , visited, filterBlock->bbNum ))
801
+ {
802
+ fgDfsReversePostorderHelper (filterBlock, visited, preorderIndex, postorderIndex);
803
+ }
804
+ }
805
+
806
+ BasicBlock* const handlerBlock = HBtab->ebdHndBeg ;
807
+ if (!BlockSetOps::IsMember (this , visited, handlerBlock->bbNum ))
808
+ {
809
+ fgDfsReversePostorderHelper (handlerBlock, visited, preorderIndex, postorderIndex);
810
+ }
811
+
812
+ #if defined(FEATURE_EH_FUNCLETS) && defined(TARGET_ARM)
813
+ // For ARM code, prevent creating retless calls by visiting the call finally successors
814
+ //
815
+ if (HBtab->HasFinallyHandler ())
816
+ {
817
+ for (BasicBlock* const finallyPredBlock : handlerBlock->PredBlocks ())
818
+ {
819
+ // In some rare cases the finally is a loop entry.
820
+ //
821
+ if (!finallyPredBlock->KindIs (BBJ_CALLFINALLY))
822
+ {
823
+ continue ;
824
+ }
825
+ assert (finallyPredBlock->isBBCallAlwaysPair ());
826
+ BasicBlock* const pairTailBlock = finallyPredBlock->Next ();
827
+
828
+ if (!BlockSetOps::IsMember (this , visited, pairTailBlock->bbNum ))
829
+ {
830
+ fgDfsReversePostorderHelper (pairTailBlock, visited, preorderIndex, postorderIndex);
831
+ }
832
+ }
833
+ }
834
+ #endif // defined(FEATURE_EH_FUNCLETS) && defined(TARGET_ARM)
811
835
}
812
836
}
813
837
814
- // If there are still unvisited blocks (say isolated cycles), visit them too .
838
+ // That's everything reachable from the roots .
815
839
//
816
- if (preorderIndex != fgBBcount + 1 )
840
+ const unsigned highestReachablePostorderNumber = postorderIndex - 1 ;
841
+
842
+ // If we still didn't end up visiting everything, visit what remains.
843
+ //
844
+ if (highestReachablePostorderNumber != fgBBcount)
817
845
{
818
- JITDUMP (" DFS: flow graph has some isolated cycles, doing extra traversals \n " );
846
+ JITDUMP (" DFS: there are %u unreachable blocks \n " , fgBBcount - highestReachablePostorderNumber );
819
847
for (BasicBlock* const block : Blocks ())
820
848
{
821
849
if (!BlockSetOps::IsMember (this , visited, block->bbNum ))
@@ -841,48 +869,12 @@ void Compiler::fgDfsReversePostorder()
841
869
printf (" \n " );
842
870
}
843
871
#endif // DEBUG
844
- }
845
-
846
- // -------------------------------------------------------------
847
- // fgDomFindStartNodes: Helper for dominance computation to find the start nodes block set.
848
- //
849
- // The start nodes is a set that represents which basic blocks in the flow graph don't have incoming edges.
850
- // We begin assuming everything is a start block and remove any block that is a successor of another.
851
- //
852
- // Returns:
853
- // Block set of start nodes.
854
- //
855
- BlockSet_ValRet_T Compiler::fgDomFindStartNodes ()
856
- {
857
- BlockSet startNodes (BlockSetOps::MakeFull (this ));
858
-
859
- for (BasicBlock* const block : Blocks ())
860
- {
861
- for (BasicBlock* const succ : block->Succs (this ))
862
- {
863
- BlockSetOps::RemoveElemD (this , startNodes, succ->bbNum );
864
- }
865
- }
866
-
867
- #ifdef DEBUG
868
- if (verbose)
869
- {
870
- printf (" \n Dominator computation start blocks (those blocks with no incoming edges):\n " );
871
- BlockSetOps::Iter iter (this , startNodes);
872
- unsigned bbNum = 0 ;
873
- while (iter.NextElem (&bbNum))
874
- {
875
- printf (FMT_BB " " , bbNum);
876
- }
877
- printf (" \n " );
878
- }
879
- #endif // DEBUG
880
872
881
- return startNodes ;
873
+ return highestReachablePostorderNumber ;
882
874
}
883
875
884
876
// ------------------------------------------------------------------------
885
- // fgDfsReversePostorderHelper: Helper to assign post-order numbers to blocks.
877
+ // fgDfsReversePostorderHelper: Helper to assign post-order numbers to blocks
886
878
//
887
879
// Arguments:
888
880
// block - The starting entry block
0 commit comments