diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 29 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 7 | 
2 files changed, 36 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 82200cd0281..c2284a8ab9b 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -3485,6 +3485,35 @@ void ScalarEvolution::forgetLoop(const Loop *L) {    }  } +/// forgetValue - This method should be called by the client when it has +/// changed a value in a way that may effect its value, or which may +/// disconnect it from a def-use chain linking it to a loop. +void ScalarEvolution::forgetValue(Value *V) { +  Instruction *I = dyn_cast<Instruction>(V); +  if (!I) return; + +  // Drop information about expressions based on loop-header PHIs. +  SmallVector<Instruction *, 16> Worklist; +  Worklist.push_back(I); + +  SmallPtrSet<Instruction *, 8> Visited; +  while (!Worklist.empty()) { +    I = Worklist.pop_back_val(); +    if (!Visited.insert(I)) continue; + +    std::map<SCEVCallbackVH, const SCEV *>::iterator It = +      Scalars.find(static_cast<Value *>(I)); +    if (It != Scalars.end()) { +      ValuesAtScopes.erase(It->second); +      Scalars.erase(It); +      if (PHINode *PN = dyn_cast<PHINode>(I)) +        ConstantEvolutionLoopExitValue.erase(PN); +    } + +    PushDefUseChildren(I, Worklist); +  } +} +  /// ComputeBackedgeTakenCount - Compute the number of times the backedge  /// of the specified loop will execute.  ScalarEvolution::BackedgeTakenInfo diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index e699261b277..60492b02836 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -246,6 +246,13 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L,        if (!PN->getType()->isIntegerTy() && !PN->getType()->isPointerTy())          continue; +      // It's necessary to tell ScalarEvolution about this explicitly so that +      // it can walk the def-use list and forget all SCEVs, as it may not be +      // watching the PHI itself. Once the new exit value is in place, there +      // may not be a def-use connection between the loop and every instruction +      // which got a SCEVAddRecExpr for that loop. +      SE->forgetValue(PN); +        // Iterate over all of the values in all the PHI nodes.        for (unsigned i = 0; i != NumPreds; ++i) {          // If the value being merged in is not integer or is not defined  | 

