diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h index 0828e0777c0..3fb33d4b6de 100644 --- a/include/llvm/BasicBlock.h +++ b/include/llvm/BasicBlock.h @@ -24,6 +24,7 @@ #include "llvm/Value.h" // Get the definition of Value #include "llvm/ValueHolder.h" +#include "llvm/CFGdecls.h" class Instruction; class Method; @@ -42,6 +43,11 @@ private : void setParent(Method *parent); public: + typedef cfg::succ_iterator succ_iterator; // Include CFG.h to use these + typedef cfg::pred_iterator pred_iterator; + typedef cfg::succ_const_iterator succ_const_iterator; + typedef cfg::pred_const_iterator pred_const_iterator; + BasicBlock(const string &Name = "", Method *Parent = 0); ~BasicBlock(); diff --git a/include/llvm/CFG.h b/include/llvm/CFG.h index 3195607c59d..7ddfbbf1cc4 100644 --- a/include/llvm/CFG.h +++ b/include/llvm/CFG.h @@ -28,144 +28,10 @@ // Interface //===----------------------------------------------------------------------===// +#include "llvm/CFGdecls.h" // See this file for concise interface info + namespace cfg { -//===--------------------------------------------------------------------===// -// Predecessor iterator code -//===--------------------------------------------------------------------===// -// -// This is used to figure out what basic blocks we could be coming from. -// - -// Forward declare iterator class template... -template class PredIterator; - -typedef PredIterator pred_iterator; -typedef PredIterator pred_const_iterator; - -inline pred_iterator pred_begin( BasicBlock *BB); -inline pred_const_iterator pred_begin(const BasicBlock *BB); -inline pred_iterator pred_end ( BasicBlock *BB); -inline pred_const_iterator pred_end (const BasicBlock *BB); - - -//===--------------------------------------------------------------------===// -// Successor iterator code -//===--------------------------------------------------------------------===// -// -// This is used to figure out what basic blocks we could be going to... -// - -// Forward declare iterator class template... -template class SuccIterator; - -typedef SuccIterator succ_iterator; -typedef SuccIterator succ_const_iterator; - -inline succ_iterator succ_begin( BasicBlock *BB); -inline succ_const_iterator succ_begin(const BasicBlock *BB); -inline succ_iterator succ_end ( BasicBlock *BB); -inline succ_const_iterator succ_end (const BasicBlock *BB); - - -//===--------------------------------------------------------------------===// -// Depth First CFG iterator code -//===--------------------------------------------------------------------===// -// -// This is used to visit basic blocks in a method in either depth first, or -// reverse depth first ordering, depending on the value passed to the df_begin -// method. -// - -// Forward declare iterator class template... -template class DFIterator; - -typedef DFIterator df_iterator; -typedef DFIterator df_const_iterator; - -inline df_iterator df_begin( Method *BB, bool Reverse = false); -inline df_const_iterator df_begin(const Method *BB, bool Reverse = false); -inline df_iterator df_end ( Method *BB); -inline df_const_iterator df_end (const Method *BB); - -inline df_iterator df_begin( BasicBlock *BB, bool Reverse = false); -inline df_const_iterator df_begin(const BasicBlock *BB, bool Reverse = false); -inline df_iterator df_end ( BasicBlock *BB); -inline df_const_iterator df_end (const BasicBlock *BB); - - -//===--------------------------------------------------------------------===// -// Post Order CFG iterator code -//===--------------------------------------------------------------------===// -// -// This is used to visit basic blocks in a method in standard post order. -// - -// Forward declare iterator class template... -template class POIterator; - -typedef POIterator po_iterator; -typedef POIterator po_const_iterator; - -inline po_iterator po_begin( Method *BB); -inline po_const_iterator po_begin(const Method *BB); -inline po_iterator po_end ( Method *BB); -inline po_const_iterator po_end (const Method *BB); - -inline po_iterator po_begin( BasicBlock *BB); -inline po_const_iterator po_begin(const BasicBlock *BB); -inline po_iterator po_end ( BasicBlock *BB); -inline po_const_iterator po_end (const BasicBlock *BB); - - -//===--------------------------------------------------------------------===// -// Reverse Post Order CFG iterator code -//===--------------------------------------------------------------------===// -// -// This is used to visit basic blocks in a method in reverse post order. This -// class is awkward to use because I don't know a good incremental algorithm to -// computer RPO from a graph. Because of this, the construction of the -// ReversePostOrderTraversal object is expensive (it must walk the entire graph -// with a postorder iterator to build the data structures). The moral of this -// story is: Don't create more ReversePostOrderTraversal classes than neccesary. -// -// This class should be used like this: -// { -// cfg::ReversePostOrderTraversal RPOT(MethodPtr); // Expensive to create -// for (cfg::rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) { -// ... -// } -// for (cfg::rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) { -// ... -// } -// } -// - -//typedef reverse_iterator::const_iterator> -// rpo_const_iterator; -typedef reverse_iterator::iterator> rpo_iterator; - -class ReversePostOrderTraversal { - vector Blocks; // Block list in normal PO order - void Initialize(BasicBlock *BB); // Implemented down below -public: - inline ReversePostOrderTraversal(Method *M) { - Initialize(M->getBasicBlocks().front()); - } - inline ReversePostOrderTraversal(BasicBlock *BB) { - Initialize(BB); - } - - // Because we want a reverse post order, use reverse iterators from the vector - inline rpo_iterator begin() { return Blocks.rbegin(); } - inline rpo_iterator end() { return Blocks.rend(); } -}; - - //===----------------------------------------------------------------------===// // Implementation //===----------------------------------------------------------------------===// @@ -496,9 +362,24 @@ inline po_const_iterator po_end (const BasicBlock *BB) { //===----------------------------------------------------------------------===// // Reverse Post Order CFG iterator code // -void ReversePostOrderTraversal::Initialize(BasicBlock *BB) { - copy(po_begin(BB), po_end(BB), back_inserter(Blocks)); -} + +class ReversePostOrderTraversal { + vector Blocks; // Block list in normal PO order + inline void Initialize(BasicBlock *BB) { + copy(po_begin(BB), po_end(BB), back_inserter(Blocks)); + } +public: + inline ReversePostOrderTraversal(Method *M) { + Initialize(M->getBasicBlocks().front()); + } + inline ReversePostOrderTraversal(BasicBlock *BB) { + Initialize(BB); + } + + // Because we want a reverse post order, use reverse iterators from the vector + inline rpo_iterator begin() { return Blocks.rbegin(); } + inline rpo_iterator end() { return Blocks.rend(); } +}; } // End namespace cfg diff --git a/include/llvm/CFGdecls.h b/include/llvm/CFGdecls.h new file mode 100644 index 00000000000..32007d89f6f --- /dev/null +++ b/include/llvm/CFGdecls.h @@ -0,0 +1,147 @@ +//===-- llvm/CFGdecls.h - CFG forward declarations ---------------*- C++ -*--=// +// +// This file contains forward declarations for CFG functions and data +// structures. This is used to reduce compile time dependencies among files. +// Any users of these functions must include CFG.h to get their full +// definitions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CFG_DECLS_H +#define LLVM_CFG_DECLS_H + +#include "llvm/Value.h" +class TerminatorInst; +class BasicBlock; +class Method; + +//===----------------------------------------------------------------------===// +// Interface +//===----------------------------------------------------------------------===// + +namespace cfg { + +//===--------------------------------------------------------------------===// +// Predecessor iterator code +//===--------------------------------------------------------------------===// +// +// This is used to figure out what basic blocks we could be coming from. +// + +// Forward declare iterator class template... +template class PredIterator; + +typedef PredIterator pred_iterator; +typedef PredIterator pred_const_iterator; + +inline pred_iterator pred_begin( BasicBlock *BB); +inline pred_const_iterator pred_begin(const BasicBlock *BB); +inline pred_iterator pred_end ( BasicBlock *BB); +inline pred_const_iterator pred_end (const BasicBlock *BB); + + +//===--------------------------------------------------------------------===// +// Successor iterator code +//===--------------------------------------------------------------------===// +// +// This is used to figure out what basic blocks we could be going to... +// + +// Forward declare iterator class template... +template class SuccIterator; + +typedef SuccIterator succ_iterator; +typedef SuccIterator succ_const_iterator; + +inline succ_iterator succ_begin( BasicBlock *BB); +inline succ_const_iterator succ_begin(const BasicBlock *BB); +inline succ_iterator succ_end ( BasicBlock *BB); +inline succ_const_iterator succ_end (const BasicBlock *BB); + + +//===--------------------------------------------------------------------===// +// Depth First CFG iterator code +//===--------------------------------------------------------------------===// +// +// This is used to visit basic blocks in a method in either depth first, or +// reverse depth first ordering, depending on the value passed to the df_begin +// method. +// + +// Forward declare iterator class template... +template class DFIterator; + +typedef DFIterator df_iterator; +typedef DFIterator df_const_iterator; + +inline df_iterator df_begin( Method *M, bool Reverse = false); +inline df_const_iterator df_begin(const Method *M, bool Reverse = false); +inline df_iterator df_end ( Method *M); +inline df_const_iterator df_end (const Method *M); + +inline df_iterator df_begin( BasicBlock *BB, bool Reverse = false); +inline df_const_iterator df_begin(const BasicBlock *BB, bool Reverse = false); +inline df_iterator df_end ( BasicBlock *BB); +inline df_const_iterator df_end (const BasicBlock *BB); + + +//===--------------------------------------------------------------------===// +// Post Order CFG iterator code +//===--------------------------------------------------------------------===// +// +// This is used to visit basic blocks in a method in standard post order. +// + +// Forward declare iterator class template... +template class POIterator; + +typedef POIterator po_iterator; +typedef POIterator po_const_iterator; + +inline po_iterator po_begin( Method *M); +inline po_const_iterator po_begin(const Method *M); +inline po_iterator po_end ( Method *M); +inline po_const_iterator po_end (const Method *M); + +inline po_iterator po_begin( BasicBlock *BB); +inline po_const_iterator po_begin(const BasicBlock *BB); +inline po_iterator po_end ( BasicBlock *BB); +inline po_const_iterator po_end (const BasicBlock *BB); + + +//===--------------------------------------------------------------------===// +// Reverse Post Order CFG iterator code +//===--------------------------------------------------------------------===// +// +// This is used to visit basic blocks in a method in reverse post order. This +// class is awkward to use because I don't know a good incremental algorithm to +// computer RPO from a graph. Because of this, the construction of the +// ReversePostOrderTraversal object is expensive (it must walk the entire graph +// with a postorder iterator to build the data structures). The moral of this +// story is: Don't create more ReversePostOrderTraversal classes than neccesary. +// +// This class should be used like this: +// { +// cfg::ReversePostOrderTraversal RPOT(MethodPtr); // Expensive to create +// for (cfg::rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) { +// ... +// } +// for (cfg::rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) { +// ... +// } +// } +// + +//typedef reverse_iterator::const_iterator> +// rpo_const_iterator; +typedef reverse_iterator::iterator> rpo_iterator; + +class ReversePostOrderTraversal; + +} // End namespace cfg + +#endif