blob: 22766e5f07f544efc82ece5cdb308a1b4067133e [file] [log] [blame]
Easwaran Ramanbdf20262018-01-09 19:39:35 +00001//===--- SyntheticCountsUtils.cpp - synthetic counts propagation utils ---===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Easwaran Ramanbdf20262018-01-09 19:39:35 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file defines utilities for propagating synthetic counts.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/Analysis/SyntheticCountsUtils.h"
14#include "llvm/ADT/DenseSet.h"
15#include "llvm/ADT/SCCIterator.h"
Easwaran Ramanbdf20262018-01-09 19:39:35 +000016#include "llvm/Analysis/CallGraph.h"
17#include "llvm/IR/CallSite.h"
18#include "llvm/IR/Function.h"
19#include "llvm/IR/InstIterator.h"
20#include "llvm/IR/Instructions.h"
Easwaran Raman5a7056f2018-12-13 19:54:27 +000021#include "llvm/IR/ModuleSummaryIndex.h"
Easwaran Ramanbdf20262018-01-09 19:39:35 +000022
23using namespace llvm;
24
Easwaran Raman8410c372018-01-25 22:02:29 +000025// Given an SCC, propagate entry counts along the edge of the SCC nodes.
26template <typename CallGraphType>
27void SyntheticCountsUtils<CallGraphType>::propagateFromSCC(
Easwaran Ramanb45994b2019-01-09 20:10:27 +000028 const SccTy &SCC, GetProfCountTy GetProfCount, AddCountTy AddCount) {
Easwaran Ramanbdf20262018-01-09 19:39:35 +000029
Easwaran Raman5a7056f2018-12-13 19:54:27 +000030 DenseSet<NodeRef> SCCNodes;
Easwaran Raman8410c372018-01-25 22:02:29 +000031 SmallVector<std::pair<NodeRef, EdgeRef>, 8> SCCEdges, NonSCCEdges;
Easwaran Ramanbdf20262018-01-09 19:39:35 +000032
Easwaran Raman8410c372018-01-25 22:02:29 +000033 for (auto &Node : SCC)
34 SCCNodes.insert(Node);
35
36 // Partition the edges coming out of the SCC into those whose destination is
37 // in the SCC and the rest.
38 for (const auto &Node : SCCNodes) {
Easwaran Raman06a71532018-02-01 19:40:35 +000039 for (auto &E : children_edges<CallGraphType>(Node)) {
Easwaran Raman8410c372018-01-25 22:02:29 +000040 if (SCCNodes.count(CGT::edge_dest(E)))
41 SCCEdges.emplace_back(Node, E);
42 else
43 NonSCCEdges.emplace_back(Node, E);
Easwaran Ramanbdf20262018-01-09 19:39:35 +000044 }
Easwaran Raman8410c372018-01-25 22:02:29 +000045 }
Easwaran Ramanbdf20262018-01-09 19:39:35 +000046
Easwaran Raman8410c372018-01-25 22:02:29 +000047 // For nodes in the same SCC, update the counts in two steps:
48 // 1. Compute the additional count for each node by propagating the counts
49 // along all incoming edges to the node that originate from within the same
50 // SCC and summing them up.
51 // 2. Add the additional counts to the nodes in the SCC.
Easwaran Ramanbdf20262018-01-09 19:39:35 +000052 // This ensures that the order of
Easwaran Raman8410c372018-01-25 22:02:29 +000053 // traversal of nodes within the SCC doesn't affect the final result.
Easwaran Ramanbdf20262018-01-09 19:39:35 +000054
Easwaran Ramanb45994b2019-01-09 20:10:27 +000055 DenseMap<NodeRef, Scaled64> AdditionalCounts;
Easwaran Raman8410c372018-01-25 22:02:29 +000056 for (auto &E : SCCEdges) {
Easwaran Ramanb45994b2019-01-09 20:10:27 +000057 auto OptProfCount = GetProfCount(E.first, E.second);
58 if (!OptProfCount)
Easwaran Raman8410c372018-01-25 22:02:29 +000059 continue;
Easwaran Raman8410c372018-01-25 22:02:29 +000060 auto Callee = CGT::edge_dest(E.second);
Easwaran Ramanb45994b2019-01-09 20:10:27 +000061 AdditionalCounts[Callee] += OptProfCount.getValue();
Easwaran Ramanbdf20262018-01-09 19:39:35 +000062 }
63
Easwaran Raman8410c372018-01-25 22:02:29 +000064 // Update the counts for the nodes in the SCC.
Easwaran Ramanbdf20262018-01-09 19:39:35 +000065 for (auto &Entry : AdditionalCounts)
Easwaran Raman8410c372018-01-25 22:02:29 +000066 AddCount(Entry.first, Entry.second);
Easwaran Ramanbdf20262018-01-09 19:39:35 +000067
Easwaran Raman8410c372018-01-25 22:02:29 +000068 // Now update the counts for nodes outside the SCC.
69 for (auto &E : NonSCCEdges) {
Easwaran Ramanb45994b2019-01-09 20:10:27 +000070 auto OptProfCount = GetProfCount(E.first, E.second);
71 if (!OptProfCount)
Easwaran Raman8410c372018-01-25 22:02:29 +000072 continue;
Easwaran Raman8410c372018-01-25 22:02:29 +000073 auto Callee = CGT::edge_dest(E.second);
Easwaran Ramanb45994b2019-01-09 20:10:27 +000074 AddCount(Callee, OptProfCount.getValue());
Easwaran Ramanbdf20262018-01-09 19:39:35 +000075 }
76}
77
Easwaran Raman8410c372018-01-25 22:02:29 +000078/// Propgate synthetic entry counts on a callgraph \p CG.
Easwaran Ramanbdf20262018-01-09 19:39:35 +000079///
80/// This performs a reverse post-order traversal of the callgraph SCC. For each
Easwaran Raman8410c372018-01-25 22:02:29 +000081/// SCC, it first propagates the entry counts to the nodes within the SCC
Easwaran Ramanbdf20262018-01-09 19:39:35 +000082/// through call edges and updates them in one shot. Then the entry counts are
Easwaran Raman06a71532018-02-01 19:40:35 +000083/// propagated to nodes outside the SCC. This requires \p GraphTraits
Easwaran Raman8410c372018-01-25 22:02:29 +000084/// to have a specialization for \p CallGraphType.
Easwaran Ramanbdf20262018-01-09 19:39:35 +000085
Easwaran Raman8410c372018-01-25 22:02:29 +000086template <typename CallGraphType>
87void SyntheticCountsUtils<CallGraphType>::propagate(const CallGraphType &CG,
Easwaran Ramanb45994b2019-01-09 20:10:27 +000088 GetProfCountTy GetProfCount,
Easwaran Raman8410c372018-01-25 22:02:29 +000089 AddCountTy AddCount) {
90 std::vector<SccTy> SCCs;
Easwaran Ramanbdf20262018-01-09 19:39:35 +000091
Easwaran Raman8410c372018-01-25 22:02:29 +000092 // Collect all the SCCs.
93 for (auto I = scc_begin(CG); !I.isAtEnd(); ++I)
94 SCCs.push_back(*I);
Easwaran Ramanbdf20262018-01-09 19:39:35 +000095
Easwaran Raman8410c372018-01-25 22:02:29 +000096 // The callgraph-scc needs to be visited in top-down order for propagation.
97 // The scc iterator returns the scc in bottom-up order, so reverse the SCCs
98 // and call propagateFromSCC.
99 for (auto &SCC : reverse(SCCs))
Easwaran Ramanb45994b2019-01-09 20:10:27 +0000100 propagateFromSCC(SCC, GetProfCount, AddCount);
Easwaran Ramanbdf20262018-01-09 19:39:35 +0000101}
Easwaran Raman8410c372018-01-25 22:02:29 +0000102
103template class llvm::SyntheticCountsUtils<const CallGraph *>;
Easwaran Raman5a7056f2018-12-13 19:54:27 +0000104template class llvm::SyntheticCountsUtils<ModuleSummaryIndex *>;