@@ -1293,9 +1293,17 @@ static bool isReachable(SILBasicBlock *Block) {
1293
1293
}
1294
1294
#endif
1295
1295
1296
+ static llvm::cl::opt<bool > SimplifyUnconditionalBranches (
1297
+ " simplify-cfg-simplify-unconditional-branches" , llvm::cl::init(true ));
1298
+
1296
1299
// / simplifyBranchBlock - Simplify a basic block that ends with an unconditional
1297
1300
// / branch.
1298
1301
bool SimplifyCFG::simplifyBranchBlock (BranchInst *BI) {
1302
+ // If we are asked to not simplify unconditional branches (for testing
1303
+ // purposes), exit early.
1304
+ if (!SimplifyUnconditionalBranches)
1305
+ return false ;
1306
+
1299
1307
// First simplify instructions generating branch operands since that
1300
1308
// can expose CFG simplifications.
1301
1309
bool Simplified = simplifyBranchOperands (BI->getArgs ());
@@ -1956,43 +1964,88 @@ static bool onlyForwardsNone(SILBasicBlock *noneBB, SILBasicBlock *someBB,
1956
1964
return true ;
1957
1965
}
1958
1966
1959
- // / Check whether \p noneBB has the same ultimate successor as the successor to someBB.
1960
- // / someBB noneBB
1961
- // / \ |
1962
- // / \ ... (more bbs?)
1967
+ // / Check whether the \p someBB has only one single successor and that successor
1968
+ // / post-dominates \p noneBB.
1969
+ // /
1970
+ // / (maybe otherNoneBB)
1971
+ // / someBB noneBB /
1972
+ // / \ | v
1973
+ // / \ ... more bbs? (A)
1963
1974
// / \ /
1964
1975
// / ulimateBB
1976
+ // /
1977
+ // / This routine does not support diverging control flow in (A). This means that
1978
+ // / there must not be any loops or diamonds beginning in that region. We do
1979
+ // / support side-entrances from blocks not reachable from noneBB in order to
1980
+ // / ensure that we properly handle other failure cases where the failure case
1981
+ // / merges into .noneBB before ultimate BB.
1982
+ // /
1983
+ // / DISCUSSION: We allow this side-entrance pattern to handle iterative
1984
+ // / conditional checks which all feed the failing case through the .none
1985
+ // / path. This is a common pattern in swift code. As an example consider a
1986
+ // / switch statement with multiple pattern binding matching that use the same
1987
+ // / cleanup code upon failure.
1965
1988
static bool hasSameUltimateSuccessor (SILBasicBlock *noneBB, SILBasicBlock *someBB) {
1966
1989
// Make sure that both our some, none blocks both have single successors that
1967
1990
// are not themselves (which can happen due to single block loops).
1968
1991
auto *someSuccessorBB = someBB->getSingleSuccessorBlock ();
1969
1992
if (!someSuccessorBB || someSuccessorBB == someBB)
1970
1993
return false ;
1994
+
1971
1995
auto *noneSuccessorBB = noneBB->getSingleSuccessorBlock ();
1972
1996
if (!noneSuccessorBB || noneSuccessorBB == noneBB)
1973
1997
return false ;
1974
1998
1975
- // If we immediately find a diamond, return true. We are done.
1999
+ // If we immediately find a simple diamond, return true. We are done.
1976
2000
if (noneSuccessorBB == someSuccessorBB)
1977
2001
return true ;
1978
2002
1979
- // Otherwise, lets keep looking down the none case.
1980
- auto *next = noneSuccessorBB;
1981
- while (next != someSuccessorBB) {
1982
- noneSuccessorBB = next;
1983
- next = noneSuccessorBB->getSingleSuccessorBlock ();
2003
+ // Otherwise, lets begin a traversal along the successors of noneSuccessorBB,
2004
+ // searching for someSuccessorBB, being careful to only allow for blocks to be
2005
+ // visited once. This enables us to guarantee that there are not any loops or
2006
+ // any sub-diamonds in the part of the CFG we are traversing. This /does/
2007
+ // allow for side-entrances to the region from blocks not reachable from
2008
+ // noneSuccessorBB. See function level comment above.
2009
+ SILBasicBlock *iter = noneSuccessorBB;
2010
+ SmallPtrSet<SILBasicBlock *, 8 > visitedBlocks;
2011
+ visitedBlocks.insert (iter);
1984
2012
1985
- // If we find another single successor and it is not our own block (due to a
1986
- // self-loop), continue.
1987
- if (next && next != noneSuccessorBB)
1988
- continue ;
2013
+ do {
2014
+ // First try to grab our single successor if we have only one. If we have no
2015
+ // successor or more than one successor, bail and do not optimize.
2016
+ //
2017
+ // DISCUSSION: Trivially, if we do not have a successor, then we have
2018
+ // reached either a return/unreachable and this path will never merge with
2019
+ // the ultimate block. If we have more than one successor, then for our
2020
+ // condition to pass, we must have that both successors eventually join into
2021
+ // someSuccessorBB. But this would imply that either someSuccessorBB has
2022
+ // more than two predecessors and or that we merge the two paths before we
2023
+ // visit someSuccessorBB.
2024
+ auto *succBlock = iter->getSingleSuccessorBlock ();
2025
+ if (!succBlock)
2026
+ return false ;
1989
2027
1990
- // Otherwise, we either have multiple successors or a self-loop. We do not
1991
- // support this, return false.
1992
- return false ;
1993
- }
2028
+ // Then check if our single successor block has been visited already. If so,
2029
+ // we have some sort of loop or have some sort of merge point that is not
2030
+ // the final merge point.
2031
+ //
2032
+ // NOTE: We do not need to worry about someSuccessorBB being in
2033
+ // visitedBlocks since before we begin the loop, we check that
2034
+ // someSuccessorBB != iter and also check that in the do-while condition. So
2035
+ // we can never have visited someSuccessorBB on any previous iteration
2036
+ // meaning that the only time we can have succBlock equal to someSuccessorBB
2037
+ // is on the last iteration before we exit the loop.
2038
+ if (!visitedBlocks.insert (succBlock).second )
2039
+ return false ;
2040
+
2041
+ // Otherwise, set iter to succBlock.
2042
+ iter = succBlock;
2043
+
2044
+ // And then check if this new successor block is someSuccessorBB. If so, we
2045
+ // break and then return true since we have found our target. Otherwise, we
2046
+ // need to visit further successors, so go back around the loop.
2047
+ } while (iter != someSuccessorBB);
1994
2048
1995
- // At this point, we know that next must be someSuccessorBB.
1996
2049
return true ;
1997
2050
}
1998
2051
0 commit comments