]> granicus.if.org Git - llvm/commitdiff
[SCEV] Limit recursion depth of constant evolving.
authorMichael Liao <michael.liao@intel.com>
Fri, 13 Jan 2017 18:28:30 +0000 (18:28 +0000)
committerMichael Liao <michael.liao@intel.com>
Fri, 13 Jan 2017 18:28:30 +0000 (18:28 +0000)
- For a loop body with VERY complicated exit condition evaluation, constant
  evolving may run out of stack on platforms such as Windows. Need to limit the
  recursion depth.

Differential Revision: https://reviews.llvm.org/D28629

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291927 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/ScalarEvolution.cpp

index b3905cc01e84b3f9b6a092f1e1bf3fa2d00bc753..81648528cb5eb6c8f3a83bcb769523c57c0c5916 100644 (file)
@@ -132,6 +132,10 @@ static cl::opt<unsigned>
                     cl::desc("Maximum depth of recursive compare complexity"),
                     cl::init(32));
 
+static cl::opt<unsigned> MaxConstantEvolvingDepth(
+    "scalar-evolution-max-constant-evolving-depth", cl::Hidden,
+    cl::desc("Maximum depth of recursive constant evolving"), cl::init(32));
+
 //===----------------------------------------------------------------------===//
 //                           SCEV class definitions
 //===----------------------------------------------------------------------===//
@@ -6403,7 +6407,10 @@ static bool canConstantEvolve(Instruction *I, const Loop *L) {
 /// recursing through each instruction operand until reaching a loop header phi.
 static PHINode *
 getConstantEvolvingPHIOperands(Instruction *UseInst, const Loop *L,
-                               DenseMap<Instruction *, PHINode *> &PHIMap) {
+                               DenseMap<Instruction *, PHINode *> &PHIMap,
+                               unsigned Depth) {
+  if (Depth > MaxConstantEvolvingDepth)
+    return nullptr;
 
   // Otherwise, we can evaluate this instruction if all of its operands are
   // constant or derived from a PHI node themselves.
@@ -6423,7 +6430,7 @@ getConstantEvolvingPHIOperands(Instruction *UseInst, const Loop *L,
     if (!P) {
       // Recurse and memoize the results, whether a phi is found or not.
       // This recursive call invalidates pointers into PHIMap.
-      P = getConstantEvolvingPHIOperands(OpInst, L, PHIMap);
+      P = getConstantEvolvingPHIOperands(OpInst, L, PHIMap, Depth + 1);
       PHIMap[OpInst] = P;
     }
     if (!P)
@@ -6450,7 +6457,7 @@ static PHINode *getConstantEvolvingPHI(Value *V, const Loop *L) {
 
   // Record non-constant instructions contained by the loop.
   DenseMap<Instruction *, PHINode *> PHIMap;
-  return getConstantEvolvingPHIOperands(I, L, PHIMap);
+  return getConstantEvolvingPHIOperands(I, L, PHIMap, 0);
 }
 
 /// EvaluateExpression - Given an expression that passes the