Skip to content

Commit

Permalink
Remove CallGraphTraits and use equivalent methods in GraphTraits
Browse files Browse the repository at this point in the history
Summary:
D42698 adds child_edge_{begin|end} and children_edges to GraphTraits
which are used here. The reason for this change is to make it easy to
use count propagation on ModulesummaryIndex. As it stands,
CallGraphTraits is in Analysis while ModuleSummaryIndex is in IR.

Reviewers: davidxl, dberlin

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D42703

llvm-svn: 323994
  • Loading branch information
Easwaran Raman committed Feb 1, 2018
1 parent 27b2990 commit 06a7153
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 53 deletions.
59 changes: 9 additions & 50 deletions llvm/include/llvm/Analysis/CallGraph.h
Expand Up @@ -426,12 +426,14 @@ template <> struct GraphTraits<CallGraphNode *> {
template <> struct GraphTraits<const CallGraphNode *> {
using NodeRef = const CallGraphNode *;
using CGNPairTy = CallGraphNode::CallRecord;
using EdgeRef = const CallGraphNode::CallRecord &;

static NodeRef getEntryNode(const CallGraphNode *CGN) { return CGN; }
static const CallGraphNode *CGNGetValue(CGNPairTy P) { return P.second; }

using ChildIteratorType =
mapped_iterator<CallGraphNode::const_iterator, decltype(&CGNGetValue)>;
using ChildEdgeIteratorType = CallGraphNode::const_iterator;

static ChildIteratorType child_begin(NodeRef N) {
return ChildIteratorType(N->begin(), &CGNGetValue);
Expand All @@ -440,6 +442,13 @@ template <> struct GraphTraits<const CallGraphNode *> {
static ChildIteratorType child_end(NodeRef N) {
return ChildIteratorType(N->end(), &CGNGetValue);
}

static ChildEdgeIteratorType child_edge_begin(NodeRef N) {
return N->begin();
}
static ChildEdgeIteratorType child_edge_end(NodeRef N) { return N->end(); }

static NodeRef edge_dest(EdgeRef E) { return E.second; }
};

template <>
Expand Down Expand Up @@ -495,56 +504,6 @@ struct GraphTraits<const CallGraph *> : public GraphTraits<
}
};

// FIXME: The traits here are not limited to callgraphs and can be moved
// elsewhere including GraphTraits. They are left here because only algorithms
// that operate on Callgraphs currently use them. If other algorithms operating
// on a general graph need edge traversals, these can be moved.
template <class CallGraphType>
struct CallGraphTraits : public GraphTraits<CallGraphType> {
// Elements to provide:

// typedef EdgeRef - Type of Edge token in the graph, which should
// be cheap to copy.
// typedef CallEdgeIteratorType - Type used to iterate over children edges in
// graph, dereference to a EdgeRef.

// static CallEdgeIteratorType call_edge_begin(NodeRef)
// static CallEdgeIteratorType call_edge_end (NodeRef)
// Return iterators that point to the beginning and ending of the call
// edges list for the given callgraph node.
//
// static NodeRef edge_dest(EdgeRef)
// Return the destination node of an edge.

// If anyone tries to use this class without having an appropriate
// specialization, make an error. If you get this error, it's because you
// need to include the appropriate specialization of GraphTraits<> for your
// graph, or you need to define it for a new graph type. Either that or
// your argument to XXX_begin(...) is unknown or needs to have the proper .h
// file #include'd.
using CallEdgeIteratorType =
typename CallGraphType::UnknownCallGraphTypeError;
};

template <class GraphType>
iterator_range<typename CallGraphTraits<GraphType>::CallEdgeIteratorType>
call_edges(const typename CallGraphTraits<GraphType>::NodeRef &G) {
return make_range(CallGraphTraits<GraphType>::call_edge_begin(G),
CallGraphTraits<GraphType>::call_edge_end(G));
}

template <>
struct CallGraphTraits<const CallGraph *>
: public GraphTraits<const CallGraph *> {
using EdgeRef = const CallGraphNode::CallRecord &;
using CallEdgeIteratorType = CallGraphNode::const_iterator;

static CallEdgeIteratorType call_edge_begin(NodeRef N) { return N->begin(); }
static CallEdgeIteratorType call_edge_end(NodeRef N) { return N->end(); }

static NodeRef edge_dest(EdgeRef E) { return E.second; }
};

} // end namespace llvm

#endif // LLVM_ANALYSIS_CALLGRAPH_H
2 changes: 1 addition & 1 deletion llvm/include/llvm/Analysis/SyntheticCountsUtils.h
Expand Up @@ -31,7 +31,7 @@ class Function;
template <typename CallGraphType> class SyntheticCountsUtils {
public:
using Scaled64 = ScaledNumber<uint64_t>;
using CGT = CallGraphTraits<CallGraphType>;
using CGT = GraphTraits<CallGraphType>;
using NodeRef = typename CGT::NodeRef;
using EdgeRef = typename CGT::EdgeRef;
using SccTy = std::vector<NodeRef>;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Analysis/SyntheticCountsUtils.cpp
Expand Up @@ -38,7 +38,7 @@ void SyntheticCountsUtils<CallGraphType>::propagateFromSCC(
// Partition the edges coming out of the SCC into those whose destination is
// in the SCC and the rest.
for (const auto &Node : SCCNodes) {
for (auto &E : call_edges<CallGraphType>(Node)) {
for (auto &E : children_edges<CallGraphType>(Node)) {
if (SCCNodes.count(CGT::edge_dest(E)))
SCCEdges.emplace_back(Node, E);
else
Expand Down Expand Up @@ -89,7 +89,7 @@ void SyntheticCountsUtils<CallGraphType>::propagateFromSCC(
/// This performs a reverse post-order traversal of the callgraph SCC. For each
/// SCC, it first propagates the entry counts to the nodes within the SCC
/// through call edges and updates them in one shot. Then the entry counts are
/// propagated to nodes outside the SCC. This requires \p CallGraphTraits
/// propagated to nodes outside the SCC. This requires \p GraphTraits
/// to have a specialization for \p CallGraphType.

template <typename CallGraphType>
Expand Down

0 comments on commit 06a7153

Please sign in to comment.