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 inline bool contains(BasicBlock *BB) {
57 return find(Nodes.begin(), Nodes.end(), BB) != Nodes.end();
60 inline bool isSuccessor(BasicBlock *BB) {
61 return find(Successors.begin(), Successors.end(), BB) != Successors.end();
64 private: // Only accessable by IntervalPartition class
65 inline Interval(BasicBlock *Header) : HeaderNode(Header) {
66 Nodes.push_back(Header);
71 // succ_begin/succ_end - define global functions so that Intervals may be used
72 // just like BasicBlocks can with the succ_* functions, and *::succ_iterator.
74 inline Interval::succ_iterator succ_begin(Interval *I) {
75 return I->Successors.begin();
77 inline Interval::succ_iterator succ_end(Interval *I) {
78 return I->Successors.end();
81 // pred_begin/pred_end - define global functions so that Intervals may be used
82 // just like BasicBlocks can with the pred_* functions, and *::pred_iterator.
84 inline Interval::pred_iterator pred_begin(Interval *I) {
85 return I->Predecessors.begin();
87 inline Interval::pred_iterator pred_end(Interval *I) {
88 return I->Predecessors.end();
93 // IntervalPartition - This class builds and holds an "interval partition" for
94 // a method. This partition divides the control flow graph into a set of
95 // maximal intervals, as defined with the properties above. Intuitively, a
96 // BasicBlock is a (possibly nonexistent) loop with a "tail" of non looping
97 // nodes following it.
99 class IntervalPartition {
100 typedef map<BasicBlock*, Interval*> IntervalMapTy;
101 IntervalMapTy IntervalMap;
103 typedef vector<Interval*> IntervalListTy;
104 IntervalListTy IntervalList;
105 Interval *RootInterval;
108 typedef IntervalListTy::iterator iterator;
111 // IntervalPartition ctor - Build the partition for the specified method
112 IntervalPartition(Method *M);
114 // IntervalPartition ctor - Build a reduced interval partition from an
115 // existing interval graph. This takes an additional boolean parameter to
116 // distinguish it from a copy constructor. Always pass in false for now.
118 IntervalPartition(IntervalPartition &I, bool);
120 // getRootInterval() - Return the root interval that contains the starting
121 // block of the method
122 inline Interval *getRootInterval() { return RootInterval; }
124 inline Interval *getBlockInterval(BasicBlock *BB) {
125 IntervalMapTy::iterator I = IntervalMap.find(BB);
126 if (I != IntervalMap.end())
132 // Iterators to iterate over all of the intervals in the method
133 inline iterator begin() { return IntervalList.begin(); }
134 inline iterator end() { return IntervalList.end(); }
137 // ProcessInterval - This method is used during the construction of the
138 // interval graph. It walks through the source graph, recursively creating
139 // an interval per invokation until the entire graph is covered. This uses
140 // the ProcessNode method to add all of the nodes to the interval.
142 // This method is templated because it may operate on two different source
143 // graphs: a basic block graph, or a preexisting interval graph.
145 template<class NodeTy, class OrigContainer>
146 void ProcessInterval(NodeTy *Node, OrigContainer *OC);
148 // ProcessNode - This method is called by ProcessInterval to add nodes to the
149 // interval being constructed, and it is also called recursively as it walks
150 // the source graph. A node is added to the current interval only if all of
151 // its predecessors are already in the graph. This also takes care of keeping
152 // the successor set of an interval up to date.
154 // This method is templated because it may operate on two different source
155 // graphs: a basic block graph, or a preexisting interval graph.
157 template<class NodeTy, class OrigContainer>
158 void ProcessNode(Interval *Int, NodeTy *Node, OrigContainer *OC);
160 // addNodeToInterval - This method exists to assist the generic ProcessNode
161 // with the task of adding a node to the new interval, depending on the
162 // type of the source node. In the case of a CFG source graph (BasicBlock
163 // case), the BasicBlock itself is added to the interval. In the case of
164 // an IntervalPartition source graph (Interval case), all of the member
165 // BasicBlocks are added to the interval.
167 inline void addNodeToInterval(Interval *Int, Interval *I);
168 inline void addNodeToInterval(Interval *Int, BasicBlock *BB);
170 // updatePredecessors - Interval generation only sets the successor fields of
171 // the interval data structures. After interval generation is complete,
172 // run through all of the intervals and propogate successor info as
175 void updatePredecessors(Interval *Int);
178 } // End namespace cfg