1 //===- llvm/Analysis/Intervals.h - Interval partition Calculation-*- C++ -*--=//
3 // This file contains the declaration of the cfg::IntervalPartition class, which
4 // calculates and represents the interval partition of a method, or a
5 // preexisting interval partition.
7 // In this way, the interval partition may be used to reduce a flow graph down
8 // to its degenerate single node interval partition (unless it is irreducible).
10 //===----------------------------------------------------------------------===//
12 #ifndef LLVM_INTERVALS_H
13 #define LLVM_INTERVALS_H
24 class IntervalPartition;
26 // Interval Class - An Interval is a set of nodes defined such that every node
27 // in the interval has all of its predecessors in the interval (except for the
30 friend class IntervalPartition;
32 typedef vector<BasicBlock*>::iterator succ_iterator;
33 typedef vector<BasicBlock*>::iterator pred_iterator;
34 typedef vector<BasicBlock*>::iterator node_iterator;
36 // HeaderNode - The header BasicBlock, which dominates all BasicBlocks in this
37 // interval. Also, any loops in this interval must go through the HeaderNode.
39 BasicBlock *HeaderNode;
41 // Nodes - The basic blocks in this interval.
43 vector<BasicBlock*> Nodes;
45 // Successors - List of BasicBlocks that are reachable directly from nodes in
46 // this interval, but are not in the interval themselves.
47 // These nodes neccesarily must be header nodes for other intervals.
49 vector<BasicBlock*> Successors;
51 // Predecessors - List of BasicBlocks that have this Interval's header block
52 // as one of their successors.
54 vector<BasicBlock*> Predecessors;
56 // contains - Find out if a basic block is in this interval
57 inline bool contains(BasicBlock *BB) const {
58 return find(Nodes.begin(), Nodes.end(), BB) != Nodes.end();
61 // isSuccessor - find out if a basic block is a successor of this Interval
62 inline bool isSuccessor(BasicBlock *BB) const {
63 return find(Successors.begin(), Successors.end(), BB) != Successors.end();
66 // isLoop - Find out if there is a back edge in this interval...
69 private: // Only accessable by IntervalPartition class
70 inline Interval(BasicBlock *Header) : HeaderNode(Header) {
71 Nodes.push_back(Header);
76 // succ_begin/succ_end - define global functions so that Intervals may be used
77 // just like BasicBlocks can with the succ_* functions, and *::succ_iterator.
79 inline Interval::succ_iterator succ_begin(Interval *I) {
80 return I->Successors.begin();
82 inline Interval::succ_iterator succ_end(Interval *I) {
83 return I->Successors.end();
86 // pred_begin/pred_end - define global functions so that Intervals may be used
87 // just like BasicBlocks can with the pred_* functions, and *::pred_iterator.
89 inline Interval::pred_iterator pred_begin(Interval *I) {
90 return I->Predecessors.begin();
92 inline Interval::pred_iterator pred_end(Interval *I) {
93 return I->Predecessors.end();
98 // IntervalPartition - This class builds and holds an "interval partition" for
99 // a method. This partition divides the control flow graph into a set of
100 // maximal intervals, as defined with the properties above. Intuitively, a
101 // BasicBlock is a (possibly nonexistent) loop with a "tail" of non looping
102 // nodes following it.
104 class IntervalPartition {
105 typedef map<BasicBlock*, Interval*> IntervalMapTy;
106 IntervalMapTy IntervalMap;
108 typedef vector<Interval*> IntervalListTy;
109 IntervalListTy IntervalList;
110 Interval *RootInterval;
113 typedef IntervalListTy::iterator iterator;
116 // IntervalPartition ctor - Build the partition for the specified method
117 IntervalPartition(Method *M);
119 // IntervalPartition ctor - Build a reduced interval partition from an
120 // existing interval graph. This takes an additional boolean parameter to
121 // distinguish it from a copy constructor. Always pass in false for now.
123 IntervalPartition(IntervalPartition &I, bool);
125 // Destructor - Free memory
126 ~IntervalPartition();
128 // getRootInterval() - Return the root interval that contains the starting
129 // block of the method.
130 inline Interval *getRootInterval() { return RootInterval; }
132 // isDegeneratePartition() - Returns true if the interval partition contains
133 // a single interval, and thus cannot be simplified anymore.
134 bool isDegeneratePartition() { return size() == 1; }
136 // TODO: isIrreducible - look for triangle graph.
138 // getBlockInterval - Return the interval that a basic block exists in.
139 inline Interval *getBlockInterval(BasicBlock *BB) {
140 IntervalMapTy::iterator I = IntervalMap.find(BB);
141 return I != IntervalMap.end() ? I->second : 0;
144 // Iterators to iterate over all of the intervals in the method
145 inline iterator begin() { return IntervalList.begin(); }
146 inline iterator end() { return IntervalList.end(); }
147 inline unsigned size() { return IntervalList.size(); }
150 // ProcessInterval - This method is used during the construction of the
151 // interval graph. It walks through the source graph, recursively creating
152 // an interval per invokation until the entire graph is covered. This uses
153 // the ProcessNode method to add all of the nodes to the interval.
155 // This method is templated because it may operate on two different source
156 // graphs: a basic block graph, or a preexisting interval graph.
158 template<class NodeTy, class OrigContainer>
159 void ProcessInterval(NodeTy *Node, OrigContainer *OC);
161 // ProcessNode - This method is called by ProcessInterval to add nodes to the
162 // interval being constructed, and it is also called recursively as it walks
163 // the source graph. A node is added to the current interval only if all of
164 // its predecessors are already in the graph. This also takes care of keeping
165 // the successor set of an interval up to date.
167 // This method is templated because it may operate on two different source
168 // graphs: a basic block graph, or a preexisting interval graph.
170 template<class NodeTy, class OrigContainer>
171 void ProcessNode(Interval *Int, NodeTy *Node, OrigContainer *OC);
173 // addNodeToInterval - This method exists to assist the generic ProcessNode
174 // with the task of adding a node to the new interval, depending on the
175 // type of the source node. In the case of a CFG source graph (BasicBlock
176 // case), the BasicBlock itself is added to the interval. In the case of
177 // an IntervalPartition source graph (Interval case), all of the member
178 // BasicBlocks are added to the interval.
180 inline void addNodeToInterval(Interval *Int, Interval *I);
181 inline void addNodeToInterval(Interval *Int, BasicBlock *BB);
183 // updatePredecessors - Interval generation only sets the successor fields of
184 // the interval data structures. After interval generation is complete,
185 // run through all of the intervals and propogate successor info as
188 void updatePredecessors(Interval *Int);
191 } // End namespace cfg