00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef LLVM_ANALYSIS_REGION_ITERATOR_H
00013 #define LLVM_ANALYSIS_REGION_ITERATOR_H
00014
00015 #include "llvm/ADT/GraphTraits.h"
00016 #include "llvm/ADT/SmallPtrSet.h"
00017 #include "llvm/ADT/PointerIntPair.h"
00018 #include "llvm/Analysis/RegionInfo.h"
00019 #include "llvm/Support/CFG.h"
00020 #include "llvm/Support/raw_ostream.h"
00021
00022 namespace llvm {
00023
00024
00025
00032 template<class NodeType>
00033 class RNSuccIterator : public std::iterator<std::forward_iterator_tag,
00034 NodeType, ptrdiff_t>
00035 {
00036 typedef std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> super;
00037
00038 enum ItMode{
00039
00040
00041 ItBB,
00042
00043
00044 ItRgBegin,
00045 ItRgEnd
00046 };
00047
00049 PointerIntPair<NodeType*, 2, enum ItMode> Node;
00050
00052 succ_iterator BItor;
00053
00056 void advanceRegionSucc() {
00057 assert(Node.getInt() == ItRgBegin && "cant advance region succ!");
00058 Node.setInt(ItRgEnd);
00059 }
00060
00061 NodeType* getNode() const{ return Node.getPointer(); }
00062
00065 bool isRegionMode() const { return Node.getInt() != ItBB; }
00066
00070 RegionNode* getISucc(BasicBlock* BB) const {
00071 RegionNode* succ = getNode()->getParent()->getChildNode(BB);
00072 assert(succ && "bb not in region or enter sub region!");
00073 return succ;
00074 }
00075
00078 inline BasicBlock* getRegionSucc() const {
00079 assert(Node.getInt() == ItRgBegin && "cant get region succ!");
00080 return getNode()->template getNodeAs<Region>()->getExit();
00081 }
00082
00084 inline bool reachExit(BasicBlock* BB) const {
00085 return getNode()->getParent()->getExit() == BB;
00086 }
00087 public:
00088 typedef RNSuccIterator<NodeType> _Self;
00089
00090 typedef typename super::pointer pointer;
00091
00094 inline RNSuccIterator(NodeType* node)
00095 : Node(node, node->isRegionNode()?ItRgBegin:ItBB),
00096 BItor(node->getBB()->getTerminator()) {
00097
00098 if (!isRegionMode() && reachExit(*BItor))
00099 ++BItor;
00100 else if (isRegionMode() && reachExit(getRegionSucc()))
00101
00102 advanceRegionSucc();
00103 }
00104
00106 inline RNSuccIterator(NodeType* node, bool)
00107 : Node(node, node->isRegionNode()?ItRgEnd:ItBB),
00108 BItor(node->getBB()->getTerminator(), true) {}
00109
00110 inline bool operator==(const _Self& x) const {
00111 assert(isRegionMode() == x.isRegionMode() && "broken iterator!");
00112
00113
00114 return isRegionMode() ?
00115 (Node.getInt() == x.Node.getInt()) : (BItor == x.BItor);
00116 }
00117
00118 inline bool operator!=(const _Self& x) const { return !operator==(x); }
00119
00120 inline pointer operator*() const {
00121 BasicBlock* BB = isRegionMode()?getRegionSucc():*BItor;
00122
00123
00124
00125 assert(!reachExit(BB) && "iterator out of range!");
00126 return getISucc(BB);
00127 }
00128
00129 inline _Self& operator++() {
00130 if(isRegionMode())
00131 advanceRegionSucc();
00132 else {
00133
00134 ++BItor;
00135
00136 if (BItor.index_is_valid(BItor.getSuccessorIndex()) &&
00137 reachExit(*BItor))
00138 ++BItor;
00139 }
00140 return *this;
00141 }
00142
00143 inline _Self operator++(int) {
00144 _Self tmp = *this;
00145 ++*this;
00146 return tmp;
00147 }
00148
00149 inline const _Self &operator=(const _Self &I) {
00150 if (this != &I) {
00151 assert(getNode()->getParent() == I.getNode()->getParent() &&
00152 "Cannot assign iterators to two different regions!");
00153 Node = I.Node;
00154 BItor = I.BItor;
00155 }
00156 return *this;
00157 }
00158
00159 };
00160
00161
00162
00165 template<class NodeType>
00166 class RNSuccIterator<FlatIt<NodeType> >
00167 : public std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t>
00168 {
00169 typedef std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> super;
00170 NodeType* Node;
00171 succ_iterator Itor;
00172
00176 RegionNode* getBBNode(BasicBlock* BB) const {
00177 RegionNode* ret = Node->getItRegion()->getBBNode(BB);
00178 Node->propItRegionTo(ret);
00179 return ret;
00180 }
00181
00182 public:
00183 typedef RNSuccIterator<FlatIt<NodeType> > _Self;
00184 typedef typename super::pointer pointer;
00185
00190 inline RNSuccIterator(NodeType* node) : Node(node),
00191 Itor(node->template getNodeAs<BasicBlock>()->getTerminator()) {
00192 assert(!Node->isRegionNode() &&
00193 "unexpect a region node in flat iterating mode!");
00194
00195 if (Node->getItRegion()->getExit() == *Itor) ++Itor;
00196 }
00198 inline RNSuccIterator(NodeType* node, bool) : Node(node),
00199
00200 Itor(node->template getNodeAs<BasicBlock>()->getTerminator(), true) {}
00201
00202 inline bool operator==(const _Self& x) const {
00203 assert(Node->getItRegion() == x.Node->getItRegion() &&
00204 "cant compare iterators of different regions!");
00205 return Itor == x.Itor;
00206 }
00207 inline bool operator!=(const _Self& x) const { return !operator==(x); }
00208
00209 inline pointer operator*() const {
00210 BasicBlock* BB = *Itor;
00211
00212
00213 assert(Node->getItRegion()->getExit()!=BB && "iterator out of range!");
00214
00218 return getBBNode(BB);
00219 }
00220
00221 inline _Self& operator++() {
00222 ++Itor;
00223
00224 if (Itor.index_is_valid(Itor.getSuccessorIndex())
00225 && Node->getItRegion()->getExit() == *Itor)
00226 ++Itor;
00227 return *this;
00228 }
00229
00230 inline _Self operator++(int) {
00231 _Self tmp = *this;
00232 ++*this;
00233 return tmp;
00234 }
00235
00236 inline const _Self &operator=(const _Self &I) {
00237 if (this != &I) {
00238 assert(Node->getParent() == I.Node->getParent() &&
00239 "Cannot assign iterators to two different regions!");
00240 Node = I.Node;
00241 Itor = I.Itor;
00242 }
00243 return *this;
00244 }
00245 };
00246
00247 template<class NodeType>
00248 inline RNSuccIterator<NodeType> succ_begin(NodeType* Node) {
00249 return RNSuccIterator<NodeType>(Node);
00250 }
00251
00252 template<class NodeType>
00253 inline RNSuccIterator<NodeType> succ_end(NodeType* Node) {
00254 return RNSuccIterator<NodeType>(Node, true);
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 #define RegionNodeGraphTraits(NodeT) \
00266 template<> struct GraphTraits<NodeT*> { \
00267 typedef NodeT NodeType; \
00268 typedef RNSuccIterator<NodeType> ChildIteratorType; \
00269 static NodeType *getEntryNode(NodeType* N) { return N; } \
00270 static inline ChildIteratorType child_begin(NodeType *N) { \
00271 return RNSuccIterator<NodeType>(N); \
00272 } \
00273 static inline ChildIteratorType child_end(NodeType *N) { \
00274 return RNSuccIterator<NodeType>(N, true); \
00275 } \
00276 }; \
00277 template<> struct GraphTraits<FlatIt<NodeT*> > { \
00278 typedef NodeT NodeType; \
00279 typedef RNSuccIterator<FlatIt<NodeT> > ChildIteratorType; \
00280 static NodeType *getEntryNode(NodeType* N) { return N; } \
00281 static inline ChildIteratorType child_begin(NodeType *N) { \
00282 return RNSuccIterator<FlatIt<NodeType> >(N); \
00283 } \
00284 static inline ChildIteratorType child_end(NodeType *N) { \
00285 return RNSuccIterator<FlatIt<NodeType> >(N, true); \
00286 } \
00287 }
00288
00289 #define RegionGraphTraits(RegionT, NodeT) \
00290 template<> struct GraphTraits<RegionT*> \
00291 : public GraphTraits<NodeT*> { \
00292 typedef df_iterator<NodeType*> nodes_iterator; \
00293 static NodeType *getEntryNode(RegionT* R) { \
00294 return R->getGraphEntry(); \
00295 } \
00296 static nodes_iterator nodes_begin(RegionT* R) { \
00297 return nodes_iterator::begin(getEntryNode(R)); \
00298 } \
00299 static nodes_iterator nodes_end(RegionT* R) { \
00300 return nodes_iterator::end(getEntryNode(R)); \
00301 } \
00302 }; \
00303 template<> struct GraphTraits<FlatIt<RegionT*> > \
00304 : public GraphTraits<FlatIt<NodeT*> > { \
00305 typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false, \
00306 GraphTraits<FlatIt<NodeType*> > > nodes_iterator; \
00307 static NodeType *getEntryNode(RegionT* R) { \
00308 return R->getFlatGraphEntry(); \
00309 } \
00310 static nodes_iterator nodes_begin(RegionT* R) { \
00311 return nodes_iterator::begin(getEntryNode(R)); \
00312 } \
00313 static nodes_iterator nodes_end(RegionT* R) { \
00314 return nodes_iterator::end(getEntryNode(R)); \
00315 } \
00316 }
00317
00318 RegionNodeGraphTraits(RegionNode);
00319 RegionNodeGraphTraits(const RegionNode);
00320
00321 RegionGraphTraits(Region, RegionNode);
00322 RegionGraphTraits(const Region, const RegionNode);
00323
00324
00325
00326 }
00327
00328 #endif