File indexing completed on 2026-05-10 08:44:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef LLVM_PROFILEDATA_INSTRPROFCORRELATOR_H
0013 #define LLVM_PROFILEDATA_INSTRPROFCORRELATOR_H
0014
0015 #include "llvm/ADT/DenseSet.h"
0016 #include "llvm/Debuginfod/BuildIDFetcher.h"
0017 #include "llvm/Object/BuildID.h"
0018 #include "llvm/ProfileData/InstrProf.h"
0019 #include "llvm/Support/Error.h"
0020 #include "llvm/Support/MemoryBuffer.h"
0021 #include "llvm/Support/YAMLTraits.h"
0022 #include <optional>
0023 #include <vector>
0024
0025 namespace llvm {
0026 class DWARFContext;
0027 class DWARFDie;
0028 namespace object {
0029 class ObjectFile;
0030 }
0031
0032
0033
0034 class InstrProfCorrelator {
0035 public:
0036
0037
0038 enum ProfCorrelatorKind { NONE, DEBUG_INFO, BINARY };
0039
0040 static llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
0041 get(StringRef Filename, ProfCorrelatorKind FileKind,
0042 const object::BuildIDFetcher *BIDFetcher = nullptr,
0043 const ArrayRef<llvm::object::BuildID> BIs = {});
0044
0045
0046
0047
0048 virtual Error correlateProfileData(int MaxWarnings) = 0;
0049
0050
0051
0052 virtual Error dumpYaml(int MaxWarnings, raw_ostream &OS) = 0;
0053
0054
0055 std::optional<size_t> getDataSize() const;
0056
0057
0058 const char *getNamesPointer() const { return Names.c_str(); }
0059
0060
0061 size_t getNamesSize() const { return Names.size(); }
0062
0063
0064 uint64_t getCountersSectionSize() const {
0065 return Ctx->CountersSectionEnd - Ctx->CountersSectionStart;
0066 }
0067
0068 static const char *FunctionNameAttributeName;
0069 static const char *CFGHashAttributeName;
0070 static const char *NumCountersAttributeName;
0071
0072 enum InstrProfCorrelatorKind { CK_32Bit, CK_64Bit };
0073 InstrProfCorrelatorKind getKind() const { return Kind; }
0074 virtual ~InstrProfCorrelator() = default;
0075
0076 protected:
0077 struct Context {
0078 static llvm::Expected<std::unique_ptr<Context>>
0079 get(std::unique_ptr<MemoryBuffer> Buffer, const object::ObjectFile &Obj,
0080 ProfCorrelatorKind FileKind);
0081 std::unique_ptr<MemoryBuffer> Buffer;
0082
0083 uint64_t CountersSectionStart;
0084 uint64_t CountersSectionEnd;
0085
0086
0087 const char *DataStart;
0088 const char *DataEnd;
0089 const char *NameStart;
0090 size_t NameSize;
0091
0092 bool ShouldSwapBytes;
0093 };
0094 const std::unique_ptr<Context> Ctx;
0095
0096 InstrProfCorrelator(InstrProfCorrelatorKind K, std::unique_ptr<Context> Ctx)
0097 : Ctx(std::move(Ctx)), Kind(K) {}
0098
0099 std::string Names;
0100 std::vector<std::string> NamesVec;
0101
0102 struct Probe {
0103 std::string FunctionName;
0104 std::optional<std::string> LinkageName;
0105 yaml::Hex64 CFGHash;
0106 yaml::Hex64 CounterOffset;
0107 uint32_t NumCounters;
0108 std::optional<std::string> FilePath;
0109 std::optional<int> LineNumber;
0110 };
0111
0112 struct CorrelationData {
0113 std::vector<Probe> Probes;
0114 };
0115
0116 friend struct yaml::MappingTraits<Probe>;
0117 friend struct yaml::SequenceElementTraits<Probe>;
0118 friend struct yaml::MappingTraits<CorrelationData>;
0119
0120 private:
0121 static llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
0122 get(std::unique_ptr<MemoryBuffer> Buffer, ProfCorrelatorKind FileKind);
0123
0124 const InstrProfCorrelatorKind Kind;
0125 };
0126
0127
0128
0129 template <class IntPtrT>
0130 class InstrProfCorrelatorImpl : public InstrProfCorrelator {
0131 public:
0132 InstrProfCorrelatorImpl(std::unique_ptr<InstrProfCorrelator::Context> Ctx);
0133 static bool classof(const InstrProfCorrelator *C);
0134
0135
0136
0137 const RawInstrProf::ProfileData<IntPtrT> *getDataPointer() const {
0138 return Data.empty() ? nullptr : Data.data();
0139 }
0140
0141
0142 size_t getDataSize() const { return Data.size(); }
0143
0144 static llvm::Expected<std::unique_ptr<InstrProfCorrelatorImpl<IntPtrT>>>
0145 get(std::unique_ptr<InstrProfCorrelator::Context> Ctx,
0146 const object::ObjectFile &Obj, ProfCorrelatorKind FileKind);
0147
0148 protected:
0149 std::vector<RawInstrProf::ProfileData<IntPtrT>> Data;
0150
0151 Error correlateProfileData(int MaxWarnings) override;
0152 virtual void correlateProfileDataImpl(
0153 int MaxWarnings,
0154 InstrProfCorrelator::CorrelationData *Data = nullptr) = 0;
0155
0156 virtual Error correlateProfileNameImpl() = 0;
0157
0158 Error dumpYaml(int MaxWarnings, raw_ostream &OS) override;
0159
0160 void addDataProbe(uint64_t FunctionName, uint64_t CFGHash,
0161 IntPtrT CounterOffset, IntPtrT FunctionPtr,
0162 uint32_t NumCounters);
0163
0164
0165 template <class T> T maybeSwap(T Value) const {
0166 return Ctx->ShouldSwapBytes ? llvm::byteswap(Value) : Value;
0167 }
0168
0169 private:
0170 InstrProfCorrelatorImpl(InstrProfCorrelatorKind Kind,
0171 std::unique_ptr<InstrProfCorrelator::Context> Ctx)
0172 : InstrProfCorrelator(Kind, std::move(Ctx)){};
0173 llvm::DenseSet<IntPtrT> CounterOffsets;
0174 };
0175
0176
0177
0178 template <class IntPtrT>
0179 class DwarfInstrProfCorrelator : public InstrProfCorrelatorImpl<IntPtrT> {
0180 public:
0181 DwarfInstrProfCorrelator(std::unique_ptr<DWARFContext> DICtx,
0182 std::unique_ptr<InstrProfCorrelator::Context> Ctx)
0183 : InstrProfCorrelatorImpl<IntPtrT>(std::move(Ctx)),
0184 DICtx(std::move(DICtx)) {}
0185
0186 private:
0187 std::unique_ptr<DWARFContext> DICtx;
0188
0189
0190 std::optional<uint64_t> getLocation(const DWARFDie &Die) const;
0191
0192
0193
0194 static bool isDIEOfProbe(const DWARFDie &Die);
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223 void correlateProfileDataImpl(
0224 int MaxWarnings,
0225 InstrProfCorrelator::CorrelationData *Data = nullptr) override;
0226
0227 Error correlateProfileNameImpl() override;
0228 };
0229
0230
0231
0232 template <class IntPtrT>
0233 class BinaryInstrProfCorrelator : public InstrProfCorrelatorImpl<IntPtrT> {
0234 public:
0235 BinaryInstrProfCorrelator(std::unique_ptr<InstrProfCorrelator::Context> Ctx)
0236 : InstrProfCorrelatorImpl<IntPtrT>(std::move(Ctx)) {}
0237
0238
0239 const char *getNamesPointer() const { return this->Ctx.NameStart; }
0240
0241
0242 size_t getNamesSize() const { return this->Ctx.NameSize; }
0243
0244 private:
0245 void correlateProfileDataImpl(
0246 int MaxWarnings,
0247 InstrProfCorrelator::CorrelationData *Data = nullptr) override;
0248
0249 Error correlateProfileNameImpl() override;
0250 };
0251
0252 }
0253
0254 #endif