blob: a98af2c462cdc6916c7bb03e263691648185a336 [file] [log] [blame]
Easwaran Ramand68aae22016-02-04 23:34:31 +00001//=-- Profilesummary.cpp - Profile summary computation ----------------------=//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains support for computing profile summary data.
11//
12//===----------------------------------------------------------------------===//
13
Dehao Chenf84b6302016-02-23 03:39:24 +000014#include "llvm/IR/Attributes.h"
15#include "llvm/IR/Function.h"
Easwaran Ramand68aae22016-02-04 23:34:31 +000016#include "llvm/ProfileData/InstrProf.h"
Easwaran Raman40ee23d2016-02-19 03:15:33 +000017#include "llvm/ProfileData/ProfileCommon.h"
18#include "llvm/ProfileData/SampleProf.h"
Easwaran Ramand68aae22016-02-04 23:34:31 +000019
20using namespace llvm;
21
Easwaran Raman40ee23d2016-02-19 03:15:33 +000022// A set of cutoff values. Each value, when divided by ProfileSummary::Scale
23// (which is 1000000) is a desired percentile of total counts.
24const std::vector<uint32_t> ProfileSummary::DefaultCutoffs(
25 {10000, /* 1% */
26 100000, /* 10% */
27 200000, 300000, 400000, 500000, 600000, 500000, 600000, 700000, 800000,
28 900000, 950000, 990000, 999000, 999900, 999990, 999999});
29
Easwaran Raman43095702016-02-17 18:18:47 +000030void InstrProfSummary::addRecord(const InstrProfRecord &R) {
31 addEntryCount(R.Counts[0]);
32 for (size_t I = 1, E = R.Counts.size(); I < E; ++I)
33 addInternalCount(R.Counts[I]);
Easwaran Ramand68aae22016-02-04 23:34:31 +000034}
35
Easwaran Raman40ee23d2016-02-19 03:15:33 +000036// To compute the detailed summary, we consider each line containing samples as
37// equivalent to a block with a count in the instrumented profile.
38void SampleProfileSummary::addRecord(const sampleprof::FunctionSamples &FS) {
39 NumFunctions++;
40 if (FS.getHeadSamples() > MaxHeadSamples)
41 MaxHeadSamples = FS.getHeadSamples();
42 for (const auto &I : FS.getBodySamples())
43 addCount(I.second.getSamples());
44}
45
Easwaran Ramand68aae22016-02-04 23:34:31 +000046// The argument to this method is a vector of cutoff percentages and the return
Easwaran Raman43095702016-02-17 18:18:47 +000047// value is a vector of (Cutoff, MinCount, NumCounts) triplets.
Easwaran Ramand68aae22016-02-04 23:34:31 +000048void ProfileSummary::computeDetailedSummary() {
49 if (DetailedSummaryCutoffs.empty())
50 return;
51 auto Iter = CountFrequencies.begin();
52 auto End = CountFrequencies.end();
53 std::sort(DetailedSummaryCutoffs.begin(), DetailedSummaryCutoffs.end());
54
Easwaran Raman43095702016-02-17 18:18:47 +000055 uint32_t CountsSeen = 0;
Easwaran Ramand68aae22016-02-04 23:34:31 +000056 uint64_t CurrSum = 0, Count = 0;
57
58 for (uint32_t Cutoff : DetailedSummaryCutoffs) {
59 assert(Cutoff <= 999999);
60 APInt Temp(128, TotalCount);
61 APInt N(128, Cutoff);
62 APInt D(128, ProfileSummary::Scale);
63 Temp *= N;
64 Temp = Temp.sdiv(D);
65 uint64_t DesiredCount = Temp.getZExtValue();
66 assert(DesiredCount <= TotalCount);
67 while (CurrSum < DesiredCount && Iter != End) {
68 Count = Iter->first;
69 uint32_t Freq = Iter->second;
70 CurrSum += (Count * Freq);
Easwaran Raman43095702016-02-17 18:18:47 +000071 CountsSeen += Freq;
Easwaran Ramand68aae22016-02-04 23:34:31 +000072 Iter++;
73 }
74 assert(CurrSum >= DesiredCount);
Easwaran Raman43095702016-02-17 18:18:47 +000075 ProfileSummaryEntry PSE = {Cutoff, Count, CountsSeen};
Easwaran Ramand68aae22016-02-04 23:34:31 +000076 DetailedSummary.push_back(PSE);
77 }
78}
79
Dehao Chenf84b6302016-02-23 03:39:24 +000080// Returns true if the function is a hot function.
81bool ProfileSummary::isFunctionHot(const Function *F) {
82 // FIXME: update when summary data is stored in module's metadata.
83 return false;
84}
85
86// Returns true if the function is a cold function.
87bool ProfileSummary::isFunctionUnlikely(const Function *F) {
88 if (F->hasFnAttribute(Attribute::Cold)) {
89 return true;
90 }
91 if (!F->getEntryCount()) {
92 return false;
93 }
94 // FIXME: update when summary data is stored in module's metadata.
95 return (*F->getEntryCount()) == 0;
96}
97
Easwaran Raman43095702016-02-17 18:18:47 +000098InstrProfSummary::InstrProfSummary(const IndexedInstrProf::Summary &S)
99 : ProfileSummary(), MaxInternalBlockCount(S.get(
100 IndexedInstrProf::Summary::MaxInternalBlockCount)),
Easwaran Ramand68aae22016-02-04 23:34:31 +0000101 MaxFunctionCount(S.get(IndexedInstrProf::Summary::MaxFunctionCount)),
Easwaran Ramand68aae22016-02-04 23:34:31 +0000102 NumFunctions(S.get(IndexedInstrProf::Summary::TotalNumFunctions)) {
Easwaran Raman43095702016-02-17 18:18:47 +0000103
104 TotalCount = S.get(IndexedInstrProf::Summary::TotalBlockCount);
105 MaxCount = S.get(IndexedInstrProf::Summary::MaxBlockCount);
106 NumCounts = S.get(IndexedInstrProf::Summary::TotalNumBlocks);
107
Easwaran Ramand68aae22016-02-04 23:34:31 +0000108 for (unsigned I = 0; I < S.NumCutoffEntries; I++) {
109 const IndexedInstrProf::Summary::Entry &Ent = S.getEntry(I);
110 DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
111 Ent.NumBlocks);
112 }
113}
Easwaran Raman43095702016-02-17 18:18:47 +0000114void InstrProfSummary::addEntryCount(uint64_t Count) {
115 addCount(Count);
116 NumFunctions++;
117 if (Count > MaxFunctionCount)
118 MaxFunctionCount = Count;
119}
120
121void InstrProfSummary::addInternalCount(uint64_t Count) {
122 addCount(Count);
123 if (Count > MaxInternalBlockCount)
124 MaxInternalBlockCount = Count;
125}