Mercurial > hg > CbC > CbC_llvm
view lib/Analysis/SyntheticCountsUtils.cpp @ 146:3fc4d5c3e21e
set tail call flag for code segment in CGCAll
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 23 Dec 2018 19:23:36 +0900 |
parents | 3a76565eade5 |
children | c2174574ed3a |
line wrap: on
line source
//===--- 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 *>;