@@ -1209,9 +1209,17 @@ static bool isReachable(SILBasicBlock *Block) {
1209
1209
}
1210
1210
#endif
1211
1211
1212
+ static llvm::cl::opt<bool > SimplifyUnconditionalBranches (
1213
+ " simplify-cfg-simplify-unconditional-branches" , llvm::cl::init(true ));
1214
+
1212
1215
// / simplifyBranchBlock - Simplify a basic block that ends with an unconditional
1213
1216
// / branch.
1214
1217
bool SimplifyCFG::simplifyBranchBlock (BranchInst *BI) {
1218
+ // If we are asked to not simplify unconditional branches (for testing
1219
+ // purposes), exit early.
1220
+ if (!SimplifyUnconditionalBranches)
1221
+ return false ;
1222
+
1215
1223
// First simplify instructions generating branch operands since that
1216
1224
// can expose CFG simplifications.
1217
1225
bool Simplified = simplifyBranchOperands (BI->getArgs ());
@@ -1872,43 +1880,88 @@ static bool onlyForwardsNone(SILBasicBlock *noneBB, SILBasicBlock *someBB,
1872
1880
return true ;
1873
1881
}
1874
1882
1875
- // / Check whether \p noneBB has the same ultimate successor as the successor to someBB.
1876
- // / someBB noneBB
1877
- // / \ |
1878
- // / \ ... (more bbs?)
1883
+ // / Check whether the \p someBB has only one single successor and that successor
1884
+ // / post-dominates \p noneBB.
1885
+ // /
1886
+ // / (maybe otherNoneBB)
1887
+ // / someBB noneBB /
1888
+ // / \ | v
1889
+ // / \ ... more bbs? (A)
1879
1890
// / \ /
1880
1891
// / ulimateBB
1892
+ // /
1893
+ // / This routine does not support diverging control flow in (A). This means that
1894
+ // / there must not be any loops or diamonds beginning in that region. We do
1895
+ // / support side-entrances from blocks not reachable from noneBB in order to
1896
+ // / ensure that we properly handle other failure cases where the failure case
1897
+ // / merges into .noneBB before ultimate BB.
1898
+ // /
1899
+ // / DISCUSSION: We allow this side-entrance pattern to handle iterative
1900
+ // / conditional checks which all feed the failing case through the .none
1901
+ // / path. This is a common pattern in swift code. As an example consider a
1902
+ // / switch statement with multiple pattern binding matching that use the same
1903
+ // / cleanup code upon failure.
1881
1904
static bool hasSameUltimateSuccessor (SILBasicBlock *noneBB, SILBasicBlock *someBB) {
1882
1905
// Make sure that both our some, none blocks both have single successors that
1883
1906
// are not themselves (which can happen due to single block loops).
1884
1907
auto *someSuccessorBB = someBB->getSingleSuccessorBlock ();
1885
1908
if (!someSuccessorBB || someSuccessorBB == someBB)
1886
1909
return false ;
1910
+
1887
1911
auto *noneSuccessorBB = noneBB->getSingleSuccessorBlock ();
1888
1912
if (!noneSuccessorBB || noneSuccessorBB == noneBB)
1889
1913
return false ;
1890
1914
1891
- // If we immediately find a diamond, return true. We are done.
1915
+ // If we immediately find a simple diamond, return true. We are done.
1892
1916
if (noneSuccessorBB == someSuccessorBB)
1893
1917
return true ;
1894
1918
1895
- // Otherwise, lets keep looking down the none case.
1896
- auto *next = noneSuccessorBB;
1897
- while (next != someSuccessorBB) {
1898
- noneSuccessorBB = next;
1899
- next = noneSuccessorBB->getSingleSuccessorBlock ();
1919
+ // Otherwise, lets begin a traversal along the successors of noneSuccessorBB,
1920
+ // searching for someSuccessorBB, being careful to only allow for blocks to be
1921
+ // visited once. This enables us to guarantee that there are not any loops or
1922
+ // any sub-diamonds in the part of the CFG we are traversing. This /does/
1923
+ // allow for side-entrances to the region from blocks not reachable from
1924
+ // noneSuccessorBB. See function level comment above.
1925
+ SILBasicBlock *iter = noneSuccessorBB;
1926
+ SmallPtrSet<SILBasicBlock *, 8 > visitedBlocks;
1927
+ visitedBlocks.insert (iter);
1900
1928
1901
- // If we find another single successor and it is not our own block (due to a
1902
- // self-loop), continue.
1903
- if (next && next != noneSuccessorBB)
1904
- continue ;
1929
+ do {
1930
+ // First try to grab our single successor if we have only one. If we have no
1931
+ // successor or more than one successor, bail and do not optimize.
1932
+ //
1933
+ // DISCUSSION: Trivially, if we do not have a successor, then we have
1934
+ // reached either a return/unreachable and this path will never merge with
1935
+ // the ultimate block. If we have more than one successor, then for our
1936
+ // condition to pass, we must have that both successors eventually join into
1937
+ // someSuccessorBB. But this would imply that either someSuccessorBB has
1938
+ // more than two predecessors and or that we merge the two paths before we
1939
+ // visit someSuccessorBB.
1940
+ auto *succBlock = iter->getSingleSuccessorBlock ();
1941
+ if (!succBlock)
1942
+ return false ;
1905
1943
1906
- // Otherwise, we either have multiple successors or a self-loop. We do not
1907
- // support this, return false.
1908
- return false ;
1909
- }
1944
+ // Then check if our single successor block has been visited already. If so,
1945
+ // we have some sort of loop or have some sort of merge point that is not
1946
+ // the final merge point.
1947
+ //
1948
+ // NOTE: We do not need to worry about someSuccessorBB being in
1949
+ // visitedBlocks since before we begin the loop, we check that
1950
+ // someSuccessorBB != iter and also check that in the do-while condition. So
1951
+ // we can never have visited someSuccessorBB on any previous iteration
1952
+ // meaning that the only time we can have succBlock equal to someSuccessorBB
1953
+ // is on the last iteration before we exit the loop.
1954
+ if (!visitedBlocks.insert (succBlock).second )
1955
+ return false ;
1956
+
1957
+ // Otherwise, set iter to succBlock.
1958
+ iter = succBlock;
1959
+
1960
+ // And then check if this new successor block is someSuccessorBB. If so, we
1961
+ // break and then return true since we have found our target. Otherwise, we
1962
+ // need to visit further successors, so go back around the loop.
1963
+ } while (iter != someSuccessorBB);
1910
1964
1911
- // At this point, we know that next must be someSuccessorBB.
1912
1965
return true ;
1913
1966
}
1914
1967
0 commit comments