@@ -314,21 +314,27 @@ class PredBlockList
314314//
315315class BBArrayIterator
316316{
317- BasicBlock* const * m_bbEntry;
317+ // Quirk: Some BasicBlock kinds refer to their successors with BasicBlock pointers,
318+ // while others use FlowEdge pointers. Eventually, every type will use FlowEdge pointers.
319+ // For now, support iterating with both types.
320+ union {
321+ BasicBlock* const * m_bbEntry;
322+ FlowEdge* const * m_edgeEntry;
323+ };
324+
325+ bool iterateEdges;
318326
319327public:
320- BBArrayIterator (BasicBlock* const * bbEntry) : m_bbEntry(bbEntry)
328+ BBArrayIterator (BasicBlock* const * bbEntry) : m_bbEntry(bbEntry), iterateEdges( false )
321329 {
322330 }
323331
324- BasicBlock* operator *() const
332+ BBArrayIterator (FlowEdge* const * edgeEntry) : m_edgeEntry(edgeEntry), iterateEdges( true )
325333 {
326- assert (m_bbEntry != nullptr );
327- BasicBlock* bTarget = *m_bbEntry;
328- assert (bTarget != nullptr );
329- return bTarget;
330334 }
331335
336+ BasicBlock* operator *() const ;
337+
332338 BBArrayIterator& operator ++()
333339 {
334340 assert (m_bbEntry != nullptr );
@@ -1570,9 +1576,22 @@ struct BasicBlock : private LIR::Range
15701576 // need to call a function or execute another `switch` to get them. Also, pre-compute the begin and end
15711577 // points of the iteration, for use by BBArrayIterator. `m_begin` and `m_end` will either point at
15721578 // `m_succs` or at the switch table successor array.
1573- BasicBlock* m_succs[2 ];
1574- BasicBlock* const * m_begin;
1575- BasicBlock* const * m_end;
1579+ BasicBlock* m_succs[2 ];
1580+
1581+ // Quirk: Some BasicBlock kinds refer to their successors with BasicBlock pointers,
1582+ // while others use FlowEdge pointers. Eventually, every type will use FlowEdge pointers.
1583+ // For now, support iterating with both types.
1584+ union {
1585+ BasicBlock* const * m_begin;
1586+ FlowEdge* const * m_beginEdge;
1587+ };
1588+
1589+ union {
1590+ BasicBlock* const * m_end;
1591+ FlowEdge* const * m_endEdge;
1592+ };
1593+
1594+ bool iterateEdges;
15761595
15771596 public:
15781597 BBSuccList (const BasicBlock* block);
@@ -1879,8 +1898,8 @@ inline BBArrayIterator BBSwitchTargetList::end() const
18791898//
18801899struct BBehfDesc
18811900{
1882- BasicBlock ** bbeSuccs; // array of `BasicBlock *` pointing to BBJ_EHFINALLYRET block successors
1883- unsigned bbeCount; // size of `bbeSuccs` array
1901+ FlowEdge ** bbeSuccs; // array of `FlowEdge *` pointing to BBJ_EHFINALLYRET block successors
1902+ unsigned bbeCount; // size of `bbeSuccs` array
18841903
18851904 BBehfDesc () : bbeSuccs(nullptr ), bbeCount(0 )
18861905 {
@@ -1913,6 +1932,8 @@ inline BBArrayIterator BBEhfSuccList::end() const
19131932inline BasicBlock::BBSuccList::BBSuccList (const BasicBlock* block)
19141933{
19151934 assert (block != nullptr );
1935+ iterateEdges = false ;
1936+
19161937 switch (block->bbKind )
19171938 {
19181939 case BBJ_THROW:
@@ -1957,14 +1978,16 @@ inline BasicBlock::BBSuccList::BBSuccList(const BasicBlock* block)
19571978 // been computed.
19581979 if (block->GetEhfTargets () == nullptr )
19591980 {
1960- m_begin = nullptr ;
1961- m_end = nullptr ;
1981+ m_beginEdge = nullptr ;
1982+ m_endEdge = nullptr ;
19621983 }
19631984 else
19641985 {
1965- m_begin = block->GetEhfTargets ()->bbeSuccs ;
1966- m_end = block->GetEhfTargets ()->bbeSuccs + block->GetEhfTargets ()->bbeCount ;
1986+ m_beginEdge = block->GetEhfTargets ()->bbeSuccs ;
1987+ m_endEdge = block->GetEhfTargets ()->bbeSuccs + block->GetEhfTargets ()->bbeCount ;
19671988 }
1989+
1990+ iterateEdges = true ;
19681991 break ;
19691992
19701993 case BBJ_SWITCH:
@@ -1984,12 +2007,12 @@ inline BasicBlock::BBSuccList::BBSuccList(const BasicBlock* block)
19842007
19852008inline BBArrayIterator BasicBlock::BBSuccList::begin () const
19862009{
1987- return BBArrayIterator (m_begin);
2010+ return (iterateEdges ? BBArrayIterator (m_beginEdge) : BBArrayIterator ( m_begin) );
19882011}
19892012
19902013inline BBArrayIterator BasicBlock::BBSuccList::end () const
19912014{
1992- return BBArrayIterator (m_end);
2015+ return (iterateEdges ? BBArrayIterator (m_endEdge) : BBArrayIterator ( m_end) );
19932016}
19942017
19952018// We have a simpler struct, BasicBlockList, which is simply a singly-linked
@@ -2192,6 +2215,25 @@ struct FlowEdge
21922215 }
21932216};
21942217
2218+ // BasicBlock iterator implementations (that are required to be defined after the declaration of FlowEdge)
2219+
2220+ inline BasicBlock* BBArrayIterator::operator *() const
2221+ {
2222+ if (iterateEdges)
2223+ {
2224+ assert (m_edgeEntry != nullptr );
2225+ FlowEdge* edgeTarget = *m_edgeEntry;
2226+ assert (edgeTarget != nullptr );
2227+ assert (edgeTarget->getDestinationBlock () != nullptr );
2228+ return edgeTarget->getDestinationBlock ();
2229+ }
2230+
2231+ assert (m_bbEntry != nullptr );
2232+ BasicBlock* bTarget = *m_bbEntry;
2233+ assert (bTarget != nullptr );
2234+ return bTarget;
2235+ }
2236+
21952237// Pred list iterator implementations (that are required to be defined after the declaration of BasicBlock and FlowEdge)
21962238
21972239inline PredEdgeList::iterator::iterator (FlowEdge* pred) : m_pred(pred)
0 commit comments