#ifndef LLVM_PROFILEDATA_PROFILE_COMMON_H
#define LLVM_PROFILEDATA_PROFILE_COMMON_H
#include "llvm/ADT/APInt.h"
#include <cstdint>
#include <functional>
#include <map>
#include <vector>
#include "llvm/Support/Casting.h"
namespace llvm {
class Function;
namespace IndexedInstrProf {
struct Summary;
}
namespace sampleprof {
class FunctionSamples;
}
struct InstrProfRecord;
class LLVMContext;
class Metadata;
class MDTuple;
class MDNode;
inline const char *getHotSectionPrefix() { return ".hot"; }
inline const char *getUnlikelySectionPrefix() { return ".unlikely"; }
struct ProfileSummaryEntry {
uint32_t Cutoff; uint64_t MinCount; uint64_t NumCounts; ProfileSummaryEntry(uint32_t TheCutoff, uint64_t TheMinCount,
uint64_t TheNumCounts)
: Cutoff(TheCutoff), MinCount(TheMinCount), NumCounts(TheNumCounts) {}
};
typedef std::vector<ProfileSummaryEntry> SummaryEntryVector;
class ProfileSummary {
public:
enum Kind { PSK_Instr, PSK_Sample };
private:
const Kind PSK;
static const char *KindStr[2];
std::map<uint64_t, uint32_t, std::greater<uint64_t>> CountFrequencies;
protected:
SummaryEntryVector DetailedSummary;
std::vector<uint32_t> DetailedSummaryCutoffs;
uint64_t TotalCount, MaxCount;
uint32_t NumCounts;
ProfileSummary(Kind K, std::vector<uint32_t> Cutoffs)
: PSK(K), DetailedSummaryCutoffs(Cutoffs), TotalCount(0), MaxCount(0),
NumCounts(0) {}
ProfileSummary(Kind K) : PSK(K), TotalCount(0), MaxCount(0), NumCounts(0) {}
ProfileSummary(Kind K, SummaryEntryVector DetailedSummary,
uint64_t TotalCount, uint64_t MaxCount, uint32_t NumCounts)
: PSK(K), DetailedSummary(DetailedSummary), TotalCount(TotalCount),
MaxCount(MaxCount), NumCounts(NumCounts) {}
~ProfileSummary() = default;
inline void addCount(uint64_t Count);
virtual std::vector<Metadata *> getFormatSpecificMD(LLVMContext &Context) = 0;
Metadata *getDetailedSummaryMD(LLVMContext &Context);
public:
static const int Scale = 1000000;
Kind getKind() const { return PSK; }
const char *getKindStr() const { return KindStr[PSK]; }
static bool isFunctionHot(const Function *F);
static bool isFunctionUnlikely(const Function *F);
inline SummaryEntryVector &getDetailedSummary();
void computeDetailedSummary();
static const std::vector<uint32_t> DefaultCutoffs;
Metadata *getMD(LLVMContext &Context);
static ProfileSummary *getFromMD(Metadata *MD);
};
class InstrProfSummary final : public ProfileSummary {
uint64_t MaxInternalBlockCount, MaxFunctionCount;
uint32_t NumFunctions;
inline void addEntryCount(uint64_t Count);
inline void addInternalCount(uint64_t Count);
protected:
std::vector<Metadata *> getFormatSpecificMD(LLVMContext &Context) override;
public:
InstrProfSummary(std::vector<uint32_t> Cutoffs)
: ProfileSummary(PSK_Instr, Cutoffs), MaxInternalBlockCount(0),
MaxFunctionCount(0), NumFunctions(0) {}
InstrProfSummary(const IndexedInstrProf::Summary &S);
InstrProfSummary(uint64_t TotalCount, uint64_t MaxBlockCount,
uint64_t MaxInternalBlockCount, uint64_t MaxFunctionCount,
uint32_t NumBlocks, uint32_t NumFunctions,
SummaryEntryVector Summary)
: ProfileSummary(PSK_Instr, Summary, TotalCount, MaxBlockCount,
NumBlocks),
MaxInternalBlockCount(MaxInternalBlockCount),
MaxFunctionCount(MaxFunctionCount), NumFunctions(NumFunctions) {}
static bool classof(const ProfileSummary *PS) {
return PS->getKind() == PSK_Instr;
}
void addRecord(const InstrProfRecord &);
uint32_t getNumBlocks() { return NumCounts; }
uint64_t getTotalCount() { return TotalCount; }
uint32_t getNumFunctions() { return NumFunctions; }
uint64_t getMaxFunctionCount() { return MaxFunctionCount; }
uint64_t getMaxBlockCount() { return MaxCount; }
uint64_t getMaxInternalBlockCount() { return MaxInternalBlockCount; }
};
class SampleProfileSummary final : public ProfileSummary {
uint64_t MaxHeadSamples;
uint32_t NumFunctions;
protected:
std::vector<Metadata *> getFormatSpecificMD(LLVMContext &Context) override;
public:
uint32_t getNumLinesWithSamples() { return NumCounts; }
uint64_t getTotalSamples() { return TotalCount; }
uint32_t getNumFunctions() { return NumFunctions; }
uint64_t getMaxHeadSamples() { return MaxHeadSamples; }
uint64_t getMaxSamplesPerLine() { return MaxCount; }
void addRecord(const sampleprof::FunctionSamples &FS);
SampleProfileSummary(std::vector<uint32_t> Cutoffs)
: ProfileSummary(PSK_Sample, Cutoffs), MaxHeadSamples(0),
NumFunctions(0) {}
SampleProfileSummary(uint64_t TotalSamples, uint64_t MaxSamplesPerLine,
uint64_t MaxHeadSamples, int32_t NumLinesWithSamples,
uint32_t NumFunctions,
SummaryEntryVector DetailedSummary)
: ProfileSummary(PSK_Sample, DetailedSummary, TotalSamples,
MaxSamplesPerLine, NumLinesWithSamples),
MaxHeadSamples(MaxHeadSamples), NumFunctions(NumFunctions) {}
static bool classof(const ProfileSummary *PS) {
return PS->getKind() == PSK_Sample;
}
};
void ProfileSummary::addCount(uint64_t Count) {
TotalCount += Count;
if (Count > MaxCount)
MaxCount = Count;
NumCounts++;
CountFrequencies[Count]++;
}
SummaryEntryVector &ProfileSummary::getDetailedSummary() {
if (!DetailedSummaryCutoffs.empty() && DetailedSummary.empty())
computeDetailedSummary();
return DetailedSummary;
}
inline uint64_t getBlockProfileCount(uint64_t BlockFreq, uint64_t EntryFreq,
uint64_t EntryCount) {
APInt ScaledCount(128, EntryCount);
APInt BlockFreqAPInt(128, BlockFreq);
APInt EntryFreqAPInt(128, EntryFreq);
ScaledCount *= BlockFreqAPInt;
ScaledCount = ScaledCount.udiv(EntryFreqAPInt);
return ScaledCount.getLimitedValue();
}
} #endif