24
24
#ifndef LLVM_SUPPORT_GENERICDOMTREE_H
25
25
#define LLVM_SUPPORT_GENERICDOMTREE_H
26
26
27
- #include " llvm/ADT/DenseMap.h"
28
- #include " llvm/ADT/GraphTraits.h"
29
- #include " llvm/ADT/STLExtras.h"
30
- #include " llvm/ADT/SmallPtrSet.h"
31
- #include " llvm/ADT/SmallVector.h"
32
- #include " llvm/Support/raw_ostream.h"
33
27
#include < algorithm>
34
28
#include < cassert>
35
29
#include < cstddef>
38
32
#include < type_traits>
39
33
#include < utility>
40
34
#include < vector>
35
+ #include " llvm/ADT/DenseMap.h"
36
+ #include " llvm/ADT/GraphTraits.h"
37
+ #include " llvm/ADT/PointerIntPair.h"
38
+ #include " llvm/ADT/STLExtras.h"
39
+ #include " llvm/ADT/SmallPtrSet.h"
40
+ #include " llvm/ADT/SmallVector.h"
41
+ #include " llvm/Support/raw_ostream.h"
41
42
42
43
namespace llvm {
43
44
44
45
template <typename NodeT, bool IsPostDom>
45
46
class DominatorTreeBase ;
46
47
47
48
namespace DomTreeBuilder {
48
- template <class DomTreeT >
49
+ template <typename DomTreeT>
49
50
struct SemiNCAInfo ;
50
51
} // namespace DomTreeBuilder
51
52
@@ -190,14 +191,48 @@ namespace DomTreeBuilder {
190
191
template <typename DomTreeT>
191
192
void Calculate (DomTreeT &DT);
192
193
193
- template <class DomTreeT >
194
+ template <typename DomTreeT>
194
195
void InsertEdge (DomTreeT &DT, typename DomTreeT::NodePtr From,
195
196
typename DomTreeT::NodePtr To);
196
197
197
- template <class DomTreeT >
198
+ template <typename DomTreeT>
198
199
void DeleteEdge (DomTreeT &DT, typename DomTreeT::NodePtr From,
199
200
typename DomTreeT::NodePtr To);
200
201
202
+ // UpdateKind and Update are used by the batch update API and it's easiest to
203
+ // define them here.
204
+ enum class UpdateKind : unsigned char { Insert, Delete };
205
+
206
+ template <typename NodePtr>
207
+ struct Update {
208
+ using NodeKindPair = PointerIntPair<NodePtr, 1 , UpdateKind>;
209
+
210
+ NodePtr From;
211
+ NodeKindPair ToAndKind;
212
+
213
+ Update (UpdateKind Kind, NodePtr From, NodePtr To)
214
+ : From(From), ToAndKind(To, Kind) {}
215
+
216
+ UpdateKind getKind () const { return ToAndKind.getInt (); }
217
+ NodePtr getFrom () const { return From; }
218
+ NodePtr getTo () const { return ToAndKind.getPointer (); }
219
+ bool operator ==(const Update &RHS) const {
220
+ return From == RHS.From && ToAndKind == RHS.ToAndKind ;
221
+ }
222
+
223
+ friend raw_ostream &operator <<(raw_ostream &OS, const Update &U) {
224
+ OS << (U.getKind () == UpdateKind::Insert ? " Insert " : " Delete " );
225
+ U.getFrom ()->printAsOperand (OS, false );
226
+ OS << " -> " ;
227
+ U.getTo ()->printAsOperand (OS, false );
228
+ return OS;
229
+ }
230
+ };
231
+
232
+ template <typename DomTreeT>
233
+ void ApplyUpdates (DomTreeT &DT,
234
+ ArrayRef<typename DomTreeT::UpdateType> Updates);
235
+
201
236
template <typename DomTreeT>
202
237
bool Verify (const DomTreeT &DT);
203
238
} // namespace DomTreeBuilder
@@ -219,6 +254,11 @@ class DominatorTreeBase {
219
254
using ParentType = typename std::remove_pointer<ParentPtr>::type;
220
255
static constexpr bool IsPostDominator = IsPostDom;
221
256
257
+ using UpdateType = DomTreeBuilder::Update<NodePtr>;
258
+ using UpdateKind = DomTreeBuilder::UpdateKind;
259
+ static constexpr UpdateKind Insert = UpdateKind::Insert;
260
+ static constexpr UpdateKind Delete = UpdateKind::Delete;
261
+
222
262
protected:
223
263
// Dominators always have a single root, postdominators can have more.
224
264
SmallVector<NodeT *, IsPostDom ? 4 : 1 > Roots;
@@ -463,6 +503,39 @@ class DominatorTreeBase {
463
503
// API to update (Post)DominatorTree information based on modifications to
464
504
// the CFG...
465
505
506
+ // / Inform the dominator tree about a sequence of CFG edge insertions and
507
+ // / deletions and perform a batch update on the tree.
508
+ // /
509
+ // / This function should be used when there were multiple CFG updates after
510
+ // / the last dominator tree update. It takes care of performing the updates
511
+ // / in sync with the CFG and optimizes away the redundant operations that
512
+ // / cancel each other.
513
+ // / The functions expects the sequence of updates to be balanced. Eg.:
514
+ // / - {{Insert, A, B}, {Delete, A, B}, {Insert, A, B}} is fine, because
515
+ // / logically it results in a single insertions.
516
+ // / - {{Insert, A, B}, {Insert, A, B}} is invalid, because it doesn't make
517
+ // / sense to insert the same edge twice.
518
+ // /
519
+ // / What's more, the functions assumes that it's safe to ask every node in the
520
+ // / CFG about its children and inverse children. This implies that deletions
521
+ // / of CFG edges must not delete the CFG nodes before calling this function.
522
+ // /
523
+ // / Batch updates should be generally faster when performing longer sequences
524
+ // / of updates than calling insertEdge/deleteEdge manually multiple times, as
525
+ // / they can reorder the updates and remove redundant ones internally.
526
+ // /
527
+ // / Note that for postdominators it automatically takes care of applying
528
+ // / updates on reverse edges internally (so there's no need to swap the
529
+ // / From and To pointers when constructing DominatorTree::UpdateType).
530
+ // / The type of updates is the same for DomTreeBase<T> and PostDomTreeBase<T>
531
+ // / with the same template parameter T.
532
+ // /
533
+ // / \param Updates An unordered sequence of updates to perform.
534
+ // /
535
+ void applyUpdates (ArrayRef<UpdateType> Updates) {
536
+ DomTreeBuilder::ApplyUpdates (*this , Updates);
537
+ }
538
+
466
539
// / Inform the dominator tree about a CFG edge insertion and update the tree.
467
540
// /
468
541
// / This function has to be called just before or just after making the update
@@ -487,11 +560,6 @@ class DominatorTreeBase {
487
560
// / DEBUG mode. There cannot be any other updates that the
488
561
// / dominator tree doesn't know about.
489
562
// /
490
- // / However, it is fine to perform multiple CFG deletions that make different
491
- // / subtrees forward-unreachable and to inform the DomTree about them all at
492
- // / the same time, as the incremental algorithm doesn't walk the tree above
493
- // / the NearestCommonDominator of a deleted edge
494
- // /
495
563
// / Note that for postdominators it automatically takes care of deleting
496
564
// / a reverse edge internally (so there's no need to swap the parameters).
497
565
// /
@@ -678,7 +746,6 @@ class DominatorTreeBase {
678
746
679
747
// / recalculate - compute a dominator tree for the given function
680
748
void recalculate (ParentType &Func) {
681
- reset ();
682
749
Parent = &Func;
683
750
DomTreeBuilder::Calculate (*this );
684
751
}
0 commit comments