From: Dan Gohman Date: Fri, 8 May 2009 20:47:27 +0000 (+0000) Subject: Add memoization for getSCEVAtScope results for instructions X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6bce643c36e7263aada5058f08cd242b4ce6b87d;p=oota-llvm.git Add memoization for getSCEVAtScope results for instructions which are not analyzed with SCEV techniques, which can require brute-forcing through a large number of instructions. This fixes a massive compile-time issue on 400.perlbench (in particular, the loop in MD5Transform). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71259 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index d6fb8f011b8..c9a80b74a2d 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -271,6 +271,11 @@ namespace llvm { /// exit value. std::map ConstantEvolutionLoopExitValue; + /// ValuesAtScopes - This map contains entries for all the instructions + /// that we attempt to compute getSCEVAtScope information for without + /// using SCEV techniques, which can be expensive. + std::map > ValuesAtScopes; + /// createSCEV - We know that there is no SCEV for the specified value. /// Analyze the expression. SCEVHandle createSCEV(Value *V); diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 8b48b78da41..4ddde5db5ed 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -2766,6 +2766,13 @@ SCEVHandle ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) { // the arguments into constants, and if so, try to constant propagate the // result. This is particularly useful for computing loop exit values. if (CanConstantFold(I)) { + // Check to see if we've folded this instruction at this loop before. + std::map &Values = ValuesAtScopes[I]; + std::pair::iterator, bool> Pair = + Values.insert(std::make_pair(L, static_cast(0))); + if (!Pair.second) + return Pair.first->second ? &*getUnknown(Pair.first->second) : V; + std::vector Operands; Operands.reserve(I->getNumOperands()); for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { @@ -2812,6 +2819,7 @@ SCEVHandle ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) { else C = ConstantFoldInstOperands(I->getOpcode(), I->getType(), &Operands[0], Operands.size()); + Pair.first->second = C; return getUnknown(C); } } @@ -3473,6 +3481,8 @@ void SCEVCallbackVH::deleted() { assert(SE && "SCEVCallbackVH called with a non-null ScalarEvolution!"); if (PHINode *PN = dyn_cast(getValPtr())) SE->ConstantEvolutionLoopExitValue.erase(PN); + if (Instruction *I = dyn_cast(getValPtr())) + SE->ValuesAtScopes.erase(I); SE->Scalars.erase(getValPtr()); // this now dangles! } @@ -3499,6 +3509,8 @@ void SCEVCallbackVH::allUsesReplacedWith(Value *) { } if (PHINode *PN = dyn_cast(U)) SE->ConstantEvolutionLoopExitValue.erase(PN); + if (Instruction *I = dyn_cast(U)) + SE->ValuesAtScopes.erase(I); if (SE->Scalars.erase(U)) for (Value::use_iterator UI = U->use_begin(), UE = U->use_end(); UI != UE; ++UI) @@ -3507,6 +3519,8 @@ void SCEVCallbackVH::allUsesReplacedWith(Value *) { if (DeleteOld) { if (PHINode *PN = dyn_cast(Old)) SE->ConstantEvolutionLoopExitValue.erase(PN); + if (Instruction *I = dyn_cast(Old)) + SE->ValuesAtScopes.erase(I); SE->Scalars.erase(Old); // this now dangles! } @@ -3535,6 +3549,7 @@ void ScalarEvolution::releaseMemory() { Scalars.clear(); BackedgeTakenCounts.clear(); ConstantEvolutionLoopExitValue.clear(); + ValuesAtScopes.clear(); } void ScalarEvolution::getAnalysisUsage(AnalysisUsage &AU) const {