summaryrefslogtreecommitdiffstats
path: root/llvm/include/llvm/Support/GenericDomTree.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include/llvm/Support/GenericDomTree.h')
-rw-r--r--llvm/include/llvm/Support/GenericDomTree.h97
1 files changed, 82 insertions, 15 deletions
diff --git a/llvm/include/llvm/Support/GenericDomTree.h b/llvm/include/llvm/Support/GenericDomTree.h
index 9b102ffb203..066a61e1ec2 100644
--- a/llvm/include/llvm/Support/GenericDomTree.h
+++ b/llvm/include/llvm/Support/GenericDomTree.h
@@ -24,12 +24,6 @@
#ifndef LLVM_SUPPORT_GENERICDOMTREE_H
#define LLVM_SUPPORT_GENERICDOMTREE_H
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -38,6 +32,13 @@
#include <type_traits>
#include <utility>
#include <vector>
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/raw_ostream.h"
namespace llvm {
@@ -45,7 +46,7 @@ template <typename NodeT, bool IsPostDom>
class DominatorTreeBase;
namespace DomTreeBuilder {
-template <class DomTreeT>
+template <typename DomTreeT>
struct SemiNCAInfo;
} // namespace DomTreeBuilder
@@ -190,14 +191,48 @@ namespace DomTreeBuilder {
template <typename DomTreeT>
void Calculate(DomTreeT &DT);
-template <class DomTreeT>
+template <typename DomTreeT>
void InsertEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
typename DomTreeT::NodePtr To);
-template <class DomTreeT>
+template <typename DomTreeT>
void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
typename DomTreeT::NodePtr To);
+// UpdateKind and Update are used by the batch update API and it's easiest to
+// define them here.
+enum class UpdateKind : unsigned char { Insert, Delete };
+
+template <typename NodePtr>
+struct Update {
+ using NodeKindPair = PointerIntPair<NodePtr, 1, UpdateKind>;
+
+ NodePtr From;
+ NodeKindPair ToAndKind;
+
+ Update(UpdateKind Kind, NodePtr From, NodePtr To)
+ : From(From), ToAndKind(To, Kind) {}
+
+ UpdateKind getKind() const { return ToAndKind.getInt(); }
+ NodePtr getFrom() const { return From; }
+ NodePtr getTo() const { return ToAndKind.getPointer(); }
+ bool operator==(const Update &RHS) const {
+ return From == RHS.From && ToAndKind == RHS.ToAndKind;
+ }
+
+ friend raw_ostream &operator<<(raw_ostream &OS, const Update &U) {
+ OS << (U.getKind() == UpdateKind::Insert ? "Insert " : "Delete ");
+ U.getFrom()->printAsOperand(OS, false);
+ OS << " -> ";
+ U.getTo()->printAsOperand(OS, false);
+ return OS;
+ }
+};
+
+template <typename DomTreeT>
+void ApplyUpdates(DomTreeT &DT,
+ ArrayRef<typename DomTreeT::UpdateType> Updates);
+
template <typename DomTreeT>
bool Verify(const DomTreeT &DT);
} // namespace DomTreeBuilder
@@ -219,6 +254,11 @@ class DominatorTreeBase {
using ParentType = typename std::remove_pointer<ParentPtr>::type;
static constexpr bool IsPostDominator = IsPostDom;
+ using UpdateType = DomTreeBuilder::Update<NodePtr>;
+ using UpdateKind = DomTreeBuilder::UpdateKind;
+ static constexpr UpdateKind Insert = UpdateKind::Insert;
+ static constexpr UpdateKind Delete = UpdateKind::Delete;
+
protected:
// Dominators always have a single root, postdominators can have more.
SmallVector<NodeT *, IsPostDom ? 4 : 1> Roots;
@@ -463,6 +503,39 @@ class DominatorTreeBase {
// API to update (Post)DominatorTree information based on modifications to
// the CFG...
+ /// Inform the dominator tree about a sequence of CFG edge insertions and
+ /// deletions and perform a batch update on the tree.
+ ///
+ /// This function should be used when there were multiple CFG updates after
+ /// the last dominator tree update. It takes care of performing the updates
+ /// in sync with the CFG and optimizes away the redundant operations that
+ /// cancel each other.
+ /// The functions expects the sequence of updates to be balanced. Eg.:
+ /// - {{Insert, A, B}, {Delete, A, B}, {Insert, A, B}} is fine, because
+ /// logically it results in a single insertions.
+ /// - {{Insert, A, B}, {Insert, A, B}} is invalid, because it doesn't make
+ /// sense to insert the same edge twice.
+ ///
+ /// What's more, the functions assumes that it's safe to ask every node in the
+ /// CFG about its children and inverse children. This implies that deletions
+ /// of CFG edges must not delete the CFG nodes before calling this function.
+ ///
+ /// Batch updates should be generally faster when performing longer sequences
+ /// of updates than calling insertEdge/deleteEdge manually multiple times, as
+ /// they can reorder the updates and remove redundant ones internally.
+ ///
+ /// Note that for postdominators it automatically takes care of applying
+ /// updates on reverse edges internally (so there's no need to swap the
+ /// From and To pointers when constructing DominatorTree::UpdateType).
+ /// The type of updates is the same for DomTreeBase<T> and PostDomTreeBase<T>
+ /// with the same template parameter T.
+ ///
+ /// \param Updates An unordered sequence of updates to perform.
+ ///
+ void applyUpdates(ArrayRef<UpdateType> Updates) {
+ DomTreeBuilder::ApplyUpdates(*this, Updates);
+ }
+
/// Inform the dominator tree about a CFG edge insertion and update the tree.
///
/// This function has to be called just before or just after making the update
@@ -487,11 +560,6 @@ class DominatorTreeBase {
/// DEBUG mode. There cannot be any other updates that the
/// dominator tree doesn't know about.
///
- /// However, it is fine to perform multiple CFG deletions that make different
- /// subtrees forward-unreachable and to inform the DomTree about them all at
- /// the same time, as the incremental algorithm doesn't walk the tree above
- /// the NearestCommonDominator of a deleted edge
- ///
/// Note that for postdominators it automatically takes care of deleting
/// a reverse edge internally (so there's no need to swap the parameters).
///
@@ -678,7 +746,6 @@ public:
/// recalculate - compute a dominator tree for the given function
void recalculate(ParentType &Func) {
- reset();
Parent = &Func;
DomTreeBuilder::Calculate(*this);
}
OpenPOWER on IntegriCloud