@@ -870,6 +870,10 @@ static void reportBoundsChecks(SILFunction *F) {
870
870
#endif
871
871
872
872
namespace {
873
+
874
+ // Should be more than enough to cover "usual" functions.
875
+ static constexpr int maxRecursionDepth = 500 ;
876
+
873
877
// / Remove redundant checks in basic blocks and hoist redundant checks out of
874
878
// / loops.
875
879
class ABCOpt : public SILFunctionTransform {
@@ -891,13 +895,15 @@ class ABCOpt : public SILFunctionTransform {
891
895
// / Walk down the dominator tree inside the loop, removing redundant checks.
892
896
bool removeRedundantChecksInLoop (DominanceInfoNode *CurBB, ABCAnalysis &ABC,
893
897
IndexedArraySet &DominatingSafeChecks,
894
- SILLoop *Loop);
898
+ SILLoop *Loop,
899
+ int recursionDepth);
895
900
// / Analyze the loop for arrays that are not modified and perform dominator
896
901
// / tree based redundant bounds check removal.
897
902
bool hoistChecksInLoop (DominanceInfoNode *DTNode, ABCAnalysis &ABC,
898
903
InductionAnalysis &IndVars, SILBasicBlock *Preheader,
899
904
SILBasicBlock *Header,
900
- SILBasicBlock *SingleExitingBlk);
905
+ SILBasicBlock *SingleExitingBlk,
906
+ int recursionDepth);
901
907
902
908
public:
903
909
void run () override {
@@ -1055,10 +1061,16 @@ bool ABCOpt::removeRedundantChecksInBlock(SILBasicBlock &BB) {
1055
1061
bool ABCOpt::removeRedundantChecksInLoop (DominanceInfoNode *CurBB,
1056
1062
ABCAnalysis &ABC,
1057
1063
IndexedArraySet &DominatingSafeChecks,
1058
- SILLoop *Loop) {
1064
+ SILLoop *Loop,
1065
+ int recursionDepth) {
1059
1066
auto *BB = CurBB->getBlock ();
1060
1067
if (!Loop->contains (BB))
1061
1068
return false ;
1069
+
1070
+ // Avoid a stack overflow for very deep dominator trees.
1071
+ if (recursionDepth >= maxRecursionDepth)
1072
+ return false ;
1073
+
1062
1074
bool Changed = false ;
1063
1075
1064
1076
// When we come back from the dominator tree recursion we need to remove
@@ -1112,7 +1124,8 @@ bool ABCOpt::removeRedundantChecksInLoop(DominanceInfoNode *CurBB,
1112
1124
// Traverse the children in the dominator tree inside the loop.
1113
1125
for (auto Child : *CurBB)
1114
1126
Changed |=
1115
- removeRedundantChecksInLoop (Child, ABC, DominatingSafeChecks, Loop);
1127
+ removeRedundantChecksInLoop (Child, ABC, DominatingSafeChecks, Loop,
1128
+ recursionDepth + 1 );
1116
1129
1117
1130
// Remove checks we have seen for the first time.
1118
1131
std::for_each (SafeChecksToPop.begin (), SafeChecksToPop.end (),
@@ -1155,7 +1168,8 @@ bool ABCOpt::processLoop(SILLoop *Loop) {
1155
1168
// check for safety outside the loop (with ABCAnalysis).
1156
1169
IndexedArraySet DominatingSafeChecks;
1157
1170
bool Changed = removeRedundantChecksInLoop (DT->getNode (Header), ABC,
1158
- DominatingSafeChecks, Loop);
1171
+ DominatingSafeChecks, Loop,
1172
+ /* recursionDepth*/ 0 );
1159
1173
1160
1174
if (!EnableABCHoisting)
1161
1175
return Changed;
@@ -1261,7 +1275,7 @@ bool ABCOpt::processLoop(SILLoop *Loop) {
1261
1275
1262
1276
// Hoist bounds checks.
1263
1277
Changed |= hoistChecksInLoop (DT->getNode (Header), ABC, IndVars, Preheader,
1264
- Header, SingleExitingBlk);
1278
+ Header, SingleExitingBlk, /* recursionDepth */ 0 );
1265
1279
if (Changed) {
1266
1280
Preheader->getParent ()->verify ();
1267
1281
}
@@ -1271,7 +1285,12 @@ bool ABCOpt::processLoop(SILLoop *Loop) {
1271
1285
bool ABCOpt::hoistChecksInLoop (DominanceInfoNode *DTNode, ABCAnalysis &ABC,
1272
1286
InductionAnalysis &IndVars,
1273
1287
SILBasicBlock *Preheader, SILBasicBlock *Header,
1274
- SILBasicBlock *SingleExitingBlk) {
1288
+ SILBasicBlock *SingleExitingBlk,
1289
+ int recursionDepth) {
1290
+ // Avoid a stack overflow for very deep dominator trees.
1291
+ if (recursionDepth >= maxRecursionDepth)
1292
+ return false ;
1293
+
1275
1294
bool Changed = false ;
1276
1295
auto *CurBB = DTNode->getBlock ();
1277
1296
bool blockAlwaysExecutes =
@@ -1370,7 +1389,7 @@ bool ABCOpt::hoistChecksInLoop(DominanceInfoNode *DTNode, ABCAnalysis &ABC,
1370
1389
// Traverse the children in the dominator tree.
1371
1390
for (auto Child : *DTNode)
1372
1391
Changed |= hoistChecksInLoop (Child, ABC, IndVars, Preheader, Header,
1373
- SingleExitingBlk);
1392
+ SingleExitingBlk, recursionDepth + 1 );
1374
1393
1375
1394
return Changed;
1376
1395
}
0 commit comments