Skip to content

Commit

Permalink
[DomTree] Replace ChildrenGetter with GraphTraits over GraphDiff.
Browse files Browse the repository at this point in the history
Summary:
This replaces the ChildrenGetter inside the DominatorTree with
GraphTraits over a GraphDiff object, an object which encapsulated the
view of the previous CFG.
This also simplifies the extentions in clang which use DominatorTree, as
GraphDiff also filters nullptrs.

Reviewers: kuhar, dblaikie, NutshellySima

Subscribers: hiraditya, cfe-commits, llvm-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D77341
  • Loading branch information
alinas committed Apr 10, 2020
1 parent 37bcf2d commit a903749
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 235 deletions.
70 changes: 0 additions & 70 deletions clang/include/clang/Analysis/Analyses/Dominators.h
Expand Up @@ -275,76 +275,6 @@ class ControlDependencyCalculator : public ManagedAnalysis {

namespace llvm {

/// Clang's CFG contains nullpointers for unreachable succesors, e.g. when an
/// if statement's condition is always false, it's 'then' branch is represented
/// with a nullptr. This however will result in a nullpointer derefernece for
/// dominator tree calculation.
///
/// To circumvent this, let's just crudely specialize the children getters
/// used in LLVM's dominator tree builder.
namespace DomTreeBuilder {

using ClangCFGDomChildrenGetter =
SemiNCAInfo<clang::CFGDomTree::DominatorTreeBase>::ChildrenGetter<
/*Inverse=*/false>;

template <>
template <>
inline ClangCFGDomChildrenGetter::ResultTy ClangCFGDomChildrenGetter::Get(
clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/false>) {
auto RChildren = reverse(children<NodePtr>(N));
ResultTy Ret(RChildren.begin(), RChildren.end());
Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
return Ret;
}

using ClangCFGDomReverseChildrenGetter =
SemiNCAInfo<clang::CFGDomTree::DominatorTreeBase>::ChildrenGetter<
/*Inverse=*/true>;

template <>
template <>
inline ClangCFGDomReverseChildrenGetter::ResultTy
ClangCFGDomReverseChildrenGetter::Get(
clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/true>) {
auto IChildren = inverse_children<NodePtr>(N);
ResultTy Ret(IChildren.begin(), IChildren.end());
Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
return Ret;
}

using ClangCFGPostDomChildrenGetter =
SemiNCAInfo<clang::CFGPostDomTree::DominatorTreeBase>::ChildrenGetter<
/*Inverse=*/false>;

template <>
template <>
inline ClangCFGPostDomChildrenGetter::ResultTy
ClangCFGPostDomChildrenGetter::Get(
clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/false>) {
auto RChildren = reverse(children<NodePtr>(N));
ResultTy Ret(RChildren.begin(), RChildren.end());
Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
return Ret;
}

using ClangCFGPostDomReverseChildrenGetter =
SemiNCAInfo<clang::CFGPostDomTree::DominatorTreeBase>::ChildrenGetter<
/*Inverse=*/true>;

template <>
template <>
inline ClangCFGPostDomReverseChildrenGetter::ResultTy
ClangCFGPostDomReverseChildrenGetter::Get(
clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/true>) {
auto IChildren = inverse_children<NodePtr>(N);
ResultTy Ret(IChildren.begin(), IChildren.end());
Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
return Ret;
}

} // end of namespace DomTreeBuilder

//===-------------------------------------
/// DominatorTree GraphTraits specialization so the DominatorTree can be
/// iterable by generic graph iterators.
Expand Down
20 changes: 19 additions & 1 deletion llvm/include/llvm/IR/CFGDiff.h
Expand Up @@ -195,6 +195,23 @@ template <typename NodePtr, bool InverseGraph = false> class GraphDiff {
#endif
};

namespace detail {
template <typename Range>
auto reverse_if_helper(Range &&R, std::integral_constant<bool, false>) {
return std::forward<Range>(R);
}

template <typename Range>
auto reverse_if_helper(Range &&R, std::integral_constant<bool, true>) {
return llvm::reverse(std::forward<Range>(R));
}

template <bool B, typename Range> auto reverse_if(Range &&R) {
return reverse_if_helper(std::forward<Range>(R),
std::integral_constant<bool, B>{});
}
} // namespace detail

template <typename GraphT, bool InverseGraph = false, bool InverseEdge = false,
typename GT = GraphTraits<GraphT>>
struct CFGViewChildren {
Expand All @@ -211,9 +228,10 @@ struct CFGViewChildren {

// filter iterator init:
auto R = make_range(GT::child_begin(N.second), GT::child_end(N.second));
auto RR = detail::reverse_if<!InverseEdge>(R);
// This lambda is copied into the iterators and persists to callers, ensure
// captures are by value or otherwise have sufficient lifetime.
auto First = make_filter_range(makeChildRange(R, N.first), [N](NodeRef C) {
auto First = make_filter_range(makeChildRange(RR, N.first), [N](NodeRef C) {
return !C.first->ignoreChild(N.second, C.second, InverseEdge);
});

Expand Down
9 changes: 7 additions & 2 deletions llvm/include/llvm/IR/Dominators.h
Expand Up @@ -44,6 +44,9 @@ using BBPostDomTree = PostDomTreeBase<BasicBlock>;

using BBUpdates = ArrayRef<llvm::cfg::Update<BasicBlock *>>;

using BBDomTreeGraphDiff = GraphDiff<BasicBlock *, false>;
using BBPostDomTreeGraphDiff = GraphDiff<BasicBlock *, true>;

extern template void Calculate<BBDomTree>(BBDomTree &DT);
extern template void CalculateWithUpdates<BBDomTree>(BBDomTree &DT,
BBUpdates U);
Expand All @@ -62,8 +65,10 @@ extern template void DeleteEdge<BBPostDomTree>(BBPostDomTree &DT,
BasicBlock *From,
BasicBlock *To);

extern template void ApplyUpdates<BBDomTree>(BBDomTree &DT, BBUpdates);
extern template void ApplyUpdates<BBPostDomTree>(BBPostDomTree &DT, BBUpdates);
extern template void ApplyUpdates<BBDomTree>(BBDomTree &DT,
BBDomTreeGraphDiff &);
extern template void ApplyUpdates<BBPostDomTree>(BBPostDomTree &DT,
BBPostDomTreeGraphDiff &);

extern template bool Verify<BBDomTree>(const BBDomTree &DT,
BBDomTree::VerificationLevel VL);
Expand Down
11 changes: 8 additions & 3 deletions llvm/include/llvm/Support/GenericDomTree.h
Expand Up @@ -29,6 +29,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/CFGDiff.h"
#include "llvm/Support/CFGUpdate.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
Expand Down Expand Up @@ -205,7 +206,8 @@ void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,

template <typename DomTreeT>
void ApplyUpdates(DomTreeT &DT,
ArrayRef<typename DomTreeT::UpdateType> Updates);
GraphDiff<typename DomTreeT::NodePtr,
DomTreeT::IsPostDominator> &PreViewCFG);

template <typename DomTreeT>
bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL);
Expand Down Expand Up @@ -515,10 +517,13 @@ class DominatorTreeBase {
/// 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.
/// \param Updates An unordered sequence of updates to perform. The current
/// CFG and the reverse of these updates provides the pre-view of the CFG.
///
void applyUpdates(ArrayRef<UpdateType> Updates) {
DomTreeBuilder::ApplyUpdates(*this, Updates);
GraphDiff<NodePtr, IsPostDominator> PreViewCFG(
Updates, /*ReverseApplyUpdates=*/true);
DomTreeBuilder::ApplyUpdates(*this, PreViewCFG);
}

/// Inform the dominator tree about a CFG edge insertion and update the tree.
Expand Down

0 comments on commit a903749

Please sign in to comment.