Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit f39b8ab

Browse files
committed
[Dominators] Introduce batch updates
Summary: This patch introduces a way of informing the (Post)DominatorTree about multiple CFG updates that happened since the last tree update. This makes performing tree updates much easier, as it internally takes care of applying the updates in lockstep with the (virtual) updates to the CFG, which is done by reverse-applying future CFG updates. The batch updater is able to remove redundant updates that cancel each other out. In the future, it should be also possible to reorder updates to reduce the amount of work needed to perform the updates. Reviewers: dberlin, sanjoy, grosser, davide, brzycki Reviewed By: brzycki Subscribers: mgorny, llvm-commits Differential Revision: https://reviews.llvm.org/D36167 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311015 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent a62eb7b commit f39b8ab

File tree

6 files changed

+667
-96
lines changed

6 files changed

+667
-96
lines changed

include/llvm/IR/Dominators.h

+7
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ namespace DomTreeBuilder {
4141
using BBDomTree = DomTreeBase<BasicBlock>;
4242
using BBPostDomTree = PostDomTreeBase<BasicBlock>;
4343

44+
extern template struct Update<BasicBlock *>;
45+
46+
using BBUpdates = ArrayRef<Update<BasicBlock *>>;
47+
4448
extern template void Calculate<BBDomTree>(BBDomTree &DT);
4549
extern template void Calculate<BBPostDomTree>(BBPostDomTree &DT);
4650

@@ -56,6 +60,9 @@ extern template void DeleteEdge<BBPostDomTree>(BBPostDomTree &DT,
5660
BasicBlock *From,
5761
BasicBlock *To);
5862

63+
extern template void ApplyUpdates<BBDomTree>(BBDomTree &DT, BBUpdates);
64+
extern template void ApplyUpdates<BBPostDomTree>(BBPostDomTree &DT, BBUpdates);
65+
5966
extern template bool Verify<BBDomTree>(const BBDomTree &DT);
6067
extern template bool Verify<BBPostDomTree>(const BBPostDomTree &DT);
6168
} // namespace DomTreeBuilder

include/llvm/Support/GenericDomTree.h

+82-15
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@
2424
#ifndef LLVM_SUPPORT_GENERICDOMTREE_H
2525
#define LLVM_SUPPORT_GENERICDOMTREE_H
2626

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"
3327
#include <algorithm>
3428
#include <cassert>
3529
#include <cstddef>
@@ -38,14 +32,21 @@
3832
#include <type_traits>
3933
#include <utility>
4034
#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"
4142

4243
namespace llvm {
4344

4445
template <typename NodeT, bool IsPostDom>
4546
class DominatorTreeBase;
4647

4748
namespace DomTreeBuilder {
48-
template <class DomTreeT>
49+
template <typename DomTreeT>
4950
struct SemiNCAInfo;
5051
} // namespace DomTreeBuilder
5152

@@ -190,14 +191,48 @@ namespace DomTreeBuilder {
190191
template <typename DomTreeT>
191192
void Calculate(DomTreeT &DT);
192193

193-
template <class DomTreeT>
194+
template <typename DomTreeT>
194195
void InsertEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
195196
typename DomTreeT::NodePtr To);
196197

197-
template <class DomTreeT>
198+
template <typename DomTreeT>
198199
void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
199200
typename DomTreeT::NodePtr To);
200201

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+
201236
template <typename DomTreeT>
202237
bool Verify(const DomTreeT &DT);
203238
} // namespace DomTreeBuilder
@@ -219,6 +254,11 @@ class DominatorTreeBase {
219254
using ParentType = typename std::remove_pointer<ParentPtr>::type;
220255
static constexpr bool IsPostDominator = IsPostDom;
221256

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+
222262
protected:
223263
// Dominators always have a single root, postdominators can have more.
224264
SmallVector<NodeT *, IsPostDom ? 4 : 1> Roots;
@@ -463,6 +503,39 @@ class DominatorTreeBase {
463503
// API to update (Post)DominatorTree information based on modifications to
464504
// the CFG...
465505

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+
466539
/// Inform the dominator tree about a CFG edge insertion and update the tree.
467540
///
468541
/// This function has to be called just before or just after making the update
@@ -487,11 +560,6 @@ class DominatorTreeBase {
487560
/// DEBUG mode. There cannot be any other updates that the
488561
/// dominator tree doesn't know about.
489562
///
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-
///
495563
/// Note that for postdominators it automatically takes care of deleting
496564
/// a reverse edge internally (so there's no need to swap the parameters).
497565
///
@@ -678,7 +746,6 @@ class DominatorTreeBase {
678746

679747
/// recalculate - compute a dominator tree for the given function
680748
void recalculate(ParentType &Func) {
681-
reset();
682749
Parent = &Func;
683750
DomTreeBuilder::Calculate(*this);
684751
}

0 commit comments

Comments
 (0)