mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
18789746d3
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
114 lines
4.1 KiB
C++
114 lines
4.1 KiB
C++
//===--- SyntheticCountsUtils.cpp - synthetic counts propagation utils ---===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines utilities for propagating synthetic counts.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Analysis/SyntheticCountsUtils.h"
|
|
#include "llvm/ADT/DenseSet.h"
|
|
#include "llvm/ADT/SCCIterator.h"
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
|
#include "llvm/Analysis/CallGraph.h"
|
|
#include "llvm/IR/CallSite.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/IR/InstIterator.h"
|
|
#include "llvm/IR/Instructions.h"
|
|
|
|
using namespace llvm;
|
|
|
|
// Given an SCC, propagate entry counts along the edge of the SCC nodes.
|
|
template <typename CallGraphType>
|
|
void SyntheticCountsUtils<CallGraphType>::propagateFromSCC(
|
|
const SccTy &SCC, GetRelBBFreqTy GetRelBBFreq, GetCountTy GetCount,
|
|
AddCountTy AddCount) {
|
|
|
|
SmallPtrSet<NodeRef, 8> SCCNodes;
|
|
SmallVector<std::pair<NodeRef, EdgeRef>, 8> SCCEdges, NonSCCEdges;
|
|
|
|
for (auto &Node : SCC)
|
|
SCCNodes.insert(Node);
|
|
|
|
// 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 : children_edges<CallGraphType>(Node)) {
|
|
if (SCCNodes.count(CGT::edge_dest(E)))
|
|
SCCEdges.emplace_back(Node, E);
|
|
else
|
|
NonSCCEdges.emplace_back(Node, E);
|
|
}
|
|
}
|
|
|
|
// For nodes in the same SCC, update the counts in two steps:
|
|
// 1. Compute the additional count for each node by propagating the counts
|
|
// along all incoming edges to the node that originate from within the same
|
|
// SCC and summing them up.
|
|
// 2. Add the additional counts to the nodes in the SCC.
|
|
// This ensures that the order of
|
|
// traversal of nodes within the SCC doesn't affect the final result.
|
|
|
|
DenseMap<NodeRef, uint64_t> AdditionalCounts;
|
|
for (auto &E : SCCEdges) {
|
|
auto OptRelFreq = GetRelBBFreq(E.second);
|
|
if (!OptRelFreq)
|
|
continue;
|
|
Scaled64 RelFreq = OptRelFreq.getValue();
|
|
auto Caller = E.first;
|
|
auto Callee = CGT::edge_dest(E.second);
|
|
RelFreq *= Scaled64(GetCount(Caller), 0);
|
|
uint64_t AdditionalCount = RelFreq.toInt<uint64_t>();
|
|
AdditionalCounts[Callee] += AdditionalCount;
|
|
}
|
|
|
|
// Update the counts for the nodes in the SCC.
|
|
for (auto &Entry : AdditionalCounts)
|
|
AddCount(Entry.first, Entry.second);
|
|
|
|
// Now update the counts for nodes outside the SCC.
|
|
for (auto &E : NonSCCEdges) {
|
|
auto OptRelFreq = GetRelBBFreq(E.second);
|
|
if (!OptRelFreq)
|
|
continue;
|
|
Scaled64 RelFreq = OptRelFreq.getValue();
|
|
auto Caller = E.first;
|
|
auto Callee = CGT::edge_dest(E.second);
|
|
RelFreq *= Scaled64(GetCount(Caller), 0);
|
|
AddCount(Callee, RelFreq.toInt<uint64_t>());
|
|
}
|
|
}
|
|
|
|
/// Propgate synthetic entry counts on a callgraph \p CG.
|
|
///
|
|
/// 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 GraphTraits
|
|
/// to have a specialization for \p CallGraphType.
|
|
|
|
template <typename CallGraphType>
|
|
void SyntheticCountsUtils<CallGraphType>::propagate(const CallGraphType &CG,
|
|
GetRelBBFreqTy GetRelBBFreq,
|
|
GetCountTy GetCount,
|
|
AddCountTy AddCount) {
|
|
std::vector<SccTy> SCCs;
|
|
|
|
// Collect all the SCCs.
|
|
for (auto I = scc_begin(CG); !I.isAtEnd(); ++I)
|
|
SCCs.push_back(*I);
|
|
|
|
// The callgraph-scc needs to be visited in top-down order for propagation.
|
|
// The scc iterator returns the scc in bottom-up order, so reverse the SCCs
|
|
// and call propagateFromSCC.
|
|
for (auto &SCC : reverse(SCCs))
|
|
propagateFromSCC(SCC, GetRelBBFreq, GetCount, AddCount);
|
|
}
|
|
|
|
template class llvm::SyntheticCountsUtils<const CallGraph *>;
|