@@ -707,11 +707,24 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
707707 fprintf (fgxFile, " >" );
708708 }
709709
710+ // In some cases, we want to change the display based on whether an edge is lexically backwards, forwards,
711+ // or lexical successor. Also, for the region tree, using the lexical order is useful for determining where
712+ // to insert in the tree, to determine nesting. We'd like to use the bbNum to do this. However, we don't
713+ // want to renumber the blocks. So, create a mapping of bbNum to ordinal, and compare block order by
714+ // comparing the mapped ordinals instead.
715+
716+ unsigned blockOrdinal = 0 ;
717+ unsigned * blkMap = new (this , CMK_DebugOnly) unsigned [fgBBNumMax + 1 ];
718+ memset (blkMap, 0 , sizeof (unsigned ) * (fgBBNumMax + 1 ));
719+ for (BasicBlock* block = fgFirstBB; block != nullptr ; block = block->bbNext )
720+ {
721+ blkMap[block->bbNum ] = blockOrdinal++;
722+ }
723+
710724 static const char * kindImage[] = {" EHFINALLYRET" , " EHFILTERRET" , " EHCATCHRET" , " THROW" , " RETURN" , " NONE" ,
711725 " ALWAYS" , " LEAVE" , " CALLFINALLY" , " COND" , " SWITCH" };
712726
713727 BasicBlock* block;
714- unsigned blockOrdinal;
715728 for (block = fgFirstBB, blockOrdinal = 1 ; block != nullptr ; block = block->bbNext , blockOrdinal++)
716729 {
717730 if (createDotFile)
@@ -840,13 +853,13 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
840853
841854 const char * sep = " " ;
842855
843- if (bSource->bbNum > bTarget->bbNum )
856+ if (blkMap[ bSource->bbNum ] > blkMap[ bTarget->bbNum ] )
844857 {
845858 // Lexical backedge
846859 fprintf (fgxFile, " [color=green" );
847860 sep = " , " ;
848861 }
849- else if ((bSource->bbNum + 1 ) == bTarget->bbNum )
862+ else if ((blkMap[ bSource->bbNum ] + 1 ) == blkMap[ bTarget->bbNum ] )
850863 {
851864 // Lexical successor
852865 fprintf (fgxFile, " [color=blue, weight=20" );
@@ -953,12 +966,12 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
953966 {
954967 BasicBlock* const bTarget = bSource->GetSucc (i);
955968 fprintf (fgxFile, " " FMT_BB " -> " FMT_BB, bSource->bbNum , bTarget->bbNum );
956- if (bSource->bbNum > bTarget->bbNum )
969+ if (blkMap[ bSource->bbNum ] > blkMap[ bTarget->bbNum ] )
957970 {
958971 // Lexical backedge
959972 fprintf (fgxFile, " [color=green]\n " );
960973 }
961- else if ((bSource->bbNum + 1 ) == bTarget->bbNum )
974+ else if ((blkMap[ bSource->bbNum ] + 1 ) == blkMap[ bTarget->bbNum ] )
962975 {
963976 // Lexical successor
964977 fprintf (fgxFile, " [color=blue]\n " );
@@ -1027,24 +1040,11 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
10271040 };
10281041
10291042 public:
1030- RegionGraph (Compiler* comp) : m_comp(comp), m_rgnRoot(nullptr )
1043+ RegionGraph (Compiler* comp, unsigned * blkMap ) : m_comp(comp), m_rgnRoot(nullptr ), m_blkMap(blkMap )
10311044 {
10321045 // Create a root region that encompasses the whole function.
1033- // We don't want to renumber the blocks, but it's useful to have a sequential number
1034- // representing the lexical block order so we know where to insert a block range
1035- // in the region tree. To do this, create a mapping of bbNum to ordinal, and compare
1036- // block order by comparing the mapped ordinals.
1037-
10381046 m_rgnRoot =
10391047 new (m_comp, CMK_DebugOnly) Region (RegionType::Root, " Root" , comp->fgFirstBB , comp->fgLastBB );
1040-
1041- unsigned bbOrdinal = 0 ;
1042- m_blkMap = new (m_comp, CMK_DebugOnly) unsigned [comp->fgBBNumMax + 1 ];
1043- memset (m_blkMap, 0 , sizeof (unsigned ) * (comp->fgBBNumMax + 1 ));
1044- for (BasicBlock* block = comp->fgFirstBB ; block != nullptr ; block = block->bbNext )
1045- {
1046- m_blkMap[block->bbNum ] = bbOrdinal++;
1047- }
10481048 }
10491049
10501050 // ------------------------------------------------------------------------
@@ -1353,7 +1353,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
13531353
13541354 // Define the region graph object. We'll add regions to this, then output the graph.
13551355
1356- RegionGraph rgnGraph (this );
1356+ RegionGraph rgnGraph (this , blkMap );
13571357
13581358 // Add the EH regions to the region graph. An EH region consists of a region for the
13591359 // `try`, a region for the handler, and, for filter/filter-handlers, a region for the
@@ -2071,7 +2071,7 @@ class BBPredsChecker
20712071 bool CheckEhTryDsc (BasicBlock* block, BasicBlock* blockPred, EHblkDsc* ehTryDsc);
20722072 bool CheckEhHndDsc (BasicBlock* block, BasicBlock* blockPred, EHblkDsc* ehHndlDsc);
20732073 bool CheckJump (BasicBlock* blockPred, BasicBlock* block);
2074- bool CheckEHFinalyRet (BasicBlock* blockPred, BasicBlock* block);
2074+ bool CheckEHFinallyRet (BasicBlock* blockPred, BasicBlock* block);
20752075
20762076private:
20772077 Compiler* comp;
@@ -2130,7 +2130,7 @@ unsigned BBPredsChecker::CheckBBPreds(BasicBlock* block, unsigned curTraversalSt
21302130 assert (CheckJump (blockPred, block));
21312131 }
21322132
2133- // Make sure preds are in increasting BBnum order
2133+ // Make sure preds are in increasing BBnum order
21342134 //
21352135 assert (block->checkPredListOrder ());
21362136
@@ -2232,7 +2232,7 @@ bool BBPredsChecker::CheckJump(BasicBlock* blockPred, BasicBlock* block)
22322232 return true ;
22332233
22342234 case BBJ_EHFINALLYRET:
2235- assert (CheckEHFinalyRet (blockPred, block));
2235+ assert (CheckEHFinallyRet (blockPred, block));
22362236 return true ;
22372237
22382238 case BBJ_THROW:
@@ -2265,9 +2265,8 @@ bool BBPredsChecker::CheckJump(BasicBlock* blockPred, BasicBlock* block)
22652265 return false ;
22662266}
22672267
2268- bool BBPredsChecker::CheckEHFinalyRet (BasicBlock* blockPred, BasicBlock* block)
2268+ bool BBPredsChecker::CheckEHFinallyRet (BasicBlock* blockPred, BasicBlock* block)
22692269{
2270-
22712270 // If the current block is a successor to a BBJ_EHFINALLYRET (return from finally),
22722271 // then the lexically previous block should be a call to the same finally.
22732272 // Verify all of that.
0 commit comments