Easwaran Raman | d68aae2 | 2016-02-04 23:34:31 +0000 | [diff] [blame] | 1 | //=-- 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 Chen | f84b630 | 2016-02-23 03:39:24 +0000 | [diff] [blame^] | 14 | #include "llvm/IR/Attributes.h" |
| 15 | #include "llvm/IR/Function.h" |
Easwaran Raman | d68aae2 | 2016-02-04 23:34:31 +0000 | [diff] [blame] | 16 | #include "llvm/ProfileData/InstrProf.h" |
Easwaran Raman | 40ee23d | 2016-02-19 03:15:33 +0000 | [diff] [blame] | 17 | #include "llvm/ProfileData/ProfileCommon.h" |
| 18 | #include "llvm/ProfileData/SampleProf.h" |
Easwaran Raman | d68aae2 | 2016-02-04 23:34:31 +0000 | [diff] [blame] | 19 | |
| 20 | using namespace llvm; |
| 21 | |
Easwaran Raman | 40ee23d | 2016-02-19 03:15:33 +0000 | [diff] [blame] | 22 | // A set of cutoff values. Each value, when divided by ProfileSummary::Scale |
| 23 | // (which is 1000000) is a desired percentile of total counts. |
| 24 | const 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 Raman | 4309570 | 2016-02-17 18:18:47 +0000 | [diff] [blame] | 30 | void 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 Raman | d68aae2 | 2016-02-04 23:34:31 +0000 | [diff] [blame] | 34 | } |
| 35 | |
Easwaran Raman | 40ee23d | 2016-02-19 03:15:33 +0000 | [diff] [blame] | 36 | // To compute the detailed summary, we consider each line containing samples as |
| 37 | // equivalent to a block with a count in the instrumented profile. |
| 38 | void 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 Raman | d68aae2 | 2016-02-04 23:34:31 +0000 | [diff] [blame] | 46 | // The argument to this method is a vector of cutoff percentages and the return |
Easwaran Raman | 4309570 | 2016-02-17 18:18:47 +0000 | [diff] [blame] | 47 | // value is a vector of (Cutoff, MinCount, NumCounts) triplets. |
Easwaran Raman | d68aae2 | 2016-02-04 23:34:31 +0000 | [diff] [blame] | 48 | void 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 Raman | 4309570 | 2016-02-17 18:18:47 +0000 | [diff] [blame] | 55 | uint32_t CountsSeen = 0; |
Easwaran Raman | d68aae2 | 2016-02-04 23:34:31 +0000 | [diff] [blame] | 56 | 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 Raman | 4309570 | 2016-02-17 18:18:47 +0000 | [diff] [blame] | 71 | CountsSeen += Freq; |
Easwaran Raman | d68aae2 | 2016-02-04 23:34:31 +0000 | [diff] [blame] | 72 | Iter++; |
| 73 | } |
| 74 | assert(CurrSum >= DesiredCount); |
Easwaran Raman | 4309570 | 2016-02-17 18:18:47 +0000 | [diff] [blame] | 75 | ProfileSummaryEntry PSE = {Cutoff, Count, CountsSeen}; |
Easwaran Raman | d68aae2 | 2016-02-04 23:34:31 +0000 | [diff] [blame] | 76 | DetailedSummary.push_back(PSE); |
| 77 | } |
| 78 | } |
| 79 | |
Dehao Chen | f84b630 | 2016-02-23 03:39:24 +0000 | [diff] [blame^] | 80 | // Returns true if the function is a hot function. |
| 81 | bool 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. |
| 87 | bool 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 Raman | 4309570 | 2016-02-17 18:18:47 +0000 | [diff] [blame] | 98 | InstrProfSummary::InstrProfSummary(const IndexedInstrProf::Summary &S) |
| 99 | : ProfileSummary(), MaxInternalBlockCount(S.get( |
| 100 | IndexedInstrProf::Summary::MaxInternalBlockCount)), |
Easwaran Raman | d68aae2 | 2016-02-04 23:34:31 +0000 | [diff] [blame] | 101 | MaxFunctionCount(S.get(IndexedInstrProf::Summary::MaxFunctionCount)), |
Easwaran Raman | d68aae2 | 2016-02-04 23:34:31 +0000 | [diff] [blame] | 102 | NumFunctions(S.get(IndexedInstrProf::Summary::TotalNumFunctions)) { |
Easwaran Raman | 4309570 | 2016-02-17 18:18:47 +0000 | [diff] [blame] | 103 | |
| 104 | TotalCount = S.get(IndexedInstrProf::Summary::TotalBlockCount); |
| 105 | MaxCount = S.get(IndexedInstrProf::Summary::MaxBlockCount); |
| 106 | NumCounts = S.get(IndexedInstrProf::Summary::TotalNumBlocks); |
| 107 | |
Easwaran Raman | d68aae2 | 2016-02-04 23:34:31 +0000 | [diff] [blame] | 108 | 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 Raman | 4309570 | 2016-02-17 18:18:47 +0000 | [diff] [blame] | 114 | void InstrProfSummary::addEntryCount(uint64_t Count) { |
| 115 | addCount(Count); |
| 116 | NumFunctions++; |
| 117 | if (Count > MaxFunctionCount) |
| 118 | MaxFunctionCount = Count; |
| 119 | } |
| 120 | |
| 121 | void InstrProfSummary::addInternalCount(uint64_t Count) { |
| 122 | addCount(Count); |
| 123 | if (Count > MaxInternalBlockCount) |
| 124 | MaxInternalBlockCount = Count; |
| 125 | } |