1 //=-- ProfilesummaryBuilder.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 14 #include "llvm/IR/Attributes.h" 15 #include "llvm/IR/Function.h" 16 #include "llvm/IR/Metadata.h" 17 #include "llvm/IR/Type.h" 18 #include "llvm/ProfileData/InstrProf.h" 19 #include "llvm/ProfileData/ProfileCommon.h" 20 #include "llvm/ProfileData/SampleProf.h" 21 #include "llvm/Support/Casting.h" 22 23 using namespace llvm; 24 25 // A set of cutoff values. Each value, when divided by ProfileSummary::Scale 26 // (which is 1000000) is a desired percentile of total counts. 27 static const uint32_t DefaultCutoffsData[] = { 28 10000, /* 1% */ 29 100000, /* 10% */ 30 200000, 300000, 400000, 500000, 600000, 700000, 800000, 31 900000, 950000, 990000, 999000, 999900, 999990, 999999}; 32 const ArrayRef<uint32_t> ProfileSummaryBuilder::DefaultCutoffs = 33 DefaultCutoffsData; 34 35 void InstrProfSummaryBuilder::addRecord(const InstrProfRecord &R) { 36 // The first counter is not necessarily an entry count for IR 37 // instrumentation profiles. 38 // Eventually MaxFunctionCount will become obsolete and this can be 39 // removed. 40 addEntryCount(R.Counts[0]); 41 for (size_t I = 1, E = R.Counts.size(); I < E; ++I) 42 addInternalCount(R.Counts[I]); 43 } 44 45 // To compute the detailed summary, we consider each line containing samples as 46 // equivalent to a block with a count in the instrumented profile. 47 void SampleProfileSummaryBuilder::addRecord( 48 const sampleprof::FunctionSamples &FS) { 49 NumFunctions++; 50 if (FS.getHeadSamples() > MaxFunctionCount) 51 MaxFunctionCount = FS.getHeadSamples(); 52 for (const auto &I : FS.getBodySamples()) 53 addCount(I.second.getSamples()); 54 } 55 56 // The argument to this method is a vector of cutoff percentages and the return 57 // value is a vector of (Cutoff, MinCount, NumCounts) triplets. 58 void ProfileSummaryBuilder::computeDetailedSummary() { 59 if (DetailedSummaryCutoffs.empty()) 60 return; 61 llvm::sort(DetailedSummaryCutoffs); 62 auto Iter = CountFrequencies.begin(); 63 const auto End = CountFrequencies.end(); 64 65 uint32_t CountsSeen = 0; 66 uint64_t CurrSum = 0, Count = 0; 67 68 for (const uint32_t Cutoff : DetailedSummaryCutoffs) { 69 assert(Cutoff <= 999999); 70 APInt Temp(128, TotalCount); 71 APInt N(128, Cutoff); 72 APInt D(128, ProfileSummary::Scale); 73 Temp *= N; 74 Temp = Temp.sdiv(D); 75 uint64_t DesiredCount = Temp.getZExtValue(); 76 assert(DesiredCount <= TotalCount); 77 while (CurrSum < DesiredCount && Iter != End) { 78 Count = Iter->first; 79 uint32_t Freq = Iter->second; 80 CurrSum += (Count * Freq); 81 CountsSeen += Freq; 82 Iter++; 83 } 84 assert(CurrSum >= DesiredCount); 85 ProfileSummaryEntry PSE = {Cutoff, Count, CountsSeen}; 86 DetailedSummary.push_back(PSE); 87 } 88 } 89 90 std::unique_ptr<ProfileSummary> SampleProfileSummaryBuilder::getSummary() { 91 computeDetailedSummary(); 92 return llvm::make_unique<ProfileSummary>( 93 ProfileSummary::PSK_Sample, DetailedSummary, TotalCount, MaxCount, 0, 94 MaxFunctionCount, NumCounts, NumFunctions); 95 } 96 97 std::unique_ptr<ProfileSummary> InstrProfSummaryBuilder::getSummary() { 98 computeDetailedSummary(); 99 return llvm::make_unique<ProfileSummary>( 100 ProfileSummary::PSK_Instr, DetailedSummary, TotalCount, MaxCount, 101 MaxInternalBlockCount, MaxFunctionCount, NumCounts, NumFunctions); 102 } 103 104 void InstrProfSummaryBuilder::addEntryCount(uint64_t Count) { 105 addCount(Count); 106 NumFunctions++; 107 if (Count > MaxFunctionCount) 108 MaxFunctionCount = Count; 109 } 110 111 void InstrProfSummaryBuilder::addInternalCount(uint64_t Count) { 112 addCount(Count); 113 if (Count > MaxInternalBlockCount) 114 MaxInternalBlockCount = Count; 115 } 116