@@ -864,6 +864,10 @@ static void reportBoundsChecks(SILFunction *F) {
864
864
#endif
865
865
866
866
namespace {
867
+
868
+ // Should be more than enough to cover "usual" functions.
869
+ static constexpr int maxRecursionDepth = 500 ;
870
+
867
871
// / Remove redundant checks in basic blocks and hoist redundant checks out of
868
872
// / loops.
869
873
class ABCOpt : public SILFunctionTransform {
@@ -885,13 +889,15 @@ class ABCOpt : public SILFunctionTransform {
885
889
// / Walk down the dominator tree inside the loop, removing redundant checks.
886
890
bool removeRedundantChecksInLoop (DominanceInfoNode *CurBB, ABCAnalysis &ABC,
887
891
IndexedArraySet &DominatingSafeChecks,
888
- SILLoop *Loop);
892
+ SILLoop *Loop,
893
+ int recursionDepth);
889
894
// / Analyze the loop for arrays that are not modified and perform dominator
890
895
// / tree based redundant bounds check removal.
891
896
bool hoistChecksInLoop (DominanceInfoNode *DTNode, ABCAnalysis &ABC,
892
897
InductionAnalysis &IndVars, SILBasicBlock *Preheader,
893
898
SILBasicBlock *Header,
894
- SILBasicBlock *SingleExitingBlk);
899
+ SILBasicBlock *SingleExitingBlk,
900
+ int recursionDepth);
895
901
896
902
public:
897
903
void run () override {
@@ -1049,10 +1055,16 @@ bool ABCOpt::removeRedundantChecksInBlock(SILBasicBlock &BB) {
1049
1055
bool ABCOpt::removeRedundantChecksInLoop (DominanceInfoNode *CurBB,
1050
1056
ABCAnalysis &ABC,
1051
1057
IndexedArraySet &DominatingSafeChecks,
1052
- SILLoop *Loop) {
1058
+ SILLoop *Loop,
1059
+ int recursionDepth) {
1053
1060
auto *BB = CurBB->getBlock ();
1054
1061
if (!Loop->contains (BB))
1055
1062
return false ;
1063
+
1064
+ // Avoid a stack overflow for very deep dominator trees.
1065
+ if (recursionDepth >= maxRecursionDepth)
1066
+ return false ;
1067
+
1056
1068
bool Changed = false ;
1057
1069
1058
1070
// When we come back from the dominator tree recursion we need to remove
@@ -1106,7 +1118,8 @@ bool ABCOpt::removeRedundantChecksInLoop(DominanceInfoNode *CurBB,
1106
1118
// Traverse the children in the dominator tree inside the loop.
1107
1119
for (auto Child : *CurBB)
1108
1120
Changed |=
1109
- removeRedundantChecksInLoop (Child, ABC, DominatingSafeChecks, Loop);
1121
+ removeRedundantChecksInLoop (Child, ABC, DominatingSafeChecks, Loop,
1122
+ recursionDepth + 1 );
1110
1123
1111
1124
// Remove checks we have seen for the first time.
1112
1125
std::for_each (SafeChecksToPop.begin (), SafeChecksToPop.end (),
@@ -1149,7 +1162,8 @@ bool ABCOpt::processLoop(SILLoop *Loop) {
1149
1162
// check for safety outside the loop (with ABCAnalysis).
1150
1163
IndexedArraySet DominatingSafeChecks;
1151
1164
bool Changed = removeRedundantChecksInLoop (DT->getNode (Header), ABC,
1152
- DominatingSafeChecks, Loop);
1165
+ DominatingSafeChecks, Loop,
1166
+ /* recursionDepth*/ 0 );
1153
1167
1154
1168
if (!EnableABCHoisting)
1155
1169
return Changed;
@@ -1255,7 +1269,7 @@ bool ABCOpt::processLoop(SILLoop *Loop) {
1255
1269
1256
1270
// Hoist bounds checks.
1257
1271
Changed |= hoistChecksInLoop (DT->getNode (Header), ABC, IndVars, Preheader,
1258
- Header, SingleExitingBlk);
1272
+ Header, SingleExitingBlk, /* recursionDepth */ 0 );
1259
1273
if (Changed) {
1260
1274
Preheader->getParent ()->verify ();
1261
1275
}
@@ -1265,7 +1279,12 @@ bool ABCOpt::processLoop(SILLoop *Loop) {
1265
1279
bool ABCOpt::hoistChecksInLoop (DominanceInfoNode *DTNode, ABCAnalysis &ABC,
1266
1280
InductionAnalysis &IndVars,
1267
1281
SILBasicBlock *Preheader, SILBasicBlock *Header,
1268
- SILBasicBlock *SingleExitingBlk) {
1282
+ SILBasicBlock *SingleExitingBlk,
1283
+ int recursionDepth) {
1284
+ // Avoid a stack overflow for very deep dominator trees.
1285
+ if (recursionDepth >= maxRecursionDepth)
1286
+ return false ;
1287
+
1269
1288
bool Changed = false ;
1270
1289
auto *CurBB = DTNode->getBlock ();
1271
1290
bool blockAlwaysExecutes =
@@ -1364,7 +1383,7 @@ bool ABCOpt::hoistChecksInLoop(DominanceInfoNode *DTNode, ABCAnalysis &ABC,
1364
1383
// Traverse the children in the dominator tree.
1365
1384
for (auto Child : *DTNode)
1366
1385
Changed |= hoistChecksInLoop (Child, ABC, IndVars, Preheader, Header,
1367
- SingleExitingBlk);
1386
+ SingleExitingBlk, recursionDepth + 1 );
1368
1387
1369
1388
return Changed;
1370
1389
}
0 commit comments