blob: ec6461ccdcb711f8450abda8acb233feca3e1388 [file] [log] [blame]
Chris Lattner0bbe58f2001-11-26 18:41:20 +00001//===- llvm/Analysis/InductionVariable.h - Induction variable ----*- C++ -*--=//
2//
3// This interface is used to identify and classify induction variables that
4// exist in the program. Induction variables must contain a PHI node that
5// exists in a loop header. Because of this, they are identified an managed by
6// this PHI node.
7//
8// Induction variables are classified into a type. Knowing that an induction
9// variable is of a specific type can constrain the values of the start and
10// step. For example, a SimpleLinear induction variable must have a start and
11// step values that are constants.
12//
13// Induction variables can be created with or without loop information. If no
14// loop information is available, induction variables cannot be recognized to be
15// more than SimpleLinear variables.
16//
17//===----------------------------------------------------------------------===//
18
19#include "llvm/Analysis/InductionVariable.h"
20#include "llvm/Analysis/LoopInfo.h"
21#include "llvm/Analysis/Expressions.h"
Chris Lattner7061dc52001-12-03 18:02:31 +000022#include "llvm/iPHINode.h"
23#include "llvm/InstrTypes.h"
Chris Lattner0bbe58f2001-11-26 18:41:20 +000024#include "llvm/Type.h"
Chris Lattner31bcdb82002-04-28 19:55:58 +000025#include "llvm/Constants.h"
Chris Lattnera59cbb22002-07-27 01:12:17 +000026#include "llvm/Assembly/Writer.h"
Chris Lattner0bbe58f2001-11-26 18:41:20 +000027
Chris Lattner1b7f7dc2002-04-28 16:21:30 +000028static bool isLoopInvariant(const Value *V, const Loop *L) {
Chris Lattner73e21422002-04-09 19:48:49 +000029 if (isa<Constant>(V) || isa<Argument>(V) || isa<GlobalValue>(V))
Chris Lattner0bbe58f2001-11-26 18:41:20 +000030 return true;
31
Chris Lattner7e708292002-06-25 16:13:24 +000032 const Instruction *I = cast<Instruction>(V);
33 const BasicBlock *BB = I->getParent();
Chris Lattner0bbe58f2001-11-26 18:41:20 +000034
35 return !L->contains(BB);
36}
37
38enum InductionVariable::iType
39InductionVariable::Classify(const Value *Start, const Value *Step,
Chris Lattnerceadf052002-07-24 22:40:36 +000040 const Loop *L) {
Chris Lattner0bbe58f2001-11-26 18:41:20 +000041 // Check for cannonical and simple linear expressions now...
Chris Lattner7e708292002-06-25 16:13:24 +000042 if (const ConstantInt *CStart = dyn_cast<ConstantInt>(Start))
43 if (const ConstantInt *CStep = dyn_cast<ConstantInt>(Step)) {
Chris Lattner0bbe58f2001-11-26 18:41:20 +000044 if (CStart->equalsInt(0) && CStep->equalsInt(1))
45 return Cannonical;
46 else
47 return SimpleLinear;
48 }
49
50 // Without loop information, we cannot do any better, so bail now...
51 if (L == 0) return Unknown;
52
53 if (isLoopInvariant(Start, L) && isLoopInvariant(Step, L))
54 return Linear;
55 return Unknown;
56}
57
58// Create an induction variable for the specified value. If it is a PHI, and
59// if it's recognizable, classify it and fill in instance variables.
60//
Chris Lattner1b7f7dc2002-04-28 16:21:30 +000061InductionVariable::InductionVariable(PHINode *P, LoopInfo *LoopInfo) {
Chris Lattner0bbe58f2001-11-26 18:41:20 +000062 InductionType = Unknown; // Assume the worst
Chris Lattnerdf89f6e2001-12-03 17:27:42 +000063 Phi = P;
Chris Lattner0bbe58f2001-11-26 18:41:20 +000064
Chris Lattnerdf89f6e2001-12-03 17:27:42 +000065 // If the PHI node has more than two predecessors, we don't know how to
Chris Lattner0bbe58f2001-11-26 18:41:20 +000066 // handle it.
67 //
Chris Lattnerdf89f6e2001-12-03 17:27:42 +000068 if (Phi->getNumIncomingValues() != 2) return;
Chris Lattner0bbe58f2001-11-26 18:41:20 +000069
Chris Lattner6de230a2001-12-05 06:32:30 +000070 // FIXME: Handle FP induction variables.
71 if (Phi->getType() == Type::FloatTy || Phi->getType() == Type::DoubleTy)
72 return;
73
Chris Lattner0bbe58f2001-11-26 18:41:20 +000074 // If we have loop information, make sure that this PHI node is in the header
75 // of a loop...
76 //
Chris Lattner1b7f7dc2002-04-28 16:21:30 +000077 const Loop *L = LoopInfo ? LoopInfo->getLoopFor(Phi->getParent()) : 0;
Chris Lattner0bbe58f2001-11-26 18:41:20 +000078 if (L && L->getHeader() != Phi->getParent())
79 return;
80
81 Value *V1 = Phi->getIncomingValue(0);
82 Value *V2 = Phi->getIncomingValue(1);
83
84 if (L == 0) { // No loop information? Base everything on expression analysis
Chris Lattnerc74cb862002-08-30 22:53:53 +000085 ExprType E1 = ClassifyExpression(V1);
86 ExprType E2 = ClassifyExpression(V2);
Chris Lattner0bbe58f2001-11-26 18:41:20 +000087
88 if (E1.ExprTy > E2.ExprTy) // Make E1 be the simpler expression
Chris Lattner697954c2002-01-20 22:54:45 +000089 std::swap(E1, E2);
Chris Lattner0bbe58f2001-11-26 18:41:20 +000090
91 // E1 must be a constant incoming value, and E2 must be a linear expression
92 // with respect to the PHI node.
93 //
94 if (E1.ExprTy > ExprType::Constant || E2.ExprTy != ExprType::Linear ||
95 E2.Var != Phi)
96 return;
97
98 // Okay, we have found an induction variable. Save the start and step values
99 const Type *ETy = Phi->getType();
Chris Lattner9b625032002-05-06 16:15:30 +0000100 if (isa<PointerType>(ETy)) ETy = Type::ULongTy;
Chris Lattner0bbe58f2001-11-26 18:41:20 +0000101
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000102 Start = (Value*)(E1.Offset ? E1.Offset : ConstantInt::get(ETy, 0));
103 Step = (Value*)(E2.Offset ? E2.Offset : ConstantInt::get(ETy, 0));
Chris Lattner0bbe58f2001-11-26 18:41:20 +0000104 } else {
105 // Okay, at this point, we know that we have loop information...
106
107 // Make sure that V1 is the incoming value, and V2 is from the backedge of
108 // the loop.
109 if (L->contains(Phi->getIncomingBlock(0))) // Wrong order. Swap now.
Chris Lattner697954c2002-01-20 22:54:45 +0000110 std::swap(V1, V2);
Chris Lattner0bbe58f2001-11-26 18:41:20 +0000111
112 Start = V1; // We know that Start has to be loop invariant...
113 Step = 0;
114
115 if (V2 == Phi) { // referencing the PHI directly? Must have zero step
Chris Lattner1a18b7c2002-04-27 02:25:14 +0000116 Step = Constant::getNullValue(Phi->getType());
Chris Lattner0bbe58f2001-11-26 18:41:20 +0000117 } else if (BinaryOperator *I = dyn_cast<BinaryOperator>(V2)) {
118 // TODO: This could be much better...
119 if (I->getOpcode() == Instruction::Add) {
120 if (I->getOperand(0) == Phi)
121 Step = I->getOperand(1);
122 else if (I->getOperand(1) == Phi)
123 Step = I->getOperand(0);
124 }
125 }
126
127 if (Step == 0) { // Unrecognized step value...
Chris Lattnerc74cb862002-08-30 22:53:53 +0000128 ExprType StepE = ClassifyExpression(V2);
Chris Lattner0bbe58f2001-11-26 18:41:20 +0000129 if (StepE.ExprTy != ExprType::Linear ||
130 StepE.Var != Phi) return;
131
132 const Type *ETy = Phi->getType();
Chris Lattner9b625032002-05-06 16:15:30 +0000133 if (isa<PointerType>(ETy)) ETy = Type::ULongTy;
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000134 Step = (Value*)(StepE.Offset ? StepE.Offset : ConstantInt::get(ETy, 0));
Chris Lattner621c9922001-12-04 08:12:47 +0000135 } else { // We were able to get a step value, simplify with expr analysis
Chris Lattnerc74cb862002-08-30 22:53:53 +0000136 ExprType StepE = ClassifyExpression(Step);
Chris Lattner621c9922001-12-04 08:12:47 +0000137 if (StepE.ExprTy == ExprType::Linear && StepE.Offset == 0) {
138 // No offset from variable? Grab the variable
139 Step = StepE.Var;
140 } else if (StepE.ExprTy == ExprType::Constant) {
141 if (StepE.Offset)
142 Step = (Value*)StepE.Offset;
143 else
Chris Lattner1a18b7c2002-04-27 02:25:14 +0000144 Step = Constant::getNullValue(Step->getType());
Chris Lattner6de230a2001-12-05 06:32:30 +0000145 const Type *ETy = Phi->getType();
Chris Lattner9b625032002-05-06 16:15:30 +0000146 if (isa<PointerType>(ETy)) ETy = Type::ULongTy;
Chris Lattner6de230a2001-12-05 06:32:30 +0000147 Step = (Value*)(StepE.Offset ? StepE.Offset : ConstantInt::get(ETy,0));
Chris Lattner621c9922001-12-04 08:12:47 +0000148 }
Chris Lattner0bbe58f2001-11-26 18:41:20 +0000149 }
150 }
151
152 // Classify the induction variable type now...
153 InductionType = InductionVariable::Classify(Start, Step, L);
154}
Chris Lattnera59cbb22002-07-27 01:12:17 +0000155
156void InductionVariable::print(std::ostream &o) const {
157 switch (InductionType) {
158 case InductionVariable::Cannonical: o << "Cannonical "; break;
159 case InductionVariable::SimpleLinear: o << "SimpleLinear "; break;
160 case InductionVariable::Linear: o << "Linear "; break;
161 case InductionVariable::Unknown: o << "Unrecognized "; break;
162 }
Chris Lattner74493a42002-09-10 15:35:39 +0000163 o << "Induction Variable: ";
Chris Lattnera59cbb22002-07-27 01:12:17 +0000164 if (Phi) {
165 WriteAsOperand(o, Phi);
166 o << ":\n" << Phi;
167 } else {
168 o << "\n";
169 }
170 if (InductionType == InductionVariable::Unknown) return;
171
Chris Lattner74493a42002-09-10 15:35:39 +0000172 o << " Start = "; WriteAsOperand(o, Start);
173 o << " Step = " ; WriteAsOperand(o, Step);
Chris Lattnera59cbb22002-07-27 01:12:17 +0000174 o << "\n";
175}