| Chris Lattner | f6e5233f | 2003-09-10 05:08:19 +0000 | [diff] [blame] | 1 | //===- InductionVariable.cpp - Induction variable classification ----------===// | 
| John Criswell | b576c94 | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 2 | //  | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
 | 5 | // This file was developed by the LLVM research group and is distributed under | 
 | 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. | 
 | 7 | //  | 
 | 8 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 9 | // | 
| Chris Lattner | f6e5233f | 2003-09-10 05:08:19 +0000 | [diff] [blame] | 10 | // This file implements identification and classification of induction  | 
 | 11 | // variables.  Induction variables must contain a PHI node that exists in a  | 
 | 12 | // loop header.  Because of this, they are identified an managed by this PHI  | 
 | 13 | // node. | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 14 | // | 
 | 15 | // Induction variables are classified into a type.  Knowing that an induction | 
 | 16 | // variable is of a specific type can constrain the values of the start and | 
 | 17 | // step.  For example, a SimpleLinear induction variable must have a start and | 
 | 18 | // step values that are constants. | 
 | 19 | // | 
 | 20 | // Induction variables can be created with or without loop information.  If no | 
 | 21 | // loop information is available, induction variables cannot be recognized to be | 
 | 22 | // more than SimpleLinear variables. | 
 | 23 | // | 
 | 24 | //===----------------------------------------------------------------------===// | 
 | 25 |  | 
 | 26 | #include "llvm/Analysis/InductionVariable.h" | 
 | 27 | #include "llvm/Analysis/LoopInfo.h" | 
 | 28 | #include "llvm/Analysis/Expressions.h" | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 29 | #include "llvm/BasicBlock.h" | 
| Chris Lattner | 4c307d4 | 2003-12-22 05:26:29 +0000 | [diff] [blame] | 30 | #include "llvm/Instructions.h" | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 31 | #include "llvm/Type.h" | 
| Chris Lattner | 31bcdb8 | 2002-04-28 19:55:58 +0000 | [diff] [blame] | 32 | #include "llvm/Constants.h" | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 33 | #include "llvm/Support/CFG.h" | 
| Chris Lattner | a59cbb2 | 2002-07-27 01:12:17 +0000 | [diff] [blame] | 34 | #include "llvm/Assembly/Writer.h" | 
| Chris Lattner | 6806f56 | 2003-08-01 22:15:03 +0000 | [diff] [blame] | 35 | #include "Support/Debug.h" | 
| Chris Lattner | 4c307d4 | 2003-12-22 05:26:29 +0000 | [diff] [blame] | 36 | using namespace llvm; | 
| Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 37 |  | 
| Chris Lattner | 1b7f7dc | 2002-04-28 16:21:30 +0000 | [diff] [blame] | 38 | static bool isLoopInvariant(const Value *V, const Loop *L) { | 
| Chris Lattner | 36836a6 | 2003-09-10 04:49:10 +0000 | [diff] [blame] | 39 |   if (const Instruction *I = dyn_cast<Instruction>(V)) | 
 | 40 |     return !L->contains(I->getParent()); | 
 | 41 |   // non-instructions all dominate instructions/blocks | 
 | 42 |   return true; | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 43 | } | 
 | 44 |  | 
 | 45 | enum InductionVariable::iType | 
 | 46 | InductionVariable::Classify(const Value *Start, const Value *Step, | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 47 |                             const Loop *L) { | 
| Chris Lattner | 69ecd0d | 2003-09-10 05:24:09 +0000 | [diff] [blame] | 48 |   // Check for canonical and simple linear expressions now... | 
| Chris Lattner | 7e70829 | 2002-06-25 16:13:24 +0000 | [diff] [blame] | 49 |   if (const ConstantInt *CStart = dyn_cast<ConstantInt>(Start)) | 
 | 50 |     if (const ConstantInt *CStep = dyn_cast<ConstantInt>(Step)) { | 
| Chris Lattner | 36836a6 | 2003-09-10 04:49:10 +0000 | [diff] [blame] | 51 |       if (CStart->isNullValue() && CStep->equalsInt(1)) | 
| Chris Lattner | 69ecd0d | 2003-09-10 05:24:09 +0000 | [diff] [blame] | 52 |         return Canonical; | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 53 |       else | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 54 |         return SimpleLinear; | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 55 |     } | 
 | 56 |  | 
 | 57 |   // Without loop information, we cannot do any better, so bail now... | 
 | 58 |   if (L == 0) return Unknown; | 
 | 59 |  | 
 | 60 |   if (isLoopInvariant(Start, L) && isLoopInvariant(Step, L)) | 
 | 61 |     return Linear; | 
 | 62 |   return Unknown; | 
 | 63 | } | 
 | 64 |  | 
 | 65 | // Create an induction variable for the specified value.  If it is a PHI, and | 
 | 66 | // if it's recognizable, classify it and fill in instance variables. | 
 | 67 | // | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 68 | InductionVariable::InductionVariable(PHINode *P, LoopInfo *LoopInfo): End(0) { | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 69 |   InductionType = Unknown;     // Assume the worst | 
| Chris Lattner | df89f6e | 2001-12-03 17:27:42 +0000 | [diff] [blame] | 70 |   Phi = P; | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 71 |    | 
| Chris Lattner | df89f6e | 2001-12-03 17:27:42 +0000 | [diff] [blame] | 72 |   // If the PHI node has more than two predecessors, we don't know how to | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 73 |   // handle it. | 
 | 74 |   // | 
| Chris Lattner | df89f6e | 2001-12-03 17:27:42 +0000 | [diff] [blame] | 75 |   if (Phi->getNumIncomingValues() != 2) return; | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 76 |  | 
| Chris Lattner | 6de230a | 2001-12-05 06:32:30 +0000 | [diff] [blame] | 77 |   // FIXME: Handle FP induction variables. | 
 | 78 |   if (Phi->getType() == Type::FloatTy || Phi->getType() == Type::DoubleTy) | 
 | 79 |     return; | 
 | 80 |  | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 81 |   // If we have loop information, make sure that this PHI node is in the header | 
 | 82 |   // of a loop... | 
 | 83 |   // | 
| Chris Lattner | 1b7f7dc | 2002-04-28 16:21:30 +0000 | [diff] [blame] | 84 |   const Loop *L = LoopInfo ? LoopInfo->getLoopFor(Phi->getParent()) : 0; | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 85 |   if (L && L->getHeader() != Phi->getParent()) | 
 | 86 |     return; | 
 | 87 |  | 
 | 88 |   Value *V1 = Phi->getIncomingValue(0); | 
 | 89 |   Value *V2 = Phi->getIncomingValue(1); | 
 | 90 |  | 
 | 91 |   if (L == 0) {  // No loop information?  Base everything on expression analysis | 
| Chris Lattner | 9a0a41f | 2003-12-23 08:04:08 +0000 | [diff] [blame^] | 92 |     ExprType E1 = ClassifyExpr(V1); | 
 | 93 |     ExprType E2 = ClassifyExpr(V2); | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 94 |  | 
 | 95 |     if (E1.ExprTy > E2.ExprTy)        // Make E1 be the simpler expression | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 96 |       std::swap(E1, E2); | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 97 |      | 
 | 98 |     // E1 must be a constant incoming value, and E2 must be a linear expression | 
 | 99 |     // with respect to the PHI node. | 
 | 100 |     // | 
 | 101 |     if (E1.ExprTy > ExprType::Constant || E2.ExprTy != ExprType::Linear || | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 102 |         E2.Var != Phi) | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 103 |       return; | 
 | 104 |  | 
 | 105 |     // Okay, we have found an induction variable. Save the start and step values | 
 | 106 |     const Type *ETy = Phi->getType(); | 
| Chris Lattner | 9b62503 | 2002-05-06 16:15:30 +0000 | [diff] [blame] | 107 |     if (isa<PointerType>(ETy)) ETy = Type::ULongTy; | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 108 |  | 
| Chris Lattner | e9bb2df | 2001-12-03 22:26:30 +0000 | [diff] [blame] | 109 |     Start = (Value*)(E1.Offset ? E1.Offset : ConstantInt::get(ETy, 0)); | 
 | 110 |     Step  = (Value*)(E2.Offset ? E2.Offset : ConstantInt::get(ETy, 0)); | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 111 |   } else { | 
 | 112 |     // Okay, at this point, we know that we have loop information... | 
 | 113 |  | 
 | 114 |     // Make sure that V1 is the incoming value, and V2 is from the backedge of | 
 | 115 |     // the loop. | 
 | 116 |     if (L->contains(Phi->getIncomingBlock(0)))     // Wrong order.  Swap now. | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 117 |       std::swap(V1, V2); | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 118 |      | 
 | 119 |     Start = V1;     // We know that Start has to be loop invariant... | 
 | 120 |     Step = 0; | 
 | 121 |  | 
 | 122 |     if (V2 == Phi) {  // referencing the PHI directly?  Must have zero step | 
| Chris Lattner | 1a18b7c | 2002-04-27 02:25:14 +0000 | [diff] [blame] | 123 |       Step = Constant::getNullValue(Phi->getType()); | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 124 |     } else if (BinaryOperator *I = dyn_cast<BinaryOperator>(V2)) { | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 125 |       if (I->getOpcode() == Instruction::Add) { | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 126 |         if (I->getOperand(0) == Phi) | 
 | 127 |           Step = I->getOperand(1); | 
 | 128 |         else if (I->getOperand(1) == Phi) | 
 | 129 |           Step = I->getOperand(0); | 
| Chris Lattner | 4c307d4 | 2003-12-22 05:26:29 +0000 | [diff] [blame] | 130 |       } else if (I->getOpcode() == Instruction::Sub && | 
 | 131 |                  I->getOperand(0) == Phi) { | 
 | 132 |         // If the incoming value is a constant, just form a constant negative | 
 | 133 |         // step.  Otherwise, negate the step outside of the loop and use it. | 
 | 134 |         Value *V = I->getOperand(1); | 
 | 135 |         Constant *Zero = Constant::getNullValue(V->getType()); | 
 | 136 |         if (Constant *CV = dyn_cast<Constant>(V)) | 
 | 137 |           Step = ConstantExpr::get(Instruction::Sub, Zero, CV); | 
 | 138 |         else if (Instruction *I = dyn_cast<Instruction>(V)) { | 
 | 139 |           Step = BinaryOperator::create(Instruction::Sub, Zero, V, | 
 | 140 |                                         V->getName()+".neg", I->getNext()); | 
 | 141 |  | 
 | 142 |         } else { | 
 | 143 |           Step = BinaryOperator::create(Instruction::Sub, Zero, V, | 
 | 144 |                                         V->getName()+".neg",  | 
 | 145 |                               Phi->getParent()->getParent()->begin()->begin()); | 
 | 146 |         } | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 147 |       } | 
| Chris Lattner | 4c307d4 | 2003-12-22 05:26:29 +0000 | [diff] [blame] | 148 |     } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V2)) { | 
 | 149 |       if (GEP->getNumOperands() == 2 && | 
 | 150 |           GEP->getOperand(0) == Phi) | 
 | 151 |         Step = GEP->getOperand(1); | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 152 |     } | 
 | 153 |  | 
 | 154 |     if (Step == 0) {                  // Unrecognized step value... | 
| Chris Lattner | 9a0a41f | 2003-12-23 08:04:08 +0000 | [diff] [blame^] | 155 |       ExprType StepE = ClassifyExpr(V2); | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 156 |       if (StepE.ExprTy != ExprType::Linear || | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 157 |           StepE.Var != Phi) return; | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 158 |  | 
 | 159 |       const Type *ETy = Phi->getType(); | 
| Chris Lattner | 9b62503 | 2002-05-06 16:15:30 +0000 | [diff] [blame] | 160 |       if (isa<PointerType>(ETy)) ETy = Type::ULongTy; | 
| Chris Lattner | e9bb2df | 2001-12-03 22:26:30 +0000 | [diff] [blame] | 161 |       Step  = (Value*)(StepE.Offset ? StepE.Offset : ConstantInt::get(ETy, 0)); | 
| Chris Lattner | 621c992 | 2001-12-04 08:12:47 +0000 | [diff] [blame] | 162 |     } else {   // We were able to get a step value, simplify with expr analysis | 
| Chris Lattner | 9a0a41f | 2003-12-23 08:04:08 +0000 | [diff] [blame^] | 163 |       ExprType StepE = ClassifyExpr(Step); | 
| Chris Lattner | 621c992 | 2001-12-04 08:12:47 +0000 | [diff] [blame] | 164 |       if (StepE.ExprTy == ExprType::Linear && StepE.Offset == 0) { | 
 | 165 |         // No offset from variable?  Grab the variable | 
 | 166 |         Step = StepE.Var; | 
 | 167 |       } else if (StepE.ExprTy == ExprType::Constant) { | 
 | 168 |         if (StepE.Offset) | 
 | 169 |           Step = (Value*)StepE.Offset; | 
 | 170 |         else | 
| Chris Lattner | 1a18b7c | 2002-04-27 02:25:14 +0000 | [diff] [blame] | 171 |           Step = Constant::getNullValue(Step->getType()); | 
| Chris Lattner | 6de230a | 2001-12-05 06:32:30 +0000 | [diff] [blame] | 172 |         const Type *ETy = Phi->getType(); | 
| Chris Lattner | 9b62503 | 2002-05-06 16:15:30 +0000 | [diff] [blame] | 173 |         if (isa<PointerType>(ETy)) ETy = Type::ULongTy; | 
| Chris Lattner | 6de230a | 2001-12-05 06:32:30 +0000 | [diff] [blame] | 174 |         Step  = (Value*)(StepE.Offset ? StepE.Offset : ConstantInt::get(ETy,0)); | 
| Chris Lattner | 621c992 | 2001-12-04 08:12:47 +0000 | [diff] [blame] | 175 |       } | 
| Chris Lattner | 0bbe58f | 2001-11-26 18:41:20 +0000 | [diff] [blame] | 176 |     } | 
 | 177 |   } | 
 | 178 |  | 
 | 179 |   // Classify the induction variable type now... | 
 | 180 |   InductionType = InductionVariable::Classify(Start, Step, L); | 
 | 181 | } | 
| Chris Lattner | a59cbb2 | 2002-07-27 01:12:17 +0000 | [diff] [blame] | 182 |  | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 183 |  | 
| Chris Lattner | 44abf85 | 2003-09-10 14:51:49 +0000 | [diff] [blame] | 184 | Value *InductionVariable::getExecutionCount(LoopInfo *LoopInfo) { | 
 | 185 |   if (InductionType != Canonical) return 0; | 
 | 186 |  | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 187 |   DEBUG(std::cerr << "entering getExecutionCount\n"); | 
 | 188 |  | 
 | 189 |   // Don't recompute if already available | 
 | 190 |   if (End) { | 
 | 191 |     DEBUG(std::cerr << "returning cached End value.\n"); | 
 | 192 |     return End; | 
 | 193 |   } | 
 | 194 |  | 
 | 195 |   const Loop *L = LoopInfo ? LoopInfo->getLoopFor(Phi->getParent()) : 0; | 
 | 196 |   if (!L) { | 
 | 197 |     DEBUG(std::cerr << "null loop. oops\n"); | 
| Chris Lattner | 44abf85 | 2003-09-10 14:51:49 +0000 | [diff] [blame] | 198 |     return 0; | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 199 |   } | 
 | 200 |  | 
 | 201 |   // >1 backedge => cannot predict number of iterations | 
 | 202 |   if (Phi->getNumIncomingValues() != 2) { | 
 | 203 |     DEBUG(std::cerr << ">2 incoming values. oops\n"); | 
| Chris Lattner | 44abf85 | 2003-09-10 14:51:49 +0000 | [diff] [blame] | 204 |     return 0; | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 205 |   } | 
 | 206 |  | 
| Misha Brukman | 2f2d065 | 2003-09-11 18:14:24 +0000 | [diff] [blame] | 207 |   // Find final node: predecessor of the loop header that's also an exit | 
| Chris Lattner | 0006bd7 | 2002-11-09 00:49:43 +0000 | [diff] [blame] | 208 |   BasicBlock *terminator = 0; | 
| Chris Lattner | 44abf85 | 2003-09-10 14:51:49 +0000 | [diff] [blame] | 209 |   for (pred_iterator PI = pred_begin(L->getHeader()), | 
 | 210 |          PE = pred_end(L->getHeader()); PI != PE; ++PI) | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 211 |     if (L->isLoopExit(*PI)) { | 
 | 212 |       terminator = *PI; | 
 | 213 |       break; | 
 | 214 |     } | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 215 |  | 
 | 216 |   // Break in the loop => cannot predict number of iterations | 
 | 217 |   // break: any block which is an exit node whose successor is not in loop, | 
 | 218 |   // and this block is not marked as the terminator | 
 | 219 |   // | 
 | 220 |   const std::vector<BasicBlock*> &blocks = L->getBlocks(); | 
| Chris Lattner | 44abf85 | 2003-09-10 14:51:49 +0000 | [diff] [blame] | 221 |   for (std::vector<BasicBlock*>::const_iterator I = blocks.begin(), | 
 | 222 |          e = blocks.end(); I != e; ++I) | 
 | 223 |     if (L->isLoopExit(*I) && *I != terminator) | 
 | 224 |       for (succ_iterator SI = succ_begin(*I), SE = succ_end(*I); SI != SE; ++SI) | 
 | 225 |         if (!L->contains(*SI)) { | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 226 |           DEBUG(std::cerr << "break found in loop"); | 
| Chris Lattner | 44abf85 | 2003-09-10 14:51:49 +0000 | [diff] [blame] | 227 |           return 0; | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 228 |         } | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 229 |  | 
 | 230 |   BranchInst *B = dyn_cast<BranchInst>(terminator->getTerminator()); | 
 | 231 |   if (!B) { | 
| Chris Lattner | 44abf85 | 2003-09-10 14:51:49 +0000 | [diff] [blame] | 232 |     DEBUG(std::cerr << "Terminator is not a cond branch!"); | 
 | 233 |     return 0;  | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 234 |   } | 
| Chris Lattner | 2ee82e0 | 2003-04-23 16:36:11 +0000 | [diff] [blame] | 235 |   SetCondInst *SCI = dyn_cast<SetCondInst>(B->getCondition()); | 
| Chris Lattner | 44abf85 | 2003-09-10 14:51:49 +0000 | [diff] [blame] | 236 |   if (!SCI) { | 
 | 237 |     DEBUG(std::cerr << "Not a cond branch on setcc!\n"); | 
 | 238 |     return 0; | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 239 |   } | 
| Chris Lattner | 44abf85 | 2003-09-10 14:51:49 +0000 | [diff] [blame] | 240 |  | 
 | 241 |   DEBUG(std::cerr << "sci:" << *SCI); | 
 | 242 |   Value *condVal0 = SCI->getOperand(0); | 
 | 243 |   Value *condVal1 = SCI->getOperand(1); | 
| Chris Lattner | 44abf85 | 2003-09-10 14:51:49 +0000 | [diff] [blame] | 244 |  | 
| Chris Lattner | a176a8b | 2003-09-10 14:55:05 +0000 | [diff] [blame] | 245 |   // The induction variable is the one coming from the backedge | 
 | 246 |   Value *indVar = Phi->getIncomingValue(L->contains(Phi->getIncomingBlock(1))); | 
| Chris Lattner | 44abf85 | 2003-09-10 14:51:49 +0000 | [diff] [blame] | 247 |  | 
 | 248 |  | 
 | 249 |   // Check to see if indVar is one of the parameters in SCI and if the other is | 
 | 250 |   // loop-invariant, it is the UB | 
 | 251 |   if (indVar == condVal0) { | 
 | 252 |     if (isLoopInvariant(condVal1, L)) | 
 | 253 |       End = condVal1; | 
 | 254 |     else { | 
 | 255 |       DEBUG(std::cerr << "not loop invariant 1\n"); | 
 | 256 |       return 0; | 
 | 257 |     } | 
 | 258 |   } else if (indVar == condVal1) { | 
 | 259 |     if (isLoopInvariant(condVal0, L)) | 
 | 260 |       End = condVal0; | 
 | 261 |     else { | 
 | 262 |       DEBUG(std::cerr << "not loop invariant 0\n"); | 
 | 263 |       return 0; | 
 | 264 |     } | 
 | 265 |   } else { | 
 | 266 |     DEBUG(std::cerr << "Loop condition doesn't directly uses indvar\n"); | 
 | 267 |     return 0; | 
 | 268 |   } | 
 | 269 |  | 
 | 270 |   switch (SCI->getOpcode()) { | 
 | 271 |   case Instruction::SetLT: | 
 | 272 |   case Instruction::SetNE: return End; // already done | 
 | 273 |   case Instruction::SetLE: | 
 | 274 |     // if compared to a constant int N, then predict N+1 iterations | 
 | 275 |     if (ConstantSInt *ubSigned = dyn_cast<ConstantSInt>(End)) { | 
 | 276 |       DEBUG(std::cerr << "signed int constant\n"); | 
 | 277 |       return ConstantSInt::get(ubSigned->getType(), ubSigned->getValue()+1); | 
 | 278 |     } else if (ConstantUInt *ubUnsigned = dyn_cast<ConstantUInt>(End)) { | 
 | 279 |       DEBUG(std::cerr << "unsigned int constant\n"); | 
 | 280 |       return ConstantUInt::get(ubUnsigned->getType(), | 
 | 281 |                                ubUnsigned->getValue()+1); | 
 | 282 |     } else { | 
 | 283 |       DEBUG(std::cerr << "symbolic bound\n"); | 
 | 284 |       // new expression N+1, insert right before the SCI.  FIXME: If End is loop | 
 | 285 |       // invariant, then so is this expression.  We should insert it in the loop | 
 | 286 |       // preheader if it exists. | 
 | 287 |       return BinaryOperator::create(Instruction::Add, End,  | 
 | 288 |                                     ConstantInt::get(End->getType(), 1), | 
 | 289 |                                     "tripcount", SCI); | 
 | 290 |     } | 
 | 291 |  | 
 | 292 |   default: | 
 | 293 |     return 0; // cannot predict | 
 | 294 |   } | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 295 | } | 
 | 296 |  | 
 | 297 |  | 
| Chris Lattner | a59cbb2 | 2002-07-27 01:12:17 +0000 | [diff] [blame] | 298 | void InductionVariable::print(std::ostream &o) const { | 
 | 299 |   switch (InductionType) { | 
| Chris Lattner | 69ecd0d | 2003-09-10 05:24:09 +0000 | [diff] [blame] | 300 |   case InductionVariable::Canonical:    o << "Canonical ";    break; | 
| Chris Lattner | a59cbb2 | 2002-07-27 01:12:17 +0000 | [diff] [blame] | 301 |   case InductionVariable::SimpleLinear: o << "SimpleLinear "; break; | 
 | 302 |   case InductionVariable::Linear:       o << "Linear ";       break; | 
 | 303 |   case InductionVariable::Unknown:      o << "Unrecognized "; break; | 
 | 304 |   } | 
| Chris Lattner | 74493a4 | 2002-09-10 15:35:39 +0000 | [diff] [blame] | 305 |   o << "Induction Variable: "; | 
| Chris Lattner | a59cbb2 | 2002-07-27 01:12:17 +0000 | [diff] [blame] | 306 |   if (Phi) { | 
 | 307 |     WriteAsOperand(o, Phi); | 
 | 308 |     o << ":\n" << Phi; | 
 | 309 |   } else { | 
 | 310 |     o << "\n"; | 
 | 311 |   } | 
 | 312 |   if (InductionType == InductionVariable::Unknown) return; | 
 | 313 |  | 
| Chris Lattner | 74493a4 | 2002-09-10 15:35:39 +0000 | [diff] [blame] | 314 |   o << "  Start = "; WriteAsOperand(o, Start); | 
 | 315 |   o << "  Step = " ; WriteAsOperand(o, Step); | 
| Misha Brukman | a272290 | 2002-10-11 05:34:32 +0000 | [diff] [blame] | 316 |   if (End) {  | 
 | 317 |     o << "  End = " ; WriteAsOperand(o, End); | 
 | 318 |   } | 
| Chris Lattner | a59cbb2 | 2002-07-27 01:12:17 +0000 | [diff] [blame] | 319 |   o << "\n"; | 
 | 320 | } |