15
15
#ifndef LLVM_CODEGEN_MACHINEDOMINATORS_H
16
16
#define LLVM_CODEGEN_MACHINEDOMINATORS_H
17
17
18
+ #include " llvm/ADT/SmallSet.h"
18
19
#include " llvm/CodeGen/MachineBasicBlock.h"
19
20
#include " llvm/CodeGen/MachineFunction.h"
20
21
#include " llvm/CodeGen/MachineFunctionPass.h"
@@ -38,6 +39,103 @@ typedef DomTreeNodeBase<MachineBasicBlock> MachineDomTreeNode;
38
39
// / compute a normal dominator tree.
39
40
// /
40
41
class MachineDominatorTree : public MachineFunctionPass {
42
+ // / \brief Helper structure used to hold all the basic blocks
43
+ // / involved in the split of a critical edge.
44
+ struct CriticalEdge {
45
+ MachineBasicBlock *FromBB;
46
+ MachineBasicBlock *ToBB;
47
+ MachineBasicBlock *NewBB;
48
+ CriticalEdge (MachineBasicBlock *FromBB, MachineBasicBlock *ToBB,
49
+ MachineBasicBlock *NewBB)
50
+ : FromBB(FromBB), ToBB(ToBB), NewBB(NewBB) {}
51
+ };
52
+
53
+ // / \brief Pile up all the critical edges to be split.
54
+ // / The splitting of a critical edge is local and thus, it is possible
55
+ // / to apply several of those changes at the same time.
56
+ mutable SmallVector<CriticalEdge, 32 > CriticalEdgesToSplit;
57
+ // / \brief Remember all the basic blocks that are inserted during
58
+ // / edge splitting.
59
+ // / Invariant: NewBBs == all the basic blocks contained in the NewBB
60
+ // / field of all the elements of CriticalEdgesToSplit.
61
+ // / I.e., forall elt in CriticalEdgesToSplit, it exists BB in NewBBs
62
+ // / such as BB == elt.NewBB.
63
+ mutable SmallSet<MachineBasicBlock *, 32 > NewBBs;
64
+
65
+ // / \brief Apply all the recorded critical edges to the DT.
66
+ // / This updates the underlying DT information in a way that uses
67
+ // / the fast query path of DT as much as possible.
68
+ // /
69
+ // / \post CriticalEdgesToSplit.empty().
70
+ void applySplitCriticalEdges () const {
71
+ // Bail out early if there is nothing to do.
72
+ if (CriticalEdgesToSplit.empty ())
73
+ return ;
74
+
75
+ // For each element in CriticalEdgesToSplit, remember whether or
76
+ // not element is the new immediate domminator of its successor.
77
+ // The mapping is done by index, i.e., the information for the ith
78
+ // element of CriticalEdgesToSplit is the ith element of IsNewIDom.
79
+ SmallVector<bool , 32 > IsNewIDom;
80
+ IsNewIDom.resize (CriticalEdgesToSplit.size ());
81
+ size_t Idx = 0 ;
82
+
83
+ // Collect all the dominance properties info, before invalidating
84
+ // the underlying DT.
85
+ for (CriticalEdge &Edge : CriticalEdgesToSplit) {
86
+ // Update dominator information.
87
+ MachineBasicBlock *Succ = Edge.ToBB ;
88
+ MachineDomTreeNode *SucccDTNode = DT->getNode (Succ);
89
+
90
+ IsNewIDom[Idx] = true ;
91
+ for (MachineBasicBlock *PredBB : Succ->predecessors ()) {
92
+ if (PredBB == Edge.NewBB )
93
+ continue ;
94
+ // If we are in this situation:
95
+ // FromBB1 FromBB2
96
+ // + +
97
+ // + + + +
98
+ // + + + +
99
+ // ... Split1 Split2 ...
100
+ // + +
101
+ // + +
102
+ // +
103
+ // Succ
104
+ // Instead of checking the domiance property with Split2, we
105
+ // check it with FromBB2 since Split2 is still unknown of the
106
+ // underlying DT structure.
107
+ if (NewBBs.count (PredBB)) {
108
+ assert (PredBB->pred_size () == 1 && " A basic block resulting from a "
109
+ " critical edge split has more "
110
+ " than one predecessor!" );
111
+ PredBB = *PredBB->pred_begin ();
112
+ }
113
+ if (!DT->dominates (SucccDTNode, DT->getNode (PredBB))) {
114
+ IsNewIDom[Idx] = false ;
115
+ break ;
116
+ }
117
+ }
118
+ ++Idx;
119
+ }
120
+
121
+ // Now, update DT with the collected dominance properties info.
122
+ Idx = 0 ;
123
+ for (CriticalEdge &Edge : CriticalEdgesToSplit) {
124
+ // We know FromBB dominates NewBB.
125
+ MachineDomTreeNode *NewDTNode = DT->addNewBlock (Edge.NewBB , Edge.FromBB );
126
+ MachineDomTreeNode *SucccDTNode = DT->getNode (Edge.ToBB );
127
+
128
+ // If all the other predecessors of "Succ" are dominated by "Succ" itself
129
+ // then the new block is the new immediate dominator of "Succ". Otherwise,
130
+ // the new block doesn't dominate anything.
131
+ if (IsNewIDom[Idx])
132
+ DT->changeImmediateDominator (SucccDTNode, NewDTNode);
133
+ ++Idx;
134
+ }
135
+ NewBBs.clear ();
136
+ CriticalEdgesToSplit.clear ();
137
+ }
138
+
41
139
public:
42
140
static char ID; // Pass ID, replacement for typeid
43
141
DominatorTreeBase<MachineBasicBlock>* DT;
@@ -46,7 +144,10 @@ class MachineDominatorTree : public MachineFunctionPass {
46
144
47
145
~MachineDominatorTree ();
48
146
49
- DominatorTreeBase<MachineBasicBlock>& getBase () { return *DT; }
147
+ DominatorTreeBase<MachineBasicBlock> &getBase () {
148
+ applySplitCriticalEdges ();
149
+ return *DT;
150
+ }
50
151
51
152
void getAnalysisUsage (AnalysisUsage &AU) const override ;
52
153
@@ -55,32 +156,38 @@ class MachineDominatorTree : public MachineFunctionPass {
55
156
// / dominators, this will always be a single block (the entry node).
56
157
// /
57
158
inline const std::vector<MachineBasicBlock*> &getRoots () const {
159
+ applySplitCriticalEdges ();
58
160
return DT->getRoots ();
59
161
}
60
162
61
163
inline MachineBasicBlock *getRoot () const {
164
+ applySplitCriticalEdges ();
62
165
return DT->getRoot ();
63
166
}
64
167
65
168
inline MachineDomTreeNode *getRootNode () const {
169
+ applySplitCriticalEdges ();
66
170
return DT->getRootNode ();
67
171
}
68
172
69
173
bool runOnMachineFunction (MachineFunction &F) override ;
70
174
71
175
inline bool dominates (const MachineDomTreeNode* A,
72
176
const MachineDomTreeNode* B) const {
177
+ applySplitCriticalEdges ();
73
178
return DT->dominates (A, B);
74
179
}
75
180
76
181
inline bool dominates (const MachineBasicBlock* A,
77
182
const MachineBasicBlock* B) const {
183
+ applySplitCriticalEdges ();
78
184
return DT->dominates (A, B);
79
185
}
80
186
81
187
// dominates - Return true if A dominates B. This performs the
82
188
// special checks necessary if A and B are in the same basic block.
83
189
bool dominates (const MachineInstr *A, const MachineInstr *B) const {
190
+ applySplitCriticalEdges ();
84
191
const MachineBasicBlock *BBA = A->getParent (), *BBB = B->getParent ();
85
192
if (BBA != BBB) return DT->dominates (BBA, BBB);
86
193
@@ -100,29 +207,34 @@ class MachineDominatorTree : public MachineFunctionPass {
100
207
101
208
inline bool properlyDominates (const MachineDomTreeNode* A,
102
209
const MachineDomTreeNode* B) const {
210
+ applySplitCriticalEdges ();
103
211
return DT->properlyDominates (A, B);
104
212
}
105
213
106
214
inline bool properlyDominates (const MachineBasicBlock* A,
107
215
const MachineBasicBlock* B) const {
216
+ applySplitCriticalEdges ();
108
217
return DT->properlyDominates (A, B);
109
218
}
110
219
111
220
// / findNearestCommonDominator - Find nearest common dominator basic block
112
221
// / for basic block A and B. If there is no such block then return NULL.
113
222
inline MachineBasicBlock *findNearestCommonDominator (MachineBasicBlock *A,
114
223
MachineBasicBlock *B) {
224
+ applySplitCriticalEdges ();
115
225
return DT->findNearestCommonDominator (A, B);
116
226
}
117
227
118
228
inline MachineDomTreeNode *operator [](MachineBasicBlock *BB) const {
229
+ applySplitCriticalEdges ();
119
230
return DT->getNode (BB);
120
231
}
121
232
122
233
// / getNode - return the (Post)DominatorTree node for the specified basic
123
234
// / block. This is the same as using operator[] on this class.
124
235
// /
125
236
inline MachineDomTreeNode *getNode (MachineBasicBlock *BB) const {
237
+ applySplitCriticalEdges ();
126
238
return DT->getNode (BB);
127
239
}
128
240
@@ -131,6 +243,7 @@ class MachineDominatorTree : public MachineFunctionPass {
131
243
// / the children list of the immediate dominator.
132
244
inline MachineDomTreeNode *addNewBlock (MachineBasicBlock *BB,
133
245
MachineBasicBlock *DomBB) {
246
+ applySplitCriticalEdges ();
134
247
return DT->addNewBlock (BB, DomBB);
135
248
}
136
249
@@ -139,36 +252,63 @@ class MachineDominatorTree : public MachineFunctionPass {
139
252
// /
140
253
inline void changeImmediateDominator (MachineBasicBlock *N,
141
254
MachineBasicBlock* NewIDom) {
255
+ applySplitCriticalEdges ();
142
256
DT->changeImmediateDominator (N, NewIDom);
143
257
}
144
258
145
259
inline void changeImmediateDominator (MachineDomTreeNode *N,
146
260
MachineDomTreeNode* NewIDom) {
261
+ applySplitCriticalEdges ();
147
262
DT->changeImmediateDominator (N, NewIDom);
148
263
}
149
264
150
265
// / eraseNode - Removes a node from the dominator tree. Block must not
151
266
// / dominate any other blocks. Removes node from its immediate dominator's
152
267
// / children list. Deletes dominator node associated with basic block BB.
153
268
inline void eraseNode (MachineBasicBlock *BB) {
269
+ applySplitCriticalEdges ();
154
270
DT->eraseNode (BB);
155
271
}
156
272
157
273
// / splitBlock - BB is split and now it has one successor. Update dominator
158
274
// / tree to reflect this change.
159
275
inline void splitBlock (MachineBasicBlock* NewBB) {
276
+ applySplitCriticalEdges ();
160
277
DT->splitBlock (NewBB);
161
278
}
162
279
163
280
// / isReachableFromEntry - Return true if A is dominated by the entry
164
281
// / block of the function containing it.
165
282
bool isReachableFromEntry (const MachineBasicBlock *A) {
283
+ applySplitCriticalEdges ();
166
284
return DT->isReachableFromEntry (A);
167
285
}
168
286
169
287
void releaseMemory () override ;
170
288
171
289
void print (raw_ostream &OS, const Module*) const override ;
290
+
291
+ // / \brief Record that the critical edge (FromBB, ToBB) has been
292
+ // / split with NewBB.
293
+ // / This is best to use this method instead of directly update the
294
+ // / underlying information, because this helps mitigating the
295
+ // / number of time the DT information is invalidated.
296
+ // /
297
+ // / \note Do not use this method with regular edges.
298
+ // /
299
+ // / \note To benefit from the compile time improvement incurred by this
300
+ // / method, the users of this method have to limit the queries to the DT
301
+ // / interface between two edges splitting. In other words, they have to
302
+ // / pack the splitting of critical edges as much as possible.
303
+ void recordSplitCriticalEdge (MachineBasicBlock *FromBB,
304
+ MachineBasicBlock *ToBB,
305
+ MachineBasicBlock *NewBB) {
306
+ bool Inserted = NewBBs.insert (NewBB);
307
+ (void )Inserted;
308
+ assert (Inserted &&
309
+ " A basic block inserted via edge splitting cannot appear twice" );
310
+ CriticalEdgesToSplit.push_back (CriticalEdge (FromBB, ToBB, NewBB));
311
+ }
172
312
};
173
313
174
314
// ===-------------------------------------
0 commit comments