IndVarSimplify.cpp revision 5ba99bd124dc18302f527d6e2b0efd0fa866bc9e
16148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner//===- IndVarSimplify.cpp - Induction Variable Elimination ----------------===//
26148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner//
36148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner// InductionVariableSimplify - Transform induction variables in a program
46148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner//   to all use a single cannonical induction variable per loop.
56148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner//
66148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner//===----------------------------------------------------------------------===//
76148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner
8022103b3f33febb7e54b8fdf2c9bc461eea78cbaChris Lattner#include "llvm/Transforms/Scalar.h"
96148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner#include "llvm/Analysis/InductionVariable.h"
106148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner#include "llvm/Analysis/LoopInfo.h"
11f016ea4ff80c56c467247a90567dd07bddb590f3Chris Lattner#include "llvm/Analysis/Writer.h"
126148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner#include "llvm/iPHINode.h"
13394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner#include "llvm/iOther.h"
14394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner#include "llvm/Type.h"
1531bcdb822fe9133b1973de51519d34e5813a6184Chris Lattner#include "llvm/Constants.h"
16455889aa79e3463a4b0f2161e3d9d72a683268b6Chris Lattner#include "llvm/Support/CFG.h"
176148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner#include "Support/STLExtras.h"
183dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner#include "Support/StatisticReporter.h"
195ba99bd124dc18302f527d6e2b0efd0fa866bc9eAnand Shukla#include <iostream>
203dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner
213dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattnerstatic Statistic<> NumRemoved ("indvars\t\t- Number of aux indvars removed");
223dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattnerstatic Statistic<> NumInserted("indvars\t\t- Number of cannonical indvars added");
236148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner
24394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
25394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner// InsertCast - Cast Val to Ty, setting a useful name on the cast if Val has a
26394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner// name...
27394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner//
28394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattnerstatic Instruction *InsertCast(Instruction *Val, const Type *Ty,
29394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner                               BasicBlock::iterator It) {
30394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  Instruction *Cast = new CastInst(Val, Ty);
31394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  if (Val->hasName()) Cast->setName(Val->getName()+"-casted");
32394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  Val->getParent()->getInstList().insert(It, Cast);
33394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  return Cast;
34394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner}
35394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
361b7f7dc4b45a900fae2e9b062d588a995935727aChris Lattnerstatic bool TransformLoop(LoopInfo *Loops, Loop *Loop) {
376148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  // Transform all subloops before this loop...
386148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  bool Changed = reduce_apply_bool(Loop->getSubLoops().begin(),
396148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner                                   Loop->getSubLoops().end(),
40697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner                              std::bind1st(std::ptr_fun(TransformLoop), Loops));
416148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  // Get the header node for this loop.  All of the phi nodes that could be
426148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  // induction variables must live in this basic block.
433dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner  //
443dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner  BasicBlock *Header = Loop->getBlocks().front();
456148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner
466148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  // Loop over all of the PHI nodes in the basic block, calculating the
476148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  // induction variables that they represent... stuffing the induction variable
486148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  // info into a vector...
496148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  //
50697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  std::vector<InductionVariable> IndVars;    // Induction variables for block
517e70829632f82de15db187845666aaca6e04b792Chris Lattner  BasicBlock::iterator AfterPHIIt = Header->begin();
527e70829632f82de15db187845666aaca6e04b792Chris Lattner  for (; PHINode *PN = dyn_cast<PHINode>(&*AfterPHIIt); ++AfterPHIIt)
536148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner    IndVars.push_back(InductionVariable(PN, Loops));
547e70829632f82de15db187845666aaca6e04b792Chris Lattner  // AfterPHIIt now points to first nonphi instruction...
556148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner
56394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  // If there are no phi nodes in this basic block, there can't be indvars...
576148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  if (IndVars.empty()) return Changed;
586148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner
596148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  // Loop over the induction variables, looking for a cannonical induction
606148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  // variable, and checking to make sure they are not all unknown induction
616148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  // variables.
626148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  //
636148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  bool FoundIndVars = false;
646148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  InductionVariable *Cannonical = 0;
656148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  for (unsigned i = 0; i < IndVars.size(); ++i) {
666148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner    if (IndVars[i].InductionType == InductionVariable::Cannonical)
676148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner      Cannonical = &IndVars[i];
686148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner    if (IndVars[i].InductionType != InductionVariable::Unknown)
696148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner      FoundIndVars = true;
706148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  }
716148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner
726148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  // No induction variables, bail early... don't add a cannonnical indvar
736148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  if (!FoundIndVars) return Changed;
746148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner
756148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  // Okay, we want to convert other induction variables to use a cannonical
766148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  // indvar.  If we don't have one, add one now...
776148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  if (!Cannonical) {
78394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    // Create the PHI node for the new induction variable
79394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    PHINode *PN = new PHINode(Type::UIntTy, "cann-indvar");
80394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
81394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    // Insert the phi node at the end of the other phi nodes...
827e70829632f82de15db187845666aaca6e04b792Chris Lattner    AfterPHIIt = ++Header->getInstList().insert(AfterPHIIt, PN);
83394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
84394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    // Create the increment instruction to add one to the counter...
85394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    Instruction *Add = BinaryOperator::create(Instruction::Add, PN,
86394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner                                              ConstantUInt::get(Type::UIntTy,1),
87394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner                                              "add1-indvar");
88394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
89394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    // Insert the add instruction after all of the PHI nodes...
907e70829632f82de15db187845666aaca6e04b792Chris Lattner    Header->getInstList().insert(AfterPHIIt, Add);
91394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
92394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    // Figure out which block is incoming and which is the backedge for the loop
93394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    BasicBlock *Incoming, *BackEdgeBlock;
94455889aa79e3463a4b0f2161e3d9d72a683268b6Chris Lattner    pred_iterator PI = pred_begin(Header);
95455889aa79e3463a4b0f2161e3d9d72a683268b6Chris Lattner    assert(PI != pred_end(Header) && "Loop headers should have 2 preds!");
96394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    if (Loop->contains(*PI)) {  // First pred is back edge...
97394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      BackEdgeBlock = *PI++;
98394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      Incoming      = *PI++;
99394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    } else {
100394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      Incoming      = *PI++;
101394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      BackEdgeBlock = *PI++;
102394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    }
103455889aa79e3463a4b0f2161e3d9d72a683268b6Chris Lattner    assert(PI == pred_end(Header) && "Loop headers should have 2 preds!");
104394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
105394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    // Add incoming values for the PHI node...
1061a18b7cf805fc6bfc6dc44fb66799ad577d57213Chris Lattner    PN->addIncoming(Constant::getNullValue(Type::UIntTy), Incoming);
107394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    PN->addIncoming(Add, BackEdgeBlock);
108394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
109394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    // Analyze the new induction variable...
110394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    IndVars.push_back(InductionVariable(PN, Loops));
111394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    assert(IndVars.back().InductionType == InductionVariable::Cannonical &&
112394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner           "Just inserted cannonical indvar that is not cannonical!");
113394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    Cannonical = &IndVars.back();
1143dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner    ++NumInserted;
1154753bf21a4310a20ee1454e9dce48c87a06e8d27Chris Lattner    Changed = true;
116394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  }
117394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
1185ba99bd124dc18302f527d6e2b0efd0fa866bc9eAnand Shukla  DEBUG(std::cerr << "Induction variables:\n");
119394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
120394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  // Get the current loop iteration count, which is always the value of the
121394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  // cannonical phi node...
122394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  //
123394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  PHINode *IterCount = Cannonical->Phi;
124394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
125394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  // Loop through and replace all of the auxillary induction variables with
126394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  // references to the primary induction variable...
127394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  //
128394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner  for (unsigned i = 0; i < IndVars.size(); ++i) {
129394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    InductionVariable *IV = &IndVars[i];
130f016ea4ff80c56c467247a90567dd07bddb590f3Chris Lattner
1315ba99bd124dc18302f527d6e2b0efd0fa866bc9eAnand Shukla    DEBUG(std::cerr << IV);
132f016ea4ff80c56c467247a90567dd07bddb590f3Chris Lattner
1333bf915f2a296472a6bead0502c88bf74e90ec19bChris Lattner    // Don't modify the cannonical indvar or unrecognized indvars...
1343bf915f2a296472a6bead0502c88bf74e90ec19bChris Lattner    if (IV != Cannonical && IV->InductionType != InductionVariable::Unknown) {
135394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      Instruction *Val = IterCount;
136394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      if (!isa<ConstantInt>(IV->Step) ||   // If the step != 1
137394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner          !cast<ConstantInt>(IV->Step)->equalsInt(1)) {
138697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner        std::string Name;   // Create a scale by the step value...
139394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner        if (IV->Phi->hasName()) Name = IV->Phi->getName()+"-scale";
140394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
141394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner        // If the types are not compatible, insert a cast now...
142394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner        if (Val->getType() != IV->Step->getType())
1437e70829632f82de15db187845666aaca6e04b792Chris Lattner          Val = InsertCast(Val, IV->Step->getType(), AfterPHIIt);
144394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
145394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner        Val = BinaryOperator::create(Instruction::Mul, Val, IV->Step, Name);
146394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner        // Insert the phi node at the end of the other phi nodes...
1477e70829632f82de15db187845666aaca6e04b792Chris Lattner        Header->getInstList().insert(AfterPHIIt, Val);
148394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      }
149394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
150394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      if (!isa<Constant>(IV->Start) ||   // If the start != 0
151394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner          !cast<Constant>(IV->Start)->isNullValue()) {
152697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner        std::string Name;   // Create a offset by the start value...
153394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner        if (IV->Phi->hasName()) Name = IV->Phi->getName()+"-offset";
154394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
155394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner        // If the types are not compatible, insert a cast now...
156394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner        if (Val->getType() != IV->Start->getType())
1577e70829632f82de15db187845666aaca6e04b792Chris Lattner          Val = InsertCast(Val, IV->Start->getType(), AfterPHIIt);
158394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
159394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner        Val = BinaryOperator::create(Instruction::Add, Val, IV->Start, Name);
160394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner        // Insert the phi node at the end of the other phi nodes...
1617e70829632f82de15db187845666aaca6e04b792Chris Lattner        Header->getInstList().insert(AfterPHIIt, Val);
162394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      }
163394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
164394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      // If the PHI node has a different type than val is, insert a cast now...
165394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      if (Val->getType() != IV->Phi->getType())
1667e70829632f82de15db187845666aaca6e04b792Chris Lattner        Val = InsertCast(Val, IV->Phi->getType(), AfterPHIIt);
167394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
168394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      // Replace all uses of the old PHI node with the new computed value...
169394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      IV->Phi->replaceAllUsesWith(Val);
170394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner
171394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      // Move the PHI name to it's new equivalent value...
172697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner      std::string OldName = IV->Phi->getName();
173394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      IV->Phi->setName("");
174394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      Val->setName(OldName);
1756148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner
176394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner      // Delete the old, now unused, phi node...
1777e70829632f82de15db187845666aaca6e04b792Chris Lattner      Header->getInstList().erase(IV->Phi);
1784753bf21a4310a20ee1454e9dce48c87a06e8d27Chris Lattner      Changed = true;
1793dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner      ++NumRemoved;
180394437ff7eaccfe1de92fe14d0022ca0addf3e41Chris Lattner    }
1816148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  }
1826148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner
1836148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner  return Changed;
1846148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner}
1856148c02591bd83da7b957589c4bbf6f9720d503fChris Lattner
186bd0ef77cde9c9e82f2b4ad33e4982c46274d6540Chris Lattnernamespace {
187f57b845547302d24ecb6a9e79d7bc386f761a6c9Chris Lattner  struct InductionVariableSimplify : public FunctionPass {
18896c466b06ab0c830b07329c1b16037f585ccbe40Chris Lattner    const char *getPassName() const {
18996c466b06ab0c830b07329c1b16037f585ccbe40Chris Lattner      return "Induction Variable Cannonicalize";
19096c466b06ab0c830b07329c1b16037f585ccbe40Chris Lattner    }
19196c466b06ab0c830b07329c1b16037f585ccbe40Chris Lattner
1927e70829632f82de15db187845666aaca6e04b792Chris Lattner    virtual bool runOnFunction(Function &) {
1933dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner      LoopInfo &LI = getAnalysis<LoopInfo>();
1943dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner
1953dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner      // Induction Variables live in the header nodes of loops
1963dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner      return reduce_apply_bool(LI.getTopLevelLoops().begin(),
1973dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner                               LI.getTopLevelLoops().end(),
1983dec1f272219ee1f8e1499929cdf53f5bc3c2272Chris Lattner                               std::bind1st(std::ptr_fun(TransformLoop), &LI));
199bd0ef77cde9c9e82f2b4ad33e4982c46274d6540Chris Lattner    }
200bd0ef77cde9c9e82f2b4ad33e4982c46274d6540Chris Lattner
201f57b845547302d24ecb6a9e79d7bc386f761a6c9Chris Lattner    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
2021b7f7dc4b45a900fae2e9b062d588a995935727aChris Lattner      AU.addRequired(LoopInfo::ID);
20397e52e43361e77963145b95a576db11b4d14d309Chris Lattner      AU.preservesCFG();
204bd0ef77cde9c9e82f2b4ad33e4982c46274d6540Chris Lattner    }
205bd0ef77cde9c9e82f2b4ad33e4982c46274d6540Chris Lattner  };
206793c6b80d3e322c3fefb3c7314b054c7880d1691Chris Lattner}
207793c6b80d3e322c3fefb3c7314b054c7880d1691Chris Lattner
208bd0ef77cde9c9e82f2b4ad33e4982c46274d6540Chris LattnerPass *createIndVarSimplifyPass() {
209bd0ef77cde9c9e82f2b4ad33e4982c46274d6540Chris Lattner  return new InductionVariableSimplify();
210793c6b80d3e322c3fefb3c7314b054c7880d1691Chris Lattner}
211bd0ef77cde9c9e82f2b4ad33e4982c46274d6540Chris Lattner
212