00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef LLVM_INTERVAL_ITERATOR_H
00034 #define LLVM_INTERVAL_ITERATOR_H
00035
00036 #include "llvm/Analysis/IntervalPartition.h"
00037 #include "llvm/Function.h"
00038 #include "llvm/Support/CFG.h"
00039 #include <stack>
00040 #include <set>
00041 #include <algorithm>
00042
00043 namespace llvm {
00044
00045
00046
00047
00048
00049 inline BasicBlock *getNodeHeader(BasicBlock *BB) { return BB; }
00050 inline BasicBlock *getNodeHeader(Interval *I) { return I->getHeaderNode(); }
00051
00052
00053
00054
00055
00056 inline BasicBlock *getSourceGraphNode(Function *, BasicBlock *BB) {
00057 return BB;
00058 }
00059 inline Interval *getSourceGraphNode(IntervalPartition *IP, BasicBlock *BB) {
00060 return IP->getBlockInterval(BB);
00061 }
00062
00063
00064
00065
00066
00067
00068 inline void addNodeToInterval(Interval *Int, BasicBlock *BB) {
00069 Int->Nodes.push_back(BB);
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079 inline void addNodeToInterval(Interval *Int, Interval *I) {
00080
00081 copy(I->Nodes.begin(), I->Nodes.end(), back_inserter(Int->Nodes));
00082 }
00083
00084
00085
00086
00087
00088 template<class NodeTy, class OrigContainer_t, class GT = GraphTraits<NodeTy*>,
00089 class IGT = GraphTraits<Inverse<NodeTy*> > >
00090 class IntervalIterator {
00091 std::stack<std::pair<Interval*, typename Interval::succ_iterator> > IntStack;
00092 std::set<BasicBlock*> Visited;
00093 OrigContainer_t *OrigContainer;
00094 bool IOwnMem;
00095
00096 public:
00097 typedef IntervalIterator<NodeTy, OrigContainer_t> _Self;
00098 typedef std::forward_iterator_tag iterator_category;
00099
00100 IntervalIterator() {}
00101 IntervalIterator(Function *M, bool OwnMemory) : IOwnMem(OwnMemory) {
00102 OrigContainer = M;
00103 if (!ProcessInterval(&M->front())) {
00104 assert(0 && "ProcessInterval should never fail for first interval!");
00105 }
00106 }
00107
00108 IntervalIterator(IntervalPartition &IP, bool OwnMemory) : IOwnMem(OwnMemory) {
00109 OrigContainer = &IP;
00110 if (!ProcessInterval(IP.getRootInterval())) {
00111 assert(0 && "ProcessInterval should never fail for first interval!");
00112 }
00113 }
00114
00115 inline ~IntervalIterator() {
00116 if (IOwnMem)
00117 while (!IntStack.empty()) {
00118 delete operator*();
00119 IntStack.pop();
00120 }
00121 }
00122
00123 inline bool operator==(const _Self& x) const { return IntStack == x.IntStack;}
00124 inline bool operator!=(const _Self& x) const { return !operator==(x); }
00125
00126 inline const Interval *operator*() const { return IntStack.top().first; }
00127 inline Interval *operator*() { return IntStack.top().first; }
00128 inline const Interval *operator->() const { return operator*(); }
00129 inline Interval *operator->() { return operator*(); }
00130
00131 _Self& operator++() {
00132 assert(!IntStack.empty() && "Attempting to use interval iterator at end!");
00133 do {
00134
00135
00136 Interval::succ_iterator &SuccIt = IntStack.top().second,
00137 EndIt = succ_end(IntStack.top().first);
00138 while (SuccIt != EndIt) {
00139 bool Done = ProcessInterval(getSourceGraphNode(OrigContainer, *SuccIt));
00140 ++SuccIt;
00141 if (Done) return *this;
00142 }
00143
00144
00145 if (IOwnMem) delete IntStack.top().first;
00146
00147
00148 IntStack.pop();
00149 } while (!IntStack.empty());
00150
00151 return *this;
00152 }
00153 inline _Self operator++(int) {
00154 _Self tmp = *this; ++*this; return tmp;
00155 }
00156
00157 private:
00158
00159
00160
00161
00162
00163
00164
00165
00166 bool ProcessInterval(NodeTy *Node) {
00167 BasicBlock *Header = getNodeHeader(Node);
00168 if (Visited.count(Header)) return false;
00169
00170 Interval *Int = new Interval(Header);
00171 Visited.insert(Header);
00172
00173
00174 for (typename GT::ChildIteratorType I = GT::child_begin(Node),
00175 E = GT::child_end(Node); I != E; ++I)
00176 ProcessNode(Int, getSourceGraphNode(OrigContainer, *I));
00177
00178 IntStack.push(std::make_pair(Int, succ_begin(Int)));
00179 return true;
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 void ProcessNode(Interval *Int, NodeTy *Node) {
00192 assert(Int && "Null interval == bad!");
00193 assert(Node && "Null Node == bad!");
00194
00195 BasicBlock *NodeHeader = getNodeHeader(Node);
00196
00197 if (Visited.count(NodeHeader)) {
00198 if (Int->contains(NodeHeader)) {
00199 return;
00200 } else {
00201 if (!Int->isSuccessor(NodeHeader))
00202 Int->Successors.push_back(NodeHeader);
00203 }
00204 } else {
00205 for (typename IGT::ChildIteratorType I = IGT::child_begin(Node),
00206 E = IGT::child_end(Node); I != E; ++I) {
00207 if (!Int->contains(*I)) {
00208 if (!Int->isSuccessor(NodeHeader))
00209 Int->Successors.push_back(NodeHeader);
00210 return;
00211 }
00212 }
00213
00214
00215
00216 addNodeToInterval(Int, Node);
00217 Visited.insert(NodeHeader);
00218
00219 if (Int->isSuccessor(NodeHeader)) {
00220
00221 Int->Successors.erase(std::remove(Int->Successors.begin(),
00222 Int->Successors.end(), NodeHeader),
00223 Int->Successors.end());
00224 }
00225
00226
00227
00228 for (typename GT::ChildIteratorType It = GT::child_begin(Node),
00229 End = GT::child_end(Node); It != End; ++It)
00230 ProcessNode(Int, getSourceGraphNode(OrigContainer, *It));
00231 }
00232 }
00233 };
00234
00235 typedef IntervalIterator<BasicBlock, Function> function_interval_iterator;
00236 typedef IntervalIterator<Interval, IntervalPartition>
00237 interval_part_interval_iterator;
00238
00239
00240 inline function_interval_iterator intervals_begin(Function *F,
00241 bool DeleteInts = true) {
00242 return function_interval_iterator(F, DeleteInts);
00243 }
00244 inline function_interval_iterator intervals_end(Function *) {
00245 return function_interval_iterator();
00246 }
00247
00248 inline interval_part_interval_iterator
00249 intervals_begin(IntervalPartition &IP, bool DeleteIntervals = true) {
00250 return interval_part_interval_iterator(IP, DeleteIntervals);
00251 }
00252
00253 inline interval_part_interval_iterator intervals_end(IntervalPartition &IP) {
00254 return interval_part_interval_iterator();
00255 }
00256
00257 }
00258
00259 #endif