File indexing completed on 2026-05-10 08:44:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_PROFILEDATA_INSTRPROFWRITER_H
0015 #define LLVM_PROFILEDATA_INSTRPROFWRITER_H
0016
0017 #include "llvm/ADT/DenseMap.h"
0018 #include "llvm/ADT/MapVector.h"
0019 #include "llvm/ADT/StringMap.h"
0020 #include "llvm/IR/GlobalValue.h"
0021 #include "llvm/Object/BuildID.h"
0022 #include "llvm/ProfileData/InstrProf.h"
0023 #include "llvm/ProfileData/MemProf.h"
0024 #include "llvm/Support/Error.h"
0025 #include <cstdint>
0026 #include <memory>
0027 #include <random>
0028
0029 namespace llvm {
0030
0031
0032 class InstrProfRecordWriterTrait;
0033 class ProfOStream;
0034 class MemoryBuffer;
0035 class raw_fd_ostream;
0036
0037 class InstrProfWriter {
0038 public:
0039 using ProfilingData = SmallDenseMap<uint64_t, InstrProfRecord>;
0040
0041 private:
0042 bool Sparse;
0043 StringMap<ProfilingData> FunctionData;
0044
0045 uint64_t MaxTemporalProfTraceLength;
0046
0047 uint64_t TemporalProfTraceReservoirSize;
0048
0049 uint64_t TemporalProfTraceStreamSize = 0;
0050
0051 SmallVector<TemporalProfTraceTy> TemporalProfTraces;
0052 std::mt19937 RNG;
0053
0054
0055 memprof::IndexedMemProfData MemProfData;
0056
0057
0058 std::vector<llvm::object::BuildID> BinaryIds;
0059
0060
0061 StringSet<> VTableNames;
0062
0063
0064 InstrProfKind ProfileKind = InstrProfKind::Unknown;
0065
0066 InstrProfRecordWriterTrait *InfoObj;
0067
0068
0069
0070
0071
0072
0073 bool WritePrevVersion = false;
0074
0075
0076 memprof::IndexedVersion MemProfVersionRequested;
0077
0078
0079 bool MemProfFullSchema;
0080
0081
0082 bool MemprofGenerateRandomHotness;
0083
0084 public:
0085
0086
0087
0088
0089 InstrProfWriter(bool Sparse = false,
0090 uint64_t TemporalProfTraceReservoirSize = 0,
0091 uint64_t MaxTemporalProfTraceLength = 0,
0092 bool WritePrevVersion = false,
0093 memprof::IndexedVersion MemProfVersionRequested =
0094 static_cast<memprof::IndexedVersion>(
0095 memprof::MinimumSupportedVersion),
0096 bool MemProfFullSchema = false,
0097 bool MemprofGenerateRandomHotness = false,
0098 unsigned MemprofGenerateRandomHotnessSeed = 0);
0099 ~InstrProfWriter();
0100
0101 StringMap<ProfilingData> &getProfileData() { return FunctionData; }
0102
0103
0104
0105
0106 void addRecord(NamedInstrProfRecord &&I, uint64_t Weight,
0107 function_ref<void(Error)> Warn);
0108 void addRecord(NamedInstrProfRecord &&I, function_ref<void(Error)> Warn) {
0109 addRecord(std::move(I), 1, Warn);
0110 }
0111 void addVTableName(StringRef VTableName) { VTableNames.insert(VTableName); }
0112
0113
0114
0115 void addTemporalProfileTraces(SmallVectorImpl<TemporalProfTraceTy> &SrcTraces,
0116 uint64_t SrcStreamSize);
0117
0118
0119 bool addMemProfData(memprof::IndexedMemProfData Incoming,
0120 function_ref<void(Error)> Warn);
0121
0122
0123 void addBinaryIds(ArrayRef<llvm::object::BuildID> BIs);
0124
0125
0126 void mergeRecordsFromWriter(InstrProfWriter &&IPW,
0127 function_ref<void(Error)> Warn);
0128
0129
0130 Error write(raw_fd_ostream &OS);
0131
0132
0133 Error write(raw_string_ostream &OS);
0134
0135
0136 Error writeText(raw_fd_ostream &OS);
0137
0138
0139 void writeTextTemporalProfTraceData(raw_fd_ostream &OS,
0140 InstrProfSymtab &Symtab);
0141
0142 Error validateRecord(const InstrProfRecord &Func);
0143
0144
0145 static void writeRecordInText(StringRef Name, uint64_t Hash,
0146 const InstrProfRecord &Counters,
0147 InstrProfSymtab &Symtab, raw_fd_ostream &OS);
0148
0149
0150 std::unique_ptr<MemoryBuffer> writeBuffer();
0151
0152
0153
0154 Error mergeProfileKind(const InstrProfKind Other) {
0155
0156
0157 if (ProfileKind == InstrProfKind::Unknown) {
0158 ProfileKind = Other;
0159 return Error::success();
0160 }
0161
0162
0163 auto testIncompatible = [&](InstrProfKind A, InstrProfKind B) {
0164 return (static_cast<bool>(ProfileKind & A) &&
0165 static_cast<bool>(Other & B)) ||
0166 (static_cast<bool>(ProfileKind & B) &&
0167 static_cast<bool>(Other & A));
0168 };
0169
0170
0171
0172 if (static_cast<bool>(
0173 (ProfileKind & InstrProfKind::FrontendInstrumentation) ^
0174 (Other & InstrProfKind::FrontendInstrumentation))) {
0175 return make_error<InstrProfError>(instrprof_error::unsupported_version);
0176 }
0177 if (testIncompatible(InstrProfKind::FunctionEntryOnly,
0178 InstrProfKind::FunctionEntryInstrumentation) ||
0179 testIncompatible(InstrProfKind::FunctionEntryOnly,
0180 InstrProfKind::LoopEntriesInstrumentation)) {
0181 return make_error<InstrProfError>(
0182 instrprof_error::unsupported_version,
0183 "cannot merge FunctionEntryOnly profiles and BB profiles together");
0184 }
0185
0186
0187 ProfileKind |= Other;
0188 return Error::success();
0189 }
0190
0191 InstrProfKind getProfileKind() const { return ProfileKind; }
0192
0193 bool hasSingleByteCoverage() const {
0194 return static_cast<bool>(ProfileKind & InstrProfKind::SingleByteCoverage);
0195 }
0196
0197
0198 void setValueProfDataEndianness(llvm::endianness Endianness);
0199 void setOutputSparse(bool Sparse);
0200 void setMemProfVersionRequested(memprof::IndexedVersion Version) {
0201 MemProfVersionRequested = Version;
0202 }
0203 void setMemProfFullSchema(bool Full) { MemProfFullSchema = Full; }
0204
0205
0206 void overlapRecord(NamedInstrProfRecord &&Other, OverlapStats &Overlap,
0207 OverlapStats &FuncLevelOverlap,
0208 const OverlapFuncFilters &FuncFilter);
0209
0210 private:
0211 void addRecord(StringRef Name, uint64_t Hash, InstrProfRecord &&I,
0212 uint64_t Weight, function_ref<void(Error)> Warn);
0213 bool shouldEncodeData(const ProfilingData &PD);
0214
0215 void addTemporalProfileTrace(TemporalProfTraceTy Trace);
0216
0217
0218 void addMemProfRecord(const GlobalValue::GUID Id,
0219 const memprof::IndexedMemProfRecord &Record);
0220
0221
0222
0223 bool addMemProfFrame(const memprof::FrameId, const memprof::Frame &F,
0224 function_ref<void(Error)> Warn);
0225
0226
0227
0228 bool addMemProfCallStack(const memprof::CallStackId CSId,
0229 const llvm::SmallVector<memprof::FrameId> &CallStack,
0230 function_ref<void(Error)> Warn);
0231
0232 Error writeImpl(ProfOStream &OS);
0233
0234
0235
0236
0237 uint64_t writeHeader(const IndexedInstrProf::Header &header,
0238 const bool WritePrevVersion, ProfOStream &OS);
0239
0240
0241 Error writeBinaryIds(ProfOStream &OS);
0242
0243
0244 Error writeVTableNames(ProfOStream &OS);
0245 };
0246
0247 }
0248
0249 #endif