@@ -763,54 +763,70 @@ 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 blocks without preds as start lblocks.
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
774
void Compiler::fgDfsReversePostorder ()
778
775
{
779
- assert (fgBBcount == fgBBNumMax);
780
- assert (BasicBlockBitSetTraits::GetSize (this ) == fgBBNumMax + 1 );
781
-
782
776
// Make sure fgEnterBlks are still there in startNodes, even if they participate in a loop (i.e., there is
783
777
// an incoming edge into the block).
784
778
assert (fgEnterBlksSetValid);
785
779
786
- 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
- BlockSet visited (BlockSetOps::MakeEmpty (this ));
791
-
792
780
// 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
781
+ // start blocks . Later on we run the recursive algorithm for each node that we
794
782
// mark in this step.
795
- BlockSet_ValRet_T startNodes = fgDomFindStartNodes ();
783
+ BlockSet_ValRet_T startBlocks = fgDomFindStartBlocks ();
784
+ BlockSetOps::UnionD (this , startBlocks, fgEnterBlks);
785
+ assert (BlockSetOps::IsMember (this , startBlocks, fgFirstBB->bbNum ));
796
786
797
- BlockSetOps::UnionD (this , startNodes, fgEnterBlks);
798
- assert (BlockSetOps::IsMember (this , startNodes, fgFirstBB->bbNum ));
787
+ fgDfsReversePostorderCore (startBlocks);
788
+ }
789
+
790
+ // -------------------------------------------------------------
791
+ // fgDfsReversePostorderCore: Depth first search to establish block
792
+ // preorder and reverse postorder numbers, plus a reverse postorder for blocks,
793
+ // using a specified set of start blocks.
794
+ //
795
+ // Arguments:
796
+ // startBlocks: set of blocks to consider as DFS roots
797
+ //
798
+ // Returns:
799
+ // postorder number of last block reachable from the root set. Any block
800
+ // with a postorder number higher than this was not reachable from the root set.
801
+ //
802
+ // Notes:
803
+ // Each block's `bbPreorderNum` and `bbPostorderNum` is set.
804
+ // The `fgBBReversePostorder` array is filled in with the `BasicBlock*` in reverse post-order.
805
+ // This algorithm only pays attention to the actual blocks. It ignores any imaginary entry block.
806
+ //
807
+ unsigned Compiler::fgDfsReversePostorderCore (BlockSet_ValArg_T startBlocks)
808
+ {
809
+ assert (fgBBcount == fgBBNumMax);
810
+ assert (BasicBlockBitSetTraits::GetSize (this ) == fgBBNumMax + 1 );
811
+ fgBBReversePostorder = new (this , CMK_DominatorMemory) BasicBlock*[fgBBNumMax + 1 ]{};
812
+ BlockSet visited (BlockSetOps::MakeEmpty (this ));
799
813
800
814
// Call the flowgraph DFS traversal helper.
801
815
unsigned preorderIndex = 1 ;
802
816
unsigned postorderIndex = 1 ;
803
817
for (BasicBlock* const block : Blocks ())
804
818
{
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 ) &&
819
+ // Spawn a DFS from each unvisited start block.
820
+ //
821
+ if (BlockSetOps::IsMember (this , startBlocks , block->bbNum ) &&
808
822
!BlockSetOps::IsMember (this , visited, block->bbNum ))
809
823
{
810
824
fgDfsReversePostorderHelper (block, visited, preorderIndex, postorderIndex);
811
825
}
812
826
}
813
827
828
+ const unsigned lastReachablePostorderNumber = postorderIndex;
829
+
814
830
// If there are still unvisited blocks (say isolated cycles), visit them too.
815
831
//
816
832
if (preorderIndex != fgBBcount + 1 )
@@ -841,18 +857,20 @@ void Compiler::fgDfsReversePostorder()
841
857
printf (" \n " );
842
858
}
843
859
#endif // DEBUG
860
+
861
+ return lastReachablePostorderNumber;
844
862
}
845
863
846
864
// -------------------------------------------------------------
847
- // fgDomFindStartNodes : Helper for dominance computation to find the start nodes block set.
865
+ // fgDomFindStartBlocks : Helper for dominance computation to find the start block set.
848
866
//
849
- // The start nodes is a set that represents which basic blocks in the flow graph don't have incoming edges.
867
+ // The start block set represents basic blocks in the flow graph that do not have incoming edges.
850
868
// We begin assuming everything is a start block and remove any block that is a successor of another.
851
869
//
852
870
// Returns:
853
- // Block set of start nodes .
871
+ // Block set describing the start blocks .
854
872
//
855
- BlockSet_ValRet_T Compiler::fgDomFindStartNodes ()
873
+ BlockSet_ValRet_T Compiler::fgDomFindStartBlocks ()
856
874
{
857
875
BlockSet startNodes (BlockSetOps::MakeFull (this ));
858
876
0 commit comments