From 3221ad0db784a8c8d6ce3029e2632216764b5533 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 17 Apr 2004 22:58:41 +0000 Subject: [PATCH] Add the ability to compute exit values for complex loop using unanalyzable operations. This allows us to compile this testcase: int main() { int h = 1; do h = 3 * h + 1; while (h <= 256); printf("%d\n", h); return 0; } into this: int %main() { entry: call void %__main( ) %tmp.6 = call int (sbyte*, ...)* %printf( sbyte* getelementptr ([4 x sbyte]* %.str_1, long 0, long 0), int 364 ) ; [#uses=0] ret int 0 } This testcase was taken directly from 256.bzip2, believe it or not. This code is not as general as I would like. Next up is to refactor it a bit to handle more cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13019 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ScalarEvolution.cpp | 285 +++++++++++++++++++++++-------- 1 file changed, 211 insertions(+), 74 deletions(-) diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 2841200b08e..b93deb2d695 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -1136,6 +1136,13 @@ namespace { /// function as they are computed. std::map IterationCounts; + /// ConstantEvolutionLoopExitValue - This map contains entries for all of + /// the PHI instructions that we attempt to compute constant evolutions for. + /// This allows us to avoid potentially expensive recomputation of these + /// properties. An instruction maps to null if we are unable to compute its + /// exit value. + std::map ConstantEvolutionLoopExitValue; + public: ScalarEvolutionsImpl(Function &f, LoopInfo &li) : F(f), LI(li), UnknownValue(new SCEVCouldNotCompute()) {} @@ -1197,6 +1204,13 @@ namespace { /// specified value for nonzero will execute. If not computable, return /// UnknownValue SCEVHandle HowFarToNonZero(SCEV *V, const Loop *L); + + /// getConstantEvolutionLoopExitValue - If we know that the specified Phi is + /// in the header of its containing loop, we know the loop executes a + /// constant number of times, and the PHI node is just a recurrence + /// involving constants, fold it. + Constant *getConstantEvolutionLoopExitValue(PHINode *PN, uint64_t Its, + const Loop *L); }; } @@ -1209,6 +1223,8 @@ namespace { /// that no dangling references are left around. void ScalarEvolutionsImpl::deleteInstructionFromRecords(Instruction *I) { Scalars.erase(I); + if (PHINode *PN = dyn_cast(I)) + ConstantEvolutionLoopExitValue.erase(PN); } @@ -1552,77 +1568,23 @@ SCEVHandle ScalarEvolutionsImpl::ComputeIterationCount(const Loop *L) { ExitBr->getSuccessor(0) == ExitBlock); } - -/// getConstantEvolvingPHI - Given an LLVM value and a loop, return a PHI node -/// in the loop that V is derived from. We allow arbitrary operations along the -/// way, but the operands of an operation must either be constants or a value -/// derived from a constant PHI. If this expression does not fit with these -/// constraints, return null. -static PHINode *getConstantEvolvingPHI(Value *V, const Loop *L) { - // If this is not an instruction, or if this is an instruction outside of the - // loop, it can't be derived from a loop PHI. - Instruction *I = dyn_cast(V); - if (I == 0 || !L->contains(I->getParent())) return 0; - - if (PHINode *PN = dyn_cast(I)) - if (L->getHeader() == I->getParent()) - return PN; - else - // We don't currently keep track of the control flow needed to evaluate - // PHIs, so we cannot handle PHIs inside of loops. - return 0; - - // If this is a call, and we have no hope of constant folding, bail early. - if (CallInst *CI = dyn_cast(I)) { - if (!CI->getCalledFunction() || - !canConstantFoldCallTo(CI->getCalledFunction())) - return 0; - } else if (InvokeInst *II = dyn_cast(I)) - return 0; +/// CanConstantFold - Return true if we can constant fold an instruction of the +/// specified type, assuming that all operands were constants. +static bool CanConstantFold(const Instruction *I) { + if (isa(I) || isa(I) || + isa(I) || isa(I) || isa(I)) + return true; - // Otherwise, we can evaluate this instruction if all of its operands but one - // are constant, and if the remaining one is derived from a constant evolving - // PHI. - unsigned Op = 0, e = I->getNumOperands(); - while (Op != e && (isa(I->getOperand(Op)) || - isa(I->getOperand(Op)))) - ++Op; // Skip over all constant operands - - if (Op == e) return 0; // No non-constants? Should be folded! - - // Found the first non-constant operand. - unsigned NonConstantOp = Op; - - // Okay, all of the rest must be constants now. - for (++Op; Op != e; ++Op) - if (!(isa(I->getOperand(Op)) || - isa(I->getOperand(Op)))) - return 0; // Too many non-constant operands! - - // This is a expression evolving from a constant PHI if the non-constant - // portion is! - return getConstantEvolvingPHI(I->getOperand(NonConstantOp), L); + if (const CallInst *CI = dyn_cast(I)) + if (const Function *F = CI->getCalledFunction()) + return canConstantFoldCallTo((Function*)F); // FIXME: elim cast + return false; } -/// EvaluateExpression - Given an expression that passes the -/// getConstantEvolvingPHI predicate, evaluate its value assuming the PHI node -/// in the loop has the value PHIVal. If we can't fold this expression for some -/// reason, return null. -static Constant *EvaluateExpression(Value *V, Constant *PHIVal) { - if (isa(V)) return PHIVal; - if (Constant *C = dyn_cast(V)) return C; - if (GlobalValue *GV = dyn_cast(V)) - return ConstantPointerRef::get(GV); - Instruction *I = cast(V); - - std::vector Operands; - Operands.resize(I->getNumOperands()); - - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { - Operands[i] = EvaluateExpression(I->getOperand(i), PHIVal); - if (Operands[i] == 0) return 0; - } - +/// ConstantFold - Constant fold an instruction of the specified type with the +/// specified constant operands. This function may modify the operands vector. +static Constant *ConstantFold(const Instruction *I, + std::vector &Operands) { if (isa(I) || isa(I)) return ConstantExpr::get(I->getOpcode(), Operands[0], Operands[1]); @@ -1647,6 +1609,119 @@ static Constant *EvaluateExpression(Value *V, Constant *PHIVal) { } +/// getConstantEvolvingPHI - Given an LLVM value and a loop, return a PHI node +/// in the loop that V is derived from. We allow arbitrary operations along the +/// way, but the operands of an operation must either be constants or a value +/// derived from a constant PHI. If this expression does not fit with these +/// constraints, return null. +static PHINode *getConstantEvolvingPHI(Value *V, const Loop *L) { + // If this is not an instruction, or if this is an instruction outside of the + // loop, it can't be derived from a loop PHI. + Instruction *I = dyn_cast(V); + if (I == 0 || !L->contains(I->getParent())) return 0; + + if (PHINode *PN = dyn_cast(I)) + if (L->getHeader() == I->getParent()) + return PN; + else + // We don't currently keep track of the control flow needed to evaluate + // PHIs, so we cannot handle PHIs inside of loops. + return 0; + + // If we won't be able to constant fold this expression even if the operands + // are constants, return early. + if (!CanConstantFold(I)) return 0; + + // Otherwise, we can evaluate this instruction if all of its operands are + // constant or derived from a PHI node themselves. + PHINode *PHI = 0; + for (unsigned Op = 0, e = I->getNumOperands(); Op != e; ++Op) + if (!(isa(I->getOperand(Op)) || + isa(I->getOperand(Op)))) { + PHINode *P = getConstantEvolvingPHI(I->getOperand(Op), L); + if (P == 0) return 0; // Not evolving from PHI + if (PHI == 0) + PHI = P; + else if (PHI != P) + return 0; // Evolving from multiple different PHIs. + } + + // This is a expression evolving from a constant PHI! + return PHI; +} + +/// EvaluateExpression - Given an expression that passes the +/// getConstantEvolvingPHI predicate, evaluate its value assuming the PHI node +/// in the loop has the value PHIVal. If we can't fold this expression for some +/// reason, return null. +static Constant *EvaluateExpression(Value *V, Constant *PHIVal) { + if (isa(V)) return PHIVal; + if (Constant *C = dyn_cast(V)) return C; + if (GlobalValue *GV = dyn_cast(V)) + return ConstantPointerRef::get(GV); + Instruction *I = cast(V); + + std::vector Operands; + Operands.resize(I->getNumOperands()); + + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { + Operands[i] = EvaluateExpression(I->getOperand(i), PHIVal); + if (Operands[i] == 0) return 0; + } + + return ConstantFold(I, Operands); +} + +/// getConstantEvolutionLoopExitValue - If we know that the specified Phi is +/// in the header of its containing loop, we know the loop executes a +/// constant number of times, and the PHI node is just a recurrence +/// involving constants, fold it. +Constant *ScalarEvolutionsImpl:: +getConstantEvolutionLoopExitValue(PHINode *PN, uint64_t Its, const Loop *L) { + std::map::iterator I = + ConstantEvolutionLoopExitValue.find(PN); + if (I != ConstantEvolutionLoopExitValue.end()) + return I->second; + + if (Its > MaxBruteForceIterations) + return ConstantEvolutionLoopExitValue[PN] = 0; // Not going to evaluate it. + + Constant *&RetVal = ConstantEvolutionLoopExitValue[PN]; + + // Since the loop is canonicalized, the PHI node must have two entries. One + // entry must be a constant (coming in from outside of the loop), and the + // second must be derived from the same PHI. + bool SecondIsBackedge = L->contains(PN->getIncomingBlock(1)); + Constant *StartCST = + dyn_cast(PN->getIncomingValue(!SecondIsBackedge)); + if (StartCST == 0) + return RetVal = 0; // Must be a constant. + + Value *BEValue = PN->getIncomingValue(SecondIsBackedge); + PHINode *PN2 = getConstantEvolvingPHI(BEValue, L); + if (PN2 != PN) + return RetVal = 0; // Not derived from same PHI. + + // Execute the loop symbolically to determine the exit value. + unsigned IterationNum = 0; + unsigned NumIterations = Its; + if (NumIterations != Its) + return RetVal = 0; // More than 2^32 iterations?? + + for (Constant *PHIVal = StartCST; ; ++IterationNum) { + if (IterationNum == NumIterations) + return RetVal = PHIVal; // Got exit value! + + // Compute the value of the PHI node for the next iteration. + Constant *NextPHI = EvaluateExpression(BEValue, PHIVal); + if (NextPHI == PHIVal) + return RetVal = NextPHI; // Stopped evolving! + if (NextPHI == 0) + return 0; // Couldn't evaluate! + PHIVal = NextPHI; + } +} + /// ComputeIterationCountExhaustively - If the trip is known to execute a /// constant number of times (the condition evolves only from constants), /// try to evaluate a few iterations of the loop until we get the exit @@ -1679,16 +1754,18 @@ ComputeIterationCountExhaustively(const Loop *L, Value *Cond, bool ExitWhen) { ConstantBool *CondVal = dyn_cast_or_null(EvaluateExpression(Cond, PHIVal)); if (!CondVal) return UnknownValue; // Couldn't symbolically evaluate. + if (CondVal->getValue() == ExitWhen) { + ConstantEvolutionLoopExitValue[PN] = PHIVal; ++NumBruteForceTripCountsComputed; return SCEVConstant::get(ConstantUInt::get(Type::UIntTy, IterationNum)); } - // Otherwise, compute the value of the PHI node for the next iteration. - Constant *Next = EvaluateExpression(BEValue, PHIVal); - if (Next == 0 || Next == PHIVal) + // Compute the value of the PHI node for the next iteration. + Constant *NextPHI = EvaluateExpression(BEValue, PHIVal); + if (NextPHI == 0 || NextPHI == PHIVal) return UnknownValue; // Couldn't evaluate or not making progress... - PHIVal = Next; + PHIVal = NextPHI; } // Too many iterations were needed to evaluate. @@ -1701,7 +1778,67 @@ ComputeIterationCountExhaustively(const Loop *L, Value *Cond, bool ExitWhen) { SCEVHandle ScalarEvolutionsImpl::getSCEVAtScope(SCEV *V, const Loop *L) { // FIXME: this should be turned into a virtual method on SCEV! - if (isa(V) || isa(V)) return V; + if (isa(V)) return V; + + // If this instruction is evolves from a constant-evolving PHI, compute the + // exit value from the loop without using SCEVs. + if (SCEVUnknown *SU = dyn_cast(V)) { + if (Instruction *I = dyn_cast(SU->getValue())) { + const Loop *LI = this->LI[I->getParent()]; + if (LI && LI->getParentLoop() == L) // Looking for loop exit value. + if (PHINode *PN = dyn_cast(I)) + if (PN->getParent() == LI->getHeader()) { + // Okay, there is no closed form solution for the PHI node. Check + // to see if the loop that contains it has a known iteration count. + // If so, we may be able to force computation of the exit value. + SCEVHandle IterationCount = getIterationCount(LI); + if (SCEVConstant *ICC = dyn_cast(IterationCount)) { + // Okay, we know how many times the containing loop executes. If + // this is a constant evolving PHI node, get the final value at + // the specified iteration number. + Constant *RV = getConstantEvolutionLoopExitValue(PN, + ICC->getValue()->getRawValue(), + LI); + if (RV) return SCEVUnknown::get(RV); + } + } + + // Okay, this is a some expression that we cannot symbolically evaluate + // into a SCEV. Check to see if it's possible to symbolically evaluate + // the arguments into constants, and if see, try to constant propagate the + // result. This is particularly useful for computing loop exit values. + if (CanConstantFold(I)) { + std::vector Operands; + Operands.reserve(I->getNumOperands()); + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { + Value *Op = I->getOperand(i); + if (Constant *C = dyn_cast(Op)) { + Operands.push_back(C); + } else if (GlobalValue *GV = dyn_cast(Op)) { + Operands.push_back(ConstantPointerRef::get(GV)); + } else { + SCEVHandle OpV = getSCEVAtScope(getSCEV(Op), L); + if (SCEVConstant *SC = dyn_cast(OpV)) + Operands.push_back(ConstantExpr::getCast(SC->getValue(), + Op->getType())); + else if (SCEVUnknown *SU = dyn_cast(OpV)) { + if (Constant *C = dyn_cast(SU->getValue())) + Operands.push_back(ConstantExpr::getCast(C, Op->getType())); + else + return V; + } else { + return V; + } + } + } + return SCEVUnknown::get(ConstantFold(I, Operands)); + } + } + + // This is some other type of SCEVUnknown, just return it. + return V; + } + if (SCEVCommutativeExpr *Comm = dyn_cast(V)) { // Avoid performing the look-up in the common case where the specified // expression has no loop-variant portions. @@ -1711,7 +1848,7 @@ SCEVHandle ScalarEvolutionsImpl::getSCEVAtScope(SCEV *V, const Loop *L) { if (OpAtScope == UnknownValue) return UnknownValue; // Okay, at least one of these operands is loop variant but might be // foldable. Build a new instance of the folded commutative expression. - std::vector NewOps(Comm->op_begin(), Comm->op_begin()+i-1); + std::vector NewOps(Comm->op_begin(), Comm->op_begin()+i); NewOps.push_back(OpAtScope); for (++i; i != e; ++i) {