1+ // ===- IntraProc/ControlDependenceGraph.h -----------------------*- C++ -*-===//
2+ //
3+ // Static Program Analysis for LLVM
4+ //
5+ // This file is distributed under a Modified BSD License (see LICENSE.TXT).
6+ //
7+ // ===----------------------------------------------------------------------===//
8+ //
9+ // This file defines the ControlDependenceGraph class, which allows fast and
10+ // efficient control dependence queries. It is based on Ferrante et al's "The
11+ // Program Dependence Graph and Its Use in Optimization."
12+ //
13+ // ===----------------------------------------------------------------------===//
14+
15+ #ifndef ANALYSIS_CONTROLDEPENDENCEGRAPH_H
16+ #define ANALYSIS_CONTROLDEPENDENCEGRAPH_H
17+
18+ #include " llvm/ADT/DepthFirstIterator.h"
19+ #include " llvm/ADT/GraphTraits.h"
20+ #include " llvm/Analysis/PostDominators.h"
21+ #include " llvm/IR/Module.h"
22+ #include " llvm/Pass.h"
23+ #include " llvm/Support/DOTGraphTraits.h"
24+
25+ #include < map>
26+ #include < set>
27+ #include < iterator>
28+
29+ namespace llvm {
30+
31+ class BasicBlock ;
32+ class ControlDependenceGraphBase ;
33+
34+ class ControlDependenceNode {
35+ public:
36+ enum EdgeType { TRUE , FALSE , OTHER };
37+ typedef std::set<ControlDependenceNode *>::iterator node_iterator;
38+ typedef std::set<ControlDependenceNode *>::const_iterator const_node_iterator;
39+
40+ struct edge_iterator {
41+ typedef node_iterator::value_type value_type;
42+ typedef node_iterator::difference_type difference_type;
43+ typedef node_iterator::reference reference;
44+ typedef node_iterator::pointer pointer;
45+ typedef std::input_iterator_tag iterator_category;
46+
47+ edge_iterator (ControlDependenceNode *n) :
48+ node (n), stage(TRUE ), it(n->TrueChildren.begin()), end(n->TrueChildren.end()) {
49+ while ((stage != OTHER) && (it == end)) this ->operator ++();
50+ }
51+ edge_iterator (ControlDependenceNode *n, EdgeType t, node_iterator i, node_iterator e) :
52+ node (n), stage(t), it(i), end(e) {
53+ while ((stage != OTHER) && (it == end)) this ->operator ++();
54+ }
55+ EdgeType type () const { return stage; }
56+ bool operator ==(edge_iterator const &other) const {
57+ return (this ->stage == other.stage ) && (this ->it == other.it );
58+ }
59+ bool operator !=(edge_iterator const &other) const { return !(*this == other); }
60+ reference operator *() { return *this ->it ; }
61+ pointer operator ->() { return &*this ->it ; }
62+ edge_iterator& operator ++() {
63+ if (it != end) ++it;
64+ while ((stage != OTHER) && (it == end)) {
65+ if (stage == TRUE ) {
66+ it = node->FalseChildren .begin ();
67+ end = node->FalseChildren .end ();
68+ stage = FALSE ;
69+ } else {
70+ it = node->OtherChildren .begin ();
71+ end = node->OtherChildren .end ();
72+ stage = OTHER;
73+ }
74+ }
75+ return *this ;
76+ }
77+ edge_iterator operator ++(int ) {
78+ edge_iterator ret (*this );
79+ assert (ret.stage == OTHER || ret.it != ret.end );
80+ this ->operator ++();
81+ return ret;
82+ }
83+ private:
84+ ControlDependenceNode *node;
85+ EdgeType stage;
86+ node_iterator it, end;
87+ };
88+
89+ edge_iterator begin () { return edge_iterator (this ); }
90+ edge_iterator end () { return edge_iterator (this , OTHER, OtherChildren.end (), OtherChildren.end ()); }
91+
92+ node_iterator true_begin () { return TrueChildren.begin (); }
93+ node_iterator true_end () { return TrueChildren.end (); }
94+
95+ node_iterator false_begin () { return FalseChildren.begin (); }
96+ node_iterator false_end () { return FalseChildren.end (); }
97+
98+ node_iterator other_begin () { return OtherChildren.begin (); }
99+ node_iterator other_end () { return OtherChildren.end (); }
100+
101+ node_iterator parent_begin () { return Parents.begin (); }
102+ node_iterator parent_end () { return Parents.end (); }
103+ const_node_iterator parent_begin () const { return Parents.begin (); }
104+ const_node_iterator parent_end () const { return Parents.end (); }
105+
106+ BasicBlock *getBlock () const { return TheBB; }
107+ size_t getNumParents () const { return Parents.size (); }
108+ size_t getNumChildren () const {
109+ return TrueChildren.size () + FalseChildren.size () + OtherChildren.size ();
110+ }
111+ bool isRegion () const { return TheBB == NULL ; }
112+ const ControlDependenceNode *enclosingRegion () const ;
113+
114+ private:
115+ BasicBlock *TheBB;
116+ std::set<ControlDependenceNode *> Parents;
117+ std::set<ControlDependenceNode *> TrueChildren;
118+ std::set<ControlDependenceNode *> FalseChildren;
119+ std::set<ControlDependenceNode *> OtherChildren;
120+
121+ friend class ControlDependenceGraphBase ;
122+
123+ void clearAllChildren () {
124+ TrueChildren.clear ();
125+ FalseChildren.clear ();
126+ OtherChildren.clear ();
127+ }
128+ void clearAllParents () { Parents.clear (); }
129+
130+ void addTrue (ControlDependenceNode *Child);
131+ void addFalse (ControlDependenceNode *Child);
132+ void addOther (ControlDependenceNode *Child);
133+ void addParent (ControlDependenceNode *Parent);
134+ void removeTrue (ControlDependenceNode *Child);
135+ void removeFalse (ControlDependenceNode *Child);
136+ void removeOther (ControlDependenceNode *Child);
137+ void removeParent (ControlDependenceNode *Child);
138+
139+ ControlDependenceNode () : TheBB(NULL ) {}
140+ ControlDependenceNode (BasicBlock *bb) : TheBB(bb) {}
141+ };
142+
143+ class ControlDependenceGraphBase {
144+ public:
145+ ControlDependenceGraphBase () : root(NULL ) {}
146+ virtual ~ControlDependenceGraphBase () { releaseMemory (); }
147+ virtual void releaseMemory () {
148+ for (ControlDependenceNode::node_iterator n = nodes.begin (), e = nodes.end ();
149+ n != e; ++n) delete *n;
150+ nodes.clear ();
151+ bbMap.clear ();
152+ root = NULL ;
153+ }
154+
155+ void graphForFunction (Function &F, PostDominatorTree &pdt);
156+
157+ ControlDependenceNode *getRoot () { return root; }
158+ const ControlDependenceNode *getRoot () const { return root; }
159+ ControlDependenceNode *operator [](const BasicBlock *BB) { return getNode (BB); }
160+ const ControlDependenceNode *operator [](const BasicBlock *BB) const { return getNode (BB); }
161+ ControlDependenceNode *getNode (const BasicBlock *BB) {
162+ return bbMap[BB];
163+ }
164+ const ControlDependenceNode *getNode (const BasicBlock *BB) const {
165+ return (bbMap.find (BB) != bbMap.end ()) ? bbMap.find (BB)->second : NULL ;
166+ }
167+ bool controls (BasicBlock *A, BasicBlock *B) const ;
168+ bool influences (BasicBlock *A, BasicBlock *B) const ;
169+ const ControlDependenceNode *enclosingRegion (BasicBlock *BB) const ;
170+
171+ private:
172+ ControlDependenceNode *root;
173+ std::set<ControlDependenceNode *> nodes;
174+ std::map<const BasicBlock *,ControlDependenceNode *> bbMap;
175+ static ControlDependenceNode::EdgeType getEdgeType (const BasicBlock *, const BasicBlock *);
176+ void computeDependencies (Function &F, PostDominatorTree &pdt);
177+ void insertRegions (PostDominatorTree &pdt);
178+ };
179+
180+ class ControlDependenceGraph : public FunctionPass , public ControlDependenceGraphBase {
181+ public:
182+ static char ID;
183+
184+ ControlDependenceGraph () : FunctionPass(ID), ControlDependenceGraphBase() {}
185+ virtual ~ControlDependenceGraph () { }
186+ virtual void getAnalysisUsage (AnalysisUsage &AU) const {
187+ AU.addRequired <PostDominatorTreeWrapperPass>();
188+ AU.setPreservesAll ();
189+ }
190+ virtual bool runOnFunction (Function &F) {
191+ PostDominatorTree &pdt = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree ();
192+ graphForFunction (F,pdt);
193+ return false ;
194+ }
195+ };
196+
197+ } // namespace llvm
198+
199+ #endif // ANALYSIS_CONTROLDEPENDENCEGRAPH_H
0 commit comments