#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Support/CFG.h"
-#include "llvm/Support/Streams.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
-#include <ostream>
namespace llvm {
return 0;
}
+ /// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
+ /// (Modelled after getExitingBlocks().)
+ typedef std::pair<const BlockT*,const BlockT*> Edge;
+ void getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const {
+ // Sort the blocks vector so that we can use binary search to do quick
+ // lookups.
+ SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
+ std::sort(LoopBBs.begin(), LoopBBs.end());
+
+ typedef GraphTraits<BlockT*> BlockTraits;
+ for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
+ for (typename BlockTraits::ChildIteratorType I =
+ BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
+ I != E; ++I)
+ if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
+ // Not in current loop? It must be an exit block.
+ ExitEdges.push_back(std::make_pair(*BI, *I));
+ }
+
/// getUniqueExitBlocks - Return all unique successor blocks of this loop.
/// These are the blocks _outside of the current loop_ which are branched to.
/// This assumes that loop is in canonical form.
#endif
}
- void print(std::ostream &OS, unsigned Depth = 0) const {
- OS << std::string(Depth*2, ' ') << "Loop at depth " << getLoopDepth()
+ void print(raw_ostream &OS, unsigned Depth = 0) const {
+ OS.indent(Depth*2) << "Loop at depth " << getLoopDepth()
<< " containing: ";
for (unsigned i = 0; i < getBlocks().size(); ++i) {
(*I)->print(OS, Depth+2);
}
- void print(std::ostream *O, unsigned Depth = 0) const {
- if (O) print(*O, Depth);
- }
-
void dump() const {
- print(cerr);
+ print(errs());
}
protected:
///
bool isLoopInvariant(Instruction *I) const;
- /// makeLoopInvariant - If the given value is an instruciton inside of the
+ /// makeLoopInvariant - If the given value is an instruction inside of the
/// loop and it can be hoisted, do so to make it trivially loop-invariant.
/// Return true if the value after any hoisting is loop invariant. This
/// function can be used as a slightly more aggressive replacement for
/// If InsertPt is specified, it is the point to hoist instructions to.
/// If null, the terminator of the loop preheader is used.
///
- bool makeLoopInvariant(Value *V, Instruction *InsertPt = 0) const;
+ bool makeLoopInvariant(Value *V, bool &Changed,
+ Instruction *InsertPt = 0) const;
/// makeLoopInvariant - If the given instruction is inside of the
/// loop and it can be hoisted, do so to make it trivially loop-invariant.
/// If InsertPt is specified, it is the point to hoist instructions to.
/// If null, the terminator of the loop preheader is used.
///
- bool makeLoopInvariant(Instruction *I, Instruction *InsertPt = 0) const;
+ bool makeLoopInvariant(Instruction *I, bool &Changed,
+ Instruction *InsertPt = 0) const;
/// getCanonicalInductionVariable - Check to see if the loop has a canonical
/// induction variable: an integer recurrence that starts at 0 and increments
/// isLCSSAForm - Return true if the Loop is in LCSSA form
bool isLCSSAForm() const;
+ /// isLoopSimplifyForm - Return true if the Loop is in the form that
+ /// the LoopSimplify form transforms loops to, which is sometimes called
+ /// normal form.
+ bool isLoopSimplifyForm() const;
+
private:
friend class LoopInfoBase<BasicBlock, Loop>;
explicit Loop(BasicBlock *BB) : LoopBase<BasicBlock, Loop>(BB) {}
// Debugging
- void print(std::ostream &OS, const Module* ) const {
+ void print(raw_ostream &OS) const {
for (unsigned i = 0; i < TopLevelLoops.size(); ++i)
TopLevelLoops[i]->print(OS);
#if 0
virtual void releaseMemory() { LI.releaseMemory(); }
- virtual void print(std::ostream &O, const Module* M = 0) const {
- LI.print(O, M);
- }
-
+ virtual void print(raw_ostream &O, const Module* M = 0) const;
+
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
/// removeLoop - This removes the specified top-level loop from this loop info