@@ -314,21 +314,27 @@ class PredBlockList
314
314
//
315
315
class BBArrayIterator
316
316
{
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;
318
326
319
327
public:
320
- BBArrayIterator (BasicBlock* const * bbEntry) : m_bbEntry(bbEntry)
328
+ BBArrayIterator (BasicBlock* const * bbEntry) : m_bbEntry(bbEntry), iterateEdges( false )
321
329
{
322
330
}
323
331
324
- BasicBlock* operator *() const
332
+ BBArrayIterator (FlowEdge* const * edgeEntry) : m_edgeEntry(edgeEntry), iterateEdges( true )
325
333
{
326
- assert (m_bbEntry != nullptr );
327
- BasicBlock* bTarget = *m_bbEntry;
328
- assert (bTarget != nullptr );
329
- return bTarget;
330
334
}
331
335
336
+ BasicBlock* operator *() const ;
337
+
332
338
BBArrayIterator& operator ++()
333
339
{
334
340
assert (m_bbEntry != nullptr );
@@ -1570,9 +1576,22 @@ struct BasicBlock : private LIR::Range
1570
1576
// need to call a function or execute another `switch` to get them. Also, pre-compute the begin and end
1571
1577
// points of the iteration, for use by BBArrayIterator. `m_begin` and `m_end` will either point at
1572
1578
// `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;
1576
1595
1577
1596
public:
1578
1597
BBSuccList (const BasicBlock* block);
@@ -1879,8 +1898,8 @@ inline BBArrayIterator BBSwitchTargetList::end() const
1879
1898
//
1880
1899
struct BBehfDesc
1881
1900
{
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
1884
1903
1885
1904
BBehfDesc () : bbeSuccs(nullptr ), bbeCount(0 )
1886
1905
{
@@ -1913,6 +1932,8 @@ inline BBArrayIterator BBEhfSuccList::end() const
1913
1932
inline BasicBlock::BBSuccList::BBSuccList (const BasicBlock* block)
1914
1933
{
1915
1934
assert (block != nullptr );
1935
+ iterateEdges = false ;
1936
+
1916
1937
switch (block->bbKind )
1917
1938
{
1918
1939
case BBJ_THROW:
@@ -1957,14 +1978,16 @@ inline BasicBlock::BBSuccList::BBSuccList(const BasicBlock* block)
1957
1978
// been computed.
1958
1979
if (block->GetEhfTargets () == nullptr )
1959
1980
{
1960
- m_begin = nullptr ;
1961
- m_end = nullptr ;
1981
+ m_beginEdge = nullptr ;
1982
+ m_endEdge = nullptr ;
1962
1983
}
1963
1984
else
1964
1985
{
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 ;
1967
1988
}
1989
+
1990
+ iterateEdges = true ;
1968
1991
break ;
1969
1992
1970
1993
case BBJ_SWITCH:
@@ -1984,12 +2007,12 @@ inline BasicBlock::BBSuccList::BBSuccList(const BasicBlock* block)
1984
2007
1985
2008
inline BBArrayIterator BasicBlock::BBSuccList::begin () const
1986
2009
{
1987
- return BBArrayIterator (m_begin);
2010
+ return (iterateEdges ? BBArrayIterator (m_beginEdge) : BBArrayIterator ( m_begin) );
1988
2011
}
1989
2012
1990
2013
inline BBArrayIterator BasicBlock::BBSuccList::end () const
1991
2014
{
1992
- return BBArrayIterator (m_end);
2015
+ return (iterateEdges ? BBArrayIterator (m_endEdge) : BBArrayIterator ( m_end) );
1993
2016
}
1994
2017
1995
2018
// We have a simpler struct, BasicBlockList, which is simply a singly-linked
@@ -2192,6 +2215,25 @@ struct FlowEdge
2192
2215
}
2193
2216
};
2194
2217
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
+
2195
2237
// Pred list iterator implementations (that are required to be defined after the declaration of BasicBlock and FlowEdge)
2196
2238
2197
2239
inline PredEdgeList::iterator::iterator (FlowEdge* pred) : m_pred(pred)
0 commit comments