diff --git a/include/llvm/Analysis/InductionVariable.h b/include/llvm/Analysis/InductionVariable.h new file mode 100644 index 00000000000..02fa6deedd5 --- /dev/null +++ b/include/llvm/Analysis/InductionVariable.h @@ -0,0 +1,53 @@ +//===- llvm/Analysis/InductionVariable.h - Induction variable ----*- C++ -*--=// +// +// This interface is used to identify and classify induction variables that +// exist in the program. Induction variables must contain a PHI node that +// exists in a loop header. Because of this, they are identified an managed by +// this PHI node. +// +// Induction variables are classified into a type. Knowing that an induction +// variable is of a specific type can constrain the values of the start and +// step. For example, a SimpleLinear induction variable must have a start and +// step values that are constants. +// +// Induction variables can be created with or without loop information. If no +// loop information is available, induction variables cannot be recognized to be +// more than SimpleLinear variables. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_INDUCTIONVARIABLE_H +#define LLVM_ANALYSIS_INDUCTIONVARIABLE_H + +class Value; +class PHINode; +class Instruction; +namespace cfg { class LoopInfo; class Loop; } + +class InductionVariable { +public: + enum iType { // Identify the type of this induction variable + Cannonical, // Starts at 0, counts by 1 + SimpleLinear, // Simple linear: Constant start, constant step + Linear, // General linear: loop invariant start, and step + Unknown, // Unknown type. Start & Step are null + } InductionType; + + Value *Start, *Step; // Start and step expressions for this indvar + PHINode *Phi; // The PHI node that corresponds to this indvar +public: + + // Create an induction variable for the specified value. If it is a PHI, and + // if it's recognizable, classify it and fill in instance variables. + // + InductionVariable(Instruction *V, cfg::LoopInfo *LoopInfo = 0); + + + // Classify Induction + static enum iType Classify(const Value *Start, const Value *Step, + const cfg::Loop *L = 0); + + +}; + +#endif diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h new file mode 100644 index 00000000000..3a202265203 --- /dev/null +++ b/include/llvm/Analysis/LoopInfo.h @@ -0,0 +1,107 @@ +//===- llvm/Analysis/LoopInfo.h - Natural Loop Calculator --------*- C++ -*--=// +// +// This file defines the LoopInfo class that is used to identify natural loops +// and determine the loop depth of various nodes of the CFG. Note that the +// loops identified may actually be several natural loops that share the same +// header node... not just a single natural loop. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_LOOP_INFO_H +#define LLVM_ANALYSIS_LOOP_INFO_H + +#include +#include +#include +class BasicBlock; + +namespace cfg { + class DominatorSet; + class LoopInfo; + +//===----------------------------------------------------------------------===// +// Loop class - Instances of this class are used to represent loops that are +// detected in the flow graph +// +class Loop { + Loop *ParentLoop; + vector Blocks; // First entry is the header node + vector SubLoops; // Loops contained entirely within this one + unsigned LoopDepth; // Nesting depth of this loop + + Loop(const Loop &); // DO NOT IMPLEMENT + const Loop &operator=(const Loop &); // DO NOT IMPLEMENT +public: + + inline unsigned getLoopDepth() const { return LoopDepth; } + inline const BasicBlock *getHeader() const { return Blocks.front(); } + + // contains - Return true of the specified basic block is in this loop + bool contains(const BasicBlock *BB) const; + + // getSubLoops - Return the loops contained entirely within this loop + inline const vector &getSubLoops() const { return SubLoops; } + inline const vector &getBlocks() const { return Blocks; } + +private: + friend class LoopInfo; + inline Loop(const BasicBlock *BB) { Blocks.push_back(BB); LoopDepth = 0; } + + void setLoopDepth(unsigned Level) { + LoopDepth = Level; + for (unsigned i = 0; i < SubLoops.size(); ++i) + SubLoops[i]->setLoopDepth(Level+1); + } +}; + + + +//===----------------------------------------------------------------------===// +// LoopInfo - This class builds and contains all of the top level loop +// structures in the specified method. +// +class LoopInfo { + // BBMap - Mapping of basic blocks to the inner most loop they occur in + map BBMap; + vector TopLevelLoops; +public: + // LoopInfo ctor - Calculate the natural loop information for a CFG + LoopInfo(const DominatorSet &DS); + + const vector &getTopLevelLoops() const { return TopLevelLoops; } + + // getLoopFor - Return the inner most loop that BB lives in. If a basic block + // is in no loop (for example the entry node), null is returned. + // + const Loop *getLoopFor(const BasicBlock *BB) const { + map::const_iterator I = BBMap.find(BB); + return I != BBMap.end() ? I->second : 0; + } + inline const Loop *operator[](const BasicBlock *BB) const { + return getLoopFor(BB); + } + + // getLoopDepth - Return the loop nesting level of the specified block... + unsigned getLoopDepth(const BasicBlock *BB) const { + const Loop *L = getLoopFor(BB); + return L ? L->getLoopDepth() : 0; + } + +#if 0 + // isLoopHeader - True if the block is a loop header node + bool isLoopHeader(const BasicBlock *BB) const { + return getLoopFor(BB)->getHeader() == BB; + } + // isLoopEnd - True if block jumps to loop entry + bool isLoopEnd(const BasicBlock *BB) const; + // isLoopExit - True if block is the loop exit + bool isLoopExit(const BasicBlock *BB) const; +#endif + +private: + Loop *ConsiderForLoop(const BasicBlock *BB, const DominatorSet &DS); +}; + +} // End namespace cfg + +#endif diff --git a/lib/Analysis/InductionVariable.cpp b/lib/Analysis/InductionVariable.cpp new file mode 100644 index 00000000000..706c778a4da --- /dev/null +++ b/lib/Analysis/InductionVariable.cpp @@ -0,0 +1,138 @@ +//===- llvm/Analysis/InductionVariable.h - Induction variable ----*- C++ -*--=// +// +// This interface is used to identify and classify induction variables that +// exist in the program. Induction variables must contain a PHI node that +// exists in a loop header. Because of this, they are identified an managed by +// this PHI node. +// +// Induction variables are classified into a type. Knowing that an induction +// variable is of a specific type can constrain the values of the start and +// step. For example, a SimpleLinear induction variable must have a start and +// step values that are constants. +// +// Induction variables can be created with or without loop information. If no +// loop information is available, induction variables cannot be recognized to be +// more than SimpleLinear variables. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/InductionVariable.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/Expressions.h" +#include "llvm/iOther.h" +#include "llvm/Type.h" +#include "llvm/ConstPoolVals.h" + +using analysis::ExprType; + + +static bool isLoopInvariant(const Value *V, const cfg::Loop *L) { + if (isa(V) || isa(V) || isa(V)) + return true; + + const Instruction *I = cast(V); + const BasicBlock *BB = I->getParent(); + + return !L->contains(BB); +} + +enum InductionVariable::iType +InductionVariable::Classify(const Value *Start, const Value *Step, + const cfg::Loop *L = 0) { + // Check for cannonical and simple linear expressions now... + if (ConstPoolInt *CStart = dyn_cast(Start)) + if (ConstPoolInt *CStep = dyn_cast(Step)) { + if (CStart->equalsInt(0) && CStep->equalsInt(1)) + return Cannonical; + else + return SimpleLinear; + } + + // Without loop information, we cannot do any better, so bail now... + if (L == 0) return Unknown; + + if (isLoopInvariant(Start, L) && isLoopInvariant(Step, L)) + return Linear; + return Unknown; +} + +// Create an induction variable for the specified value. If it is a PHI, and +// if it's recognizable, classify it and fill in instance variables. +// +InductionVariable::InductionVariable(Instruction *V, cfg::LoopInfo *LoopInfo) { + InductionType = Unknown; // Assume the worst + + // If this instruction is not a PHINode, it can't be an induction variable. + // Also, if the PHI node has more than two predecessors, we don't know how to + // handle it. + // + Phi = dyn_cast(V); + if (!Phi || Phi->getNumIncomingValues() != 2) return; + + // If we have loop information, make sure that this PHI node is in the header + // of a loop... + // + const cfg::Loop *L = LoopInfo ? LoopInfo->getLoopFor(Phi->getParent()) : 0; + if (L && L->getHeader() != Phi->getParent()) + return; + + Value *V1 = Phi->getIncomingValue(0); + Value *V2 = Phi->getIncomingValue(1); + + if (L == 0) { // No loop information? Base everything on expression analysis + ExprType E1 = analysis::ClassifyExpression(V1); + ExprType E2 = analysis::ClassifyExpression(V2); + + if (E1.ExprTy > E2.ExprTy) // Make E1 be the simpler expression + swap(E1, E2); + + // E1 must be a constant incoming value, and E2 must be a linear expression + // with respect to the PHI node. + // + if (E1.ExprTy > ExprType::Constant || E2.ExprTy != ExprType::Linear || + E2.Var != Phi) + return; + + // Okay, we have found an induction variable. Save the start and step values + const Type *ETy = Phi->getType(); + if (ETy->isPointerType()) ETy = Type::ULongTy; + + Start = (Value*)(E1.Offset ? E1.Offset : ConstPoolInt::get(ETy, 0)); + Step = (Value*)(E2.Offset ? E2.Offset : ConstPoolInt::get(ETy, 0)); + } else { + // Okay, at this point, we know that we have loop information... + + // Make sure that V1 is the incoming value, and V2 is from the backedge of + // the loop. + if (L->contains(Phi->getIncomingBlock(0))) // Wrong order. Swap now. + swap(V1, V2); + + Start = V1; // We know that Start has to be loop invariant... + Step = 0; + + if (V2 == Phi) { // referencing the PHI directly? Must have zero step + Step = ConstPoolVal::getNullConstant(Phi->getType()); + } else if (BinaryOperator *I = dyn_cast(V2)) { + // TODO: This could be much better... + if (I->getOpcode() == Instruction::Add) { + if (I->getOperand(0) == Phi) + Step = I->getOperand(1); + else if (I->getOperand(1) == Phi) + Step = I->getOperand(0); + } + } + + if (Step == 0) { // Unrecognized step value... + ExprType StepE = analysis::ClassifyExpression(V2); + if (StepE.ExprTy != ExprType::Linear || + StepE.Var != Phi) return; + + const Type *ETy = Phi->getType(); + if (ETy->isPointerType()) ETy = Type::ULongTy; + Step = (Value*)(StepE.Offset ? StepE.Offset : ConstPoolInt::get(ETy, 0)); + } + } + + // Classify the induction variable type now... + InductionType = InductionVariable::Classify(Start, Step, L); +} diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp new file mode 100644 index 00000000000..a240ec8b8ba --- /dev/null +++ b/lib/Analysis/LoopInfo.cpp @@ -0,0 +1,81 @@ +//===- LoopInfo.cpp - Natural Loop Calculator -------------------------------=// +// +// This file defines the LoopInfo class that is used to identify natural loops +// and determine the loop depth of various nodes of the CFG. Note that the +// loops identified may actually be several natural loops that share the same +// header node... not just a single natural loop. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/Support/DepthFirstIterator.h" +#include "llvm/BasicBlock.h" +#include + +bool cfg::Loop::contains(const BasicBlock *BB) const { + return find(Blocks.begin(), Blocks.end(), BB) != Blocks.end(); +} + +cfg::LoopInfo::LoopInfo(const DominatorSet &DS) { + const BasicBlock *RootNode = DS.getRoot(); + + for (df_iterator NI = df_begin(RootNode), + NE = df_end(RootNode); NI != NE; ++NI) + if (Loop *L = ConsiderForLoop(*NI, DS)) + TopLevelLoops.push_back(L); + + for (unsigned i = 0; i < TopLevelLoops.size(); ++i) + TopLevelLoops[i]->setLoopDepth(1); +} + +cfg::Loop *cfg::LoopInfo::ConsiderForLoop(const BasicBlock *BB, + const DominatorSet &DS) { + if (BBMap.find(BB) != BBMap.end()) return 0; // Havn't processed this node? + + vector TodoStack; + + // Scan the predecessors of BB, checking to see if BB dominates any of + // them. + for (BasicBlock::pred_const_iterator I = BB->pred_begin(), + E = BB->pred_end(); I != E; ++I) + if (DS.dominates(BB, *I)) // If BB dominates it's predecessor... + TodoStack.push_back(*I); + + if (TodoStack.empty()) return 0; // Doesn't dominate any predecessors... + + // Create a new loop to represent this basic block... + Loop *L = new Loop(BB); + BBMap[BB] = L; + + while (!TodoStack.empty()) { // Process all the nodes in the loop + const BasicBlock *X = TodoStack.back(); + TodoStack.pop_back(); + + if (!L->contains(X)) { // As of yet unprocessed?? + L->Blocks.push_back(X); + + // Add all of the predecessors of X to the end of the work stack... + TodoStack.insert(TodoStack.end(), X->pred_begin(), X->pred_end()); + } + } + + // Add the basic blocks that comprise this loop to the BBMap so that this + // loop can be found for them. Also check subsidary basic blocks to see if + // they start subloops of their own. + // + for (vector::reverse_iterator I = L->Blocks.rbegin(), + E = L->Blocks.rend(); I != E; ++I) { + + // Check to see if this block starts a new loop + if (Loop *NewLoop = ConsiderForLoop(*I, DS)) { + L->SubLoops.push_back(NewLoop); + NewLoop->ParentLoop = L; + } + + if (BBMap.find(*I) == BBMap.end()) + BBMap.insert(make_pair(*I, L)); + } + + return L; +}