Files
archived-llvm/lib/LTO/SummaryBasedOptimizations.cpp
Easwaran Raman f1f1adc004 [ThinLTO] Compute synthetic function entry count
Summary:
This patch computes the synthetic function entry count on the whole
program callgraph (based on module summary) and writes the entry counts
to the summary. After function importing, this count gets attached to
the IR as metadata. Since it adds a new field to the summary, this bumps
up the version.

Reviewers: tejohnson

Subscribers: mehdi_amini, inglorion, llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@349076 91177308-0d34-0410-b5e6-96231b3b80d8
2018-12-13 19:54:27 +00:00

81 lines
2.9 KiB
C++

//==-SummaryBasedOptimizations.cpp - Optimizations based on ThinLTO summary-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements optimizations that are based on the module summaries.
// These optimizations are performed during the thinlink phase of the
// compilation.
//
//===----------------------------------------------------------------------===//
#include "llvm/LTO/SummaryBasedOptimizations.h"
#include "llvm/Analysis/SyntheticCountsUtils.h"
#include "llvm/IR/ModuleSummaryIndex.h"
using namespace llvm;
cl::opt<bool> ThinLTOSynthesizeEntryCounts(
"thinlto-synthesize-entry-counts", cl::init(false), cl::Hidden,
cl::desc("Synthesize entry counts based on the summary"));
extern cl::opt<int> InitialSyntheticCount;
static void initializeCounts(ModuleSummaryIndex &Index) {
auto Root = Index.calculateCallGraphRoot();
// Root is a fake node. All its successors are the actual roots of the
// callgraph.
// FIXME: This initializes the entry counts of only the root nodes. This makes
// sense when compiling a binary with ThinLTO, but for libraries any of the
// non-root nodes could be called from outside.
for (auto &C : Root.calls()) {
auto &V = C.first;
for (auto &GVS : V.getSummaryList()) {
auto S = GVS.get()->getBaseObject();
auto *F = cast<FunctionSummary>(S);
F->setEntryCount(InitialSyntheticCount);
}
}
}
void llvm::computeSyntheticCounts(ModuleSummaryIndex &Index) {
if (!ThinLTOSynthesizeEntryCounts)
return;
using Scaled64 = ScaledNumber<uint64_t>;
initializeCounts(Index);
auto GetCallSiteRelFreq = [](FunctionSummary::EdgeTy &Edge) {
return Scaled64(Edge.second.RelBlockFreq, -CalleeInfo::ScaleShift);
};
auto GetEntryCount = [](ValueInfo V) {
if (V.getSummaryList().size()) {
auto S = V.getSummaryList().front().get()->getBaseObject();
auto *F = cast<FunctionSummary>(S);
return F->entryCount();
} else {
return UINT64_C(0);
}
};
auto AddToEntryCount = [](ValueInfo V, uint64_t New) {
if (!V.getSummaryList().size())
return;
for (auto &GVS : V.getSummaryList()) {
auto S = GVS.get()->getBaseObject();
auto *F = cast<FunctionSummary>(S);
F->setEntryCount(SaturatingAdd(F->entryCount(), New));
}
};
// After initializing the counts in initializeCounts above, the counts have to
// be propagated across the combined callgraph.
// SyntheticCountsUtils::propagate takes care of this propagation on any
// callgraph that specialized GraphTraits.
SyntheticCountsUtils<ModuleSummaryIndex *>::propagate(
&Index, GetCallSiteRelFreq, GetEntryCount, AddToEntryCount);
Index.setHasSyntheticEntryCounts();
}