Skip to content

Commit 0445c64

Browse files
alinasjoker-eph
authored andcommitted
[DomTree] Replace ChildrenGetter with GraphTraits over GraphDiff.
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. Re-land a903749 after moving CFGDiff.h to Support. Differential Revision: https://reviews.llvm.org/D77341
1 parent a5b9316 commit 0445c64

File tree

6 files changed

+102
-235
lines changed

6 files changed

+102
-235
lines changed

clang/include/clang/Analysis/Analyses/Dominators.h

-70
Original file line numberDiff line numberDiff line change
@@ -275,76 +275,6 @@ class ControlDependencyCalculator : public ManagedAnalysis {
275275

276276
namespace llvm {
277277

278-
/// Clang's CFG contains nullpointers for unreachable succesors, e.g. when an
279-
/// if statement's condition is always false, it's 'then' branch is represented
280-
/// with a nullptr. This however will result in a nullpointer derefernece for
281-
/// dominator tree calculation.
282-
///
283-
/// To circumvent this, let's just crudely specialize the children getters
284-
/// used in LLVM's dominator tree builder.
285-
namespace DomTreeBuilder {
286-
287-
using ClangCFGDomChildrenGetter =
288-
SemiNCAInfo<clang::CFGDomTree::DominatorTreeBase>::ChildrenGetter<
289-
/*Inverse=*/false>;
290-
291-
template <>
292-
template <>
293-
inline ClangCFGDomChildrenGetter::ResultTy ClangCFGDomChildrenGetter::Get(
294-
clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/false>) {
295-
auto RChildren = reverse(children<NodePtr>(N));
296-
ResultTy Ret(RChildren.begin(), RChildren.end());
297-
Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
298-
return Ret;
299-
}
300-
301-
using ClangCFGDomReverseChildrenGetter =
302-
SemiNCAInfo<clang::CFGDomTree::DominatorTreeBase>::ChildrenGetter<
303-
/*Inverse=*/true>;
304-
305-
template <>
306-
template <>
307-
inline ClangCFGDomReverseChildrenGetter::ResultTy
308-
ClangCFGDomReverseChildrenGetter::Get(
309-
clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/true>) {
310-
auto IChildren = inverse_children<NodePtr>(N);
311-
ResultTy Ret(IChildren.begin(), IChildren.end());
312-
Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
313-
return Ret;
314-
}
315-
316-
using ClangCFGPostDomChildrenGetter =
317-
SemiNCAInfo<clang::CFGPostDomTree::DominatorTreeBase>::ChildrenGetter<
318-
/*Inverse=*/false>;
319-
320-
template <>
321-
template <>
322-
inline ClangCFGPostDomChildrenGetter::ResultTy
323-
ClangCFGPostDomChildrenGetter::Get(
324-
clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/false>) {
325-
auto RChildren = reverse(children<NodePtr>(N));
326-
ResultTy Ret(RChildren.begin(), RChildren.end());
327-
Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
328-
return Ret;
329-
}
330-
331-
using ClangCFGPostDomReverseChildrenGetter =
332-
SemiNCAInfo<clang::CFGPostDomTree::DominatorTreeBase>::ChildrenGetter<
333-
/*Inverse=*/true>;
334-
335-
template <>
336-
template <>
337-
inline ClangCFGPostDomReverseChildrenGetter::ResultTy
338-
ClangCFGPostDomReverseChildrenGetter::Get(
339-
clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/true>) {
340-
auto IChildren = inverse_children<NodePtr>(N);
341-
ResultTy Ret(IChildren.begin(), IChildren.end());
342-
Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
343-
return Ret;
344-
}
345-
346-
} // end of namespace DomTreeBuilder
347-
348278
//===-------------------------------------
349279
/// DominatorTree GraphTraits specialization so the DominatorTree can be
350280
/// iterable by generic graph iterators.

llvm/include/llvm/IR/Dominators.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ using BBPostDomTree = PostDomTreeBase<BasicBlock>;
4444

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

47+
using BBDomTreeGraphDiff = GraphDiff<BasicBlock *, false>;
48+
using BBPostDomTreeGraphDiff = GraphDiff<BasicBlock *, true>;
49+
4750
extern template void Calculate<BBDomTree>(BBDomTree &DT);
4851
extern template void CalculateWithUpdates<BBDomTree>(BBDomTree &DT,
4952
BBUpdates U);
@@ -62,8 +65,10 @@ extern template void DeleteEdge<BBPostDomTree>(BBPostDomTree &DT,
6265
BasicBlock *From,
6366
BasicBlock *To);
6467

65-
extern template void ApplyUpdates<BBDomTree>(BBDomTree &DT, BBUpdates);
66-
extern template void ApplyUpdates<BBPostDomTree>(BBPostDomTree &DT, BBUpdates);
68+
extern template void ApplyUpdates<BBDomTree>(BBDomTree &DT,
69+
BBDomTreeGraphDiff &);
70+
extern template void ApplyUpdates<BBPostDomTree>(BBPostDomTree &DT,
71+
BBPostDomTreeGraphDiff &);
6772

6873
extern template bool Verify<BBDomTree>(const BBDomTree &DT,
6974
BBDomTree::VerificationLevel VL);

llvm/include/llvm/Support/CFGDiff.h

+19-1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,23 @@ template <typename NodePtr, bool InverseGraph = false> class GraphDiff {
194194
#endif
195195
};
196196

197+
namespace detail {
198+
template <typename Range>
199+
auto reverse_if_helper(Range &&R, std::integral_constant<bool, false>) {
200+
return std::forward<Range>(R);
201+
}
202+
203+
template <typename Range>
204+
auto reverse_if_helper(Range &&R, std::integral_constant<bool, true>) {
205+
return llvm::reverse(std::forward<Range>(R));
206+
}
207+
208+
template <bool B, typename Range> auto reverse_if(Range &&R) {
209+
return reverse_if_helper(std::forward<Range>(R),
210+
std::integral_constant<bool, B>{});
211+
}
212+
} // namespace detail
213+
197214
template <typename GraphT, bool InverseGraph = false, bool InverseEdge = false,
198215
typename GT = GraphTraits<GraphT>>
199216
struct CFGViewChildren {
@@ -210,9 +227,10 @@ struct CFGViewChildren {
210227

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

llvm/include/llvm/Support/GenericDomTree.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "llvm/ADT/STLExtras.h"
3030
#include "llvm/ADT/SmallPtrSet.h"
3131
#include "llvm/ADT/SmallVector.h"
32+
#include "llvm/Support/CFGDiff.h"
3233
#include "llvm/Support/CFGUpdate.h"
3334
#include "llvm/Support/raw_ostream.h"
3435
#include <algorithm>
@@ -205,7 +206,8 @@ void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
205206

206207
template <typename DomTreeT>
207208
void ApplyUpdates(DomTreeT &DT,
208-
ArrayRef<typename DomTreeT::UpdateType> Updates);
209+
GraphDiff<typename DomTreeT::NodePtr,
210+
DomTreeT::IsPostDominator> &PreViewCFG);
209211

210212
template <typename DomTreeT>
211213
bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL);
@@ -515,10 +517,13 @@ class DominatorTreeBase {
515517
/// The type of updates is the same for DomTreeBase<T> and PostDomTreeBase<T>
516518
/// with the same template parameter T.
517519
///
518-
/// \param Updates An unordered sequence of updates to perform.
520+
/// \param Updates An unordered sequence of updates to perform. The current
521+
/// CFG and the reverse of these updates provides the pre-view of the CFG.
519522
///
520523
void applyUpdates(ArrayRef<UpdateType> Updates) {
521-
DomTreeBuilder::ApplyUpdates(*this, Updates);
524+
GraphDiff<NodePtr, IsPostDominator> PreViewCFG(
525+
Updates, /*ReverseApplyUpdates=*/true);
526+
DomTreeBuilder::ApplyUpdates(*this, PreViewCFG);
522527
}
523528

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

0 commit comments

Comments
 (0)