@@ -73,22 +73,86 @@ extern template bool Verify<MBBDomTree>(const MBBDomTree &DT,
73
73
// / compute a normal dominator tree.
74
74
// /
75
75
class MachineDominatorTree : public DomTreeBase <MachineBasicBlock> {
76
+ // / Helper structure used to hold all the basic blocks
77
+ // / involved in the split of a critical edge.
78
+ struct CriticalEdge {
79
+ MachineBasicBlock *FromBB;
80
+ MachineBasicBlock *ToBB;
81
+ MachineBasicBlock *NewBB;
82
+ };
83
+
84
+ // / Pile up all the critical edges to be split.
85
+ // / The splitting of a critical edge is local and thus, it is possible
86
+ // / to apply several of those changes at the same time.
87
+ mutable SmallVector<CriticalEdge, 32 > CriticalEdgesToSplit;
88
+
89
+ // / Remember all the basic blocks that are inserted during
90
+ // / edge splitting.
91
+ // / Invariant: NewBBs == all the basic blocks contained in the NewBB
92
+ // / field of all the elements of CriticalEdgesToSplit.
93
+ // / I.e., forall elt in CriticalEdgesToSplit, it exists BB in NewBBs
94
+ // / such as BB == elt.NewBB.
95
+ mutable SmallSet<MachineBasicBlock *, 32 > NewBBs;
96
+
97
+ // / Apply all the recorded critical edges to the DT.
98
+ // / This updates the underlying DT information in a way that uses
99
+ // / the fast query path of DT as much as possible.
100
+ // / FIXME: This method should not be a const member!
101
+ // /
102
+ // / \post CriticalEdgesToSplit.empty().
103
+ void applySplitCriticalEdges () const ;
76
104
77
105
public:
78
106
using Base = DomTreeBase<MachineBasicBlock>;
79
107
80
108
MachineDominatorTree () = default ;
81
- explicit MachineDominatorTree (MachineFunction &MF) { recalculate (MF); }
109
+ explicit MachineDominatorTree (MachineFunction &MF) { calculate (MF); }
82
110
83
111
// / Handle invalidation explicitly.
84
112
bool invalidate (MachineFunction &, const PreservedAnalyses &PA,
85
113
MachineFunctionAnalysisManager::Invalidator &);
86
114
87
- using Base::dominates;
115
+ // FIXME: If there is an updater for MachineDominatorTree,
116
+ // migrate to this updater and remove these wrappers.
117
+
118
+ MachineDominatorTree &getBase () {
119
+ applySplitCriticalEdges ();
120
+ return *this ;
121
+ }
122
+
123
+ MachineBasicBlock *getRoot () const {
124
+ applySplitCriticalEdges ();
125
+ return Base::getRoot ();
126
+ }
127
+
128
+ MachineDomTreeNode *getRootNode () const {
129
+ applySplitCriticalEdges ();
130
+ return const_cast <MachineDomTreeNode *>(Base::getRootNode ());
131
+ }
132
+
133
+ void calculate (MachineFunction &F);
134
+
135
+ bool dominates (const MachineDomTreeNode *A,
136
+ const MachineDomTreeNode *B) const {
137
+ applySplitCriticalEdges ();
138
+ return Base::dominates (A, B);
139
+ }
140
+
141
+ void getDescendants (MachineBasicBlock *A,
142
+ SmallVectorImpl<MachineBasicBlock *> &Result) {
143
+ applySplitCriticalEdges ();
144
+ Base::getDescendants (A, Result);
145
+ }
146
+
147
+ bool dominates (const MachineBasicBlock *A, const MachineBasicBlock *B) const {
148
+ applySplitCriticalEdges ();
149
+ return Base::dominates (A, B);
150
+ }
88
151
89
152
// dominates - Return true if A dominates B. This performs the
90
153
// special checks necessary if A and B are in the same basic block.
91
154
bool dominates (const MachineInstr *A, const MachineInstr *B) const {
155
+ applySplitCriticalEdges ();
92
156
const MachineBasicBlock *BBA = A->getParent (), *BBB = B->getParent ();
93
157
if (BBA != BBB)
94
158
return Base::dominates (BBA, BBB);
@@ -100,6 +164,107 @@ class MachineDominatorTree : public DomTreeBase<MachineBasicBlock> {
100
164
101
165
return &*I == A;
102
166
}
167
+
168
+ bool properlyDominates (const MachineDomTreeNode *A,
169
+ const MachineDomTreeNode *B) const {
170
+ applySplitCriticalEdges ();
171
+ return Base::properlyDominates (A, B);
172
+ }
173
+
174
+ bool properlyDominates (const MachineBasicBlock *A,
175
+ const MachineBasicBlock *B) const {
176
+ applySplitCriticalEdges ();
177
+ return Base::properlyDominates (A, B);
178
+ }
179
+
180
+ // / findNearestCommonDominator - Find nearest common dominator basic block
181
+ // / for basic block A and B. If there is no such block then return NULL.
182
+ MachineBasicBlock *findNearestCommonDominator (MachineBasicBlock *A,
183
+ MachineBasicBlock *B) {
184
+ applySplitCriticalEdges ();
185
+ return Base::findNearestCommonDominator (A, B);
186
+ }
187
+
188
+ MachineDomTreeNode *operator [](MachineBasicBlock *BB) const {
189
+ applySplitCriticalEdges ();
190
+ return Base::getNode (BB);
191
+ }
192
+
193
+ // / getNode - return the (Post)DominatorTree node for the specified basic
194
+ // / block. This is the same as using operator[] on this class.
195
+ // /
196
+ MachineDomTreeNode *getNode (MachineBasicBlock *BB) const {
197
+ applySplitCriticalEdges ();
198
+ return Base::getNode (BB);
199
+ }
200
+
201
+ // / addNewBlock - Add a new node to the dominator tree information. This
202
+ // / creates a new node as a child of DomBB dominator node,linking it into
203
+ // / the children list of the immediate dominator.
204
+ MachineDomTreeNode *addNewBlock (MachineBasicBlock *BB,
205
+ MachineBasicBlock *DomBB) {
206
+ applySplitCriticalEdges ();
207
+ return Base::addNewBlock (BB, DomBB);
208
+ }
209
+
210
+ // / changeImmediateDominator - This method is used to update the dominator
211
+ // / tree information when a node's immediate dominator changes.
212
+ // /
213
+ void changeImmediateDominator (MachineBasicBlock *N,
214
+ MachineBasicBlock *NewIDom) {
215
+ applySplitCriticalEdges ();
216
+ Base::changeImmediateDominator (N, NewIDom);
217
+ }
218
+
219
+ void changeImmediateDominator (MachineDomTreeNode *N,
220
+ MachineDomTreeNode *NewIDom) {
221
+ applySplitCriticalEdges ();
222
+ Base::changeImmediateDominator (N, NewIDom);
223
+ }
224
+
225
+ // / eraseNode - Removes a node from the dominator tree. Block must not
226
+ // / dominate any other blocks. Removes node from its immediate dominator's
227
+ // / children list. Deletes dominator node associated with basic block BB.
228
+ void eraseNode (MachineBasicBlock *BB) {
229
+ applySplitCriticalEdges ();
230
+ Base::eraseNode (BB);
231
+ }
232
+
233
+ // / splitBlock - BB is split and now it has one successor. Update dominator
234
+ // / tree to reflect this change.
235
+ void splitBlock (MachineBasicBlock* NewBB) {
236
+ applySplitCriticalEdges ();
237
+ Base::splitBlock (NewBB);
238
+ }
239
+
240
+ // / isReachableFromEntry - Return true if A is dominated by the entry
241
+ // / block of the function containing it.
242
+ bool isReachableFromEntry (const MachineBasicBlock *A) {
243
+ applySplitCriticalEdges ();
244
+ return Base::isReachableFromEntry (A);
245
+ }
246
+
247
+ // / Record that the critical edge (FromBB, ToBB) has been
248
+ // / split with NewBB.
249
+ // / This is best to use this method instead of directly update the
250
+ // / underlying information, because this helps mitigating the
251
+ // / number of time the DT information is invalidated.
252
+ // /
253
+ // / \note Do not use this method with regular edges.
254
+ // /
255
+ // / \note To benefit from the compile time improvement incurred by this
256
+ // / method, the users of this method have to limit the queries to the DT
257
+ // / interface between two edges splitting. In other words, they have to
258
+ // / pack the splitting of critical edges as much as possible.
259
+ void recordSplitCriticalEdge (MachineBasicBlock *FromBB,
260
+ MachineBasicBlock *ToBB,
261
+ MachineBasicBlock *NewBB) {
262
+ bool Inserted = NewBBs.insert (NewBB).second ;
263
+ (void )Inserted;
264
+ assert (Inserted &&
265
+ " A basic block inserted via edge splitting cannot appear twice" );
266
+ CriticalEdgesToSplit.push_back ({FromBB, ToBB, NewBB});
267
+ }
103
268
};
104
269
105
270
// / \brief Analysis pass which computes a \c MachineDominatorTree.
0 commit comments