class PHINode;
class Instruction;
template<class N> class LoopInfoBase;
+template<class N> class LoopBase;
+
+typedef LoopBase<BasicBlock> Loop;
//===----------------------------------------------------------------------===//
-/// LoopBase class - Instances of this class are used to represent loops that are
-/// detected in the flow graph
+/// LoopBase class - Instances of this class are used to represent loops that
+/// are detected in the flow graph
///
template<class BlockT>
class LoopBase {
LoopBase<BlockT> *ParentLoop;
- std::vector<LoopBase<BlockT>*> SubLoops; // Loops contained entirely within this one
- std::vector<BlockT*> Blocks; // First entry is the header node
+ // SubLoops - Loops contained entirely within this one.
+ std::vector<LoopBase<BlockT>*> SubLoops;
+
+ // Blocks - The list of blocks in this loop. First entry is the header node.
+ std::vector<BlockT*> Blocks;
LoopBase(const LoopBase<BlockT> &); // DO NOT IMPLEMENT
- const LoopBase<BlockT> &operator=(const LoopBase<BlockT> &); // DO NOT IMPLEMENT
+ const LoopBase<BlockT>&operator=(const LoopBase<BlockT> &);// DO NOT IMPLEMENT
public:
/// Loop ctor - This creates an empty loop.
LoopBase() : ParentLoop(0) {}
delete SubLoops[i];
}
+ /// getLoopDepth - Return the nesting level of this loop. An outer-most
+ /// loop has depth 1, for consistency with loop depth values used for basic
+ /// blocks, where depth 0 is used for blocks not inside any loops.
unsigned getLoopDepth() const {
- unsigned D = 0;
- for (const LoopBase<BlockT> *CurLoop = this; CurLoop;
+ unsigned D = 1;
+ for (const LoopBase<BlockT> *CurLoop = ParentLoop; CurLoop;
CurLoop = CurLoop->ParentLoop)
++D;
return D;
block_iterator block_begin() const { return Blocks.begin(); }
block_iterator block_end() const { return Blocks.end(); }
- /// isLoopExit - True if terminator in the block can branch to another block
- /// that is outside of the current loop.
+ /// isLoopExit - True if this block can branch to another block that is
+ /// outside of the current loop.
///
bool isLoopExit(const BlockT *BB) const {
typedef GraphTraits<BlockT*> BlockTraits;
if (SI != BlockTraits::child_end(Out))
return 0; // Multiple exits from the block, must not be a preheader.
- // If there is exactly one preheader, return it. If there was zero, then Out
- // is still null.
+ // If there is exactly one preheader, return it. If there was zero, then
+ // Out is still null.
return Out;
}
// Loop over all of the PHI nodes, looking for a canonical indvar.
for (typename BlockT::iterator I = H->begin(); isa<PHINode>(I); ++I) {
PHINode *PN = cast<PHINode>(I);
- if (Instruction *Inc =
- dyn_cast<Instruction>(PN->getIncomingValueForBlock(Backedge)))
- if (Inc->getOpcode() == Instruction::Add && Inc->getOperand(0) == PN)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(Inc->getOperand(1)))
- if (CI->equalsInt(1))
- return PN;
+ if (ConstantInt *CI =
+ dyn_cast<ConstantInt>(PN->getIncomingValueForBlock(Incoming)))
+ if (CI->isNullValue())
+ if (Instruction *Inc =
+ dyn_cast<Instruction>(PN->getIncomingValueForBlock(Backedge)))
+ if (Inc->getOpcode() == Instruction::Add &&
+ Inc->getOperand(0) == PN)
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Inc->getOperand(1)))
+ if (CI->equalsInt(1))
+ return PN;
}
return 0;
}
if (BranchInst *BI = dyn_cast<BranchInst>(BackedgeBlock->getTerminator()))
if (BI->isConditional()) {
if (ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition())) {
- if (ICI->getOperand(0) == Inc)
+ if (ICI->getOperand(0) == Inc) {
if (BI->getSuccessor(0) == getHeader()) {
if (ICI->getPredicate() == ICmpInst::ICMP_NE)
return ICI->getOperand(1);
} else if (ICI->getPredicate() == ICmpInst::ICMP_EQ) {
return ICI->getOperand(1);
}
+ }
}
}
for (block_iterator BI = block_begin(), E = block_end(); BI != E; ++BI) {
BlockT *BB = *BI;
- for (typename BlockT::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
+ for (typename BlockT::iterator I = BB->begin(), E = BB->end(); I != E;++I)
for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E;
++UI) {
BlockT *UserBB = cast<Instruction>(*UI)->getParent();
UserBB = P->getIncomingBlock(OperandNo/2);
}
- // Check the current block, as a fast-path. Most values are used in the
- // same block they are defined in.
+ // Check the current block, as a fast-path. Most values are used in
+ // the same block they are defined in.
if (UserBB != BB && !LoopBBs.count(UserBB))
return false;
}
}
};
-typedef LoopBase<BasicBlock> Loop;
-
//===----------------------------------------------------------------------===//
/// LoopInfo - This class builds and contains all of the top level loop
TopLevelLoops.begin(), E = TopLevelLoops.end(); I != E; ++I)
delete *I; // Delete all of the loops...
- BBMap.clear(); // Reset internal state of analysis
+ BBMap.clear(); // Reset internal state of analysis
TopLevelLoops.clear();
}
return getLoopFor(BB);
}
- /// getLoopDepth - Return the loop nesting level of the specified block...
+ /// getLoopDepth - Return the loop nesting level of the specified block. A
+ /// depth of 0 means the block is not inside any loop.
///
unsigned getLoopDepth(const BlockT *BB) const {
const LoopBase<BlockT> *L = getLoopFor(BB);
if (!L->contains(X) && // As of yet unprocessed??
DT.dominates(EntryBlock, X)) { // X is reachable from entry block?
// Check to see if this block already belongs to a loop. If this occurs
- // then we have a case where a loop that is supposed to be a child of the
- // current loop was processed before the current loop. When this occurs,
- // this child loop gets added to a part of the current loop, making it a
- // sibling to the current loop. We have to reparent this loop.
+ // then we have a case where a loop that is supposed to be a child of
+ // the current loop was processed before the current loop. When this
+ // occurs, this child loop gets added to a part of the current loop,
+ // making it a sibling to the current loop. We have to reparent this
+ // loop.
if (LoopBase<BlockT> *SubLoop =
const_cast<LoopBase<BlockT>*>(getLoopFor(X)))
- if (SubLoop->getHeader() == X && isNotAlreadyContainedIn(SubLoop, L)) {
+ if (SubLoop->getHeader() == X && isNotAlreadyContainedIn(SubLoop, L)){
// Remove the subloop from it's current parent...
assert(SubLoop->ParentLoop && SubLoop->ParentLoop != L);
LoopBase<BlockT> *SLP = SubLoop->ParentLoop; // SubLoopParent
typename std::vector<LoopBase<BlockT>*>::iterator I =
std::find(SLP->SubLoops.begin(), SLP->SubLoops.end(), SubLoop);
- assert(I != SLP->SubLoops.end() && "SubLoop not a child of parent?");
+ assert(I != SLP->SubLoops.end() &&"SubLoop not a child of parent?");
SLP->SubLoops.erase(I); // Remove from parent...
// Add the subloop to THIS loop...
}
// Now that we have a list of all of the child loops of this loop, check to
- // see if any of them should actually be nested inside of each other. We can
- // accidentally pull loops our of their parents, so we must make sure to
+ // see if any of them should actually be nested inside of each other. We
+ // can accidentally pull loops our of their parents, so we must make sure to
// organize the loop nests correctly now.
{
std::map<BlockT*, LoopBase<BlockT>*> ContainingLoops;
MoveSiblingLoopInto(Child, ContainingLoop);
--i; // The loop got removed from the SubLoops list.
} else {
- // This is currently considered to be a top-level loop. Check to see if
- // any of the contained blocks are loop headers for subloops we have
- // already processed.
+ // This is currently considered to be a top-level loop. Check to see
+ // if any of the contained blocks are loop headers for subloops we
+ // have already processed.
for (unsigned b = 0, e = Child->Blocks.size(); b != e; ++b) {
LoopBase<BlockT> *&BlockLoop = ContainingLoops[Child->Blocks[b]];
if (BlockLoop == 0) { // Child block not processed yet...
return L;
}
- /// MoveSiblingLoopInto - This method moves the NewChild loop to live inside of
- /// the NewParent Loop, instead of being a sibling of it.
+ /// MoveSiblingLoopInto - This method moves the NewChild loop to live inside
+ /// of the NewParent Loop, instead of being a sibling of it.
void MoveSiblingLoopInto(LoopBase<BlockT> *NewChild,
LoopBase<BlockT> *NewParent) {
LoopBase<BlockT> *OldParent = NewChild->getParentLoop();
// Remove NewChild from being a child of OldParent
typename std::vector<LoopBase<BlockT>*>::iterator I =
- std::find(OldParent->SubLoops.begin(), OldParent->SubLoops.end(), NewChild);
+ std::find(OldParent->SubLoops.begin(), OldParent->SubLoops.end(),
+ NewChild);
assert(I != OldParent->SubLoops.end() && "Parent fields incorrect??");
OldParent->SubLoops.erase(I); // Remove from parent's subloops list
NewChild->ParentLoop = 0;
InsertLoopInto(NewChild, NewParent);
}
- /// InsertLoopInto - This inserts loop L into the specified parent loop. If the
- /// parent loop contains a loop which should contain L, the loop gets inserted
- /// into L instead.
+ /// InsertLoopInto - This inserts loop L into the specified parent loop. If
+ /// the parent loop contains a loop which should contain L, the loop gets
+ /// inserted into L instead.
void InsertLoopInto(LoopBase<BlockT> *L, LoopBase<BlockT> *Parent) {
BlockT *LHeader = L->getHeader();
- assert(Parent->contains(LHeader) && "This loop should not be inserted here!");
+ assert(Parent->contains(LHeader) &&
+ "This loop should not be inserted here!");
// Check to see if it belongs in a child loop...
for (unsigned i = 0, e = Parent->SubLoops.size(); i != e; ++i)
return LI->getLoopFor(BB);
}
- /// getLoopDepth - Return the loop nesting level of the specified block...
+ /// getLoopDepth - Return the loop nesting level of the specified block. A
+ /// depth of 0 means the block is not inside any loop.
///
inline unsigned getLoopDepth(const BasicBlock *BB) const {
return LI->getLoopDepth(BB);