|
19 | 19 | #include "llvm/ProfileData/InstrProf.h" |
20 | 20 | #include "llvm/ProfileData/MemProf.h" |
21 | 21 | #include "llvm/ProfileData/ProfileCommon.h" |
| 22 | +#include "llvm/Support/CommandLine.h" |
22 | 23 | #include "llvm/Support/Compression.h" |
23 | 24 | #include "llvm/Support/Endian.h" |
24 | 25 | #include "llvm/Support/EndianStream.h" |
@@ -184,13 +185,25 @@ class InstrProfRecordWriterTrait { |
184 | 185 | InstrProfWriter::InstrProfWriter( |
185 | 186 | bool Sparse, uint64_t TemporalProfTraceReservoirSize, |
186 | 187 | uint64_t MaxTemporalProfTraceLength, bool WritePrevVersion, |
187 | | - memprof::IndexedVersion MemProfVersionRequested, bool MemProfFullSchema) |
| 188 | + memprof::IndexedVersion MemProfVersionRequested, bool MemProfFullSchema, |
| 189 | + bool MemprofGenerateRandomHotness, |
| 190 | + unsigned MemprofGenerateRandomHotnessSeed) |
188 | 191 | : Sparse(Sparse), MaxTemporalProfTraceLength(MaxTemporalProfTraceLength), |
189 | 192 | TemporalProfTraceReservoirSize(TemporalProfTraceReservoirSize), |
190 | 193 | InfoObj(new InstrProfRecordWriterTrait()), |
191 | 194 | WritePrevVersion(WritePrevVersion), |
192 | 195 | MemProfVersionRequested(MemProfVersionRequested), |
193 | | - MemProfFullSchema(MemProfFullSchema) {} |
| 196 | + MemProfFullSchema(MemProfFullSchema), |
| 197 | + MemprofGenerateRandomHotness(MemprofGenerateRandomHotness) { |
| 198 | + // Set up the random number seed if requested. |
| 199 | + if (MemprofGenerateRandomHotness) { |
| 200 | + unsigned seed = MemprofGenerateRandomHotnessSeed |
| 201 | + ? MemprofGenerateRandomHotnessSeed |
| 202 | + : std::time(nullptr); |
| 203 | + errs() << "random hotness seed = " << seed << "\n"; |
| 204 | + std::srand(seed); |
| 205 | + } |
| 206 | +} |
194 | 207 |
|
195 | 208 | InstrProfWriter::~InstrProfWriter() { delete InfoObj; } |
196 | 209 |
|
@@ -273,13 +286,34 @@ void InstrProfWriter::addRecord(StringRef Name, uint64_t Hash, |
273 | 286 |
|
274 | 287 | void InstrProfWriter::addMemProfRecord( |
275 | 288 | const Function::GUID Id, const memprof::IndexedMemProfRecord &Record) { |
276 | | - auto [Iter, Inserted] = MemProfData.Records.insert({Id, Record}); |
| 289 | + auto NewRecord = Record; |
| 290 | + // Provoke random hotness values if requested. We specify the lifetime access |
| 291 | + // density and lifetime length that will result in a cold or not cold hotness. |
| 292 | + // See the logic in getAllocType() in Analysis/MemoryProfileInfo.cpp. |
| 293 | + if (MemprofGenerateRandomHotness) { |
| 294 | + for (auto &Alloc : NewRecord.AllocSites) { |
| 295 | + // To get a not cold context, set the lifetime access density to the |
| 296 | + // maximum value and the lifetime to 0. |
| 297 | + uint64_t NewTLAD = std::numeric_limits<uint64_t>::max(); |
| 298 | + uint64_t NewTL = 0; |
| 299 | + bool IsCold = std::rand() % 2; |
| 300 | + if (IsCold) { |
| 301 | + // To get a cold context, set the lifetime access density to 0 and the |
| 302 | + // lifetime to the maximum value. |
| 303 | + NewTLAD = 0; |
| 304 | + NewTL = std::numeric_limits<uint64_t>::max(); |
| 305 | + } |
| 306 | + Alloc.Info.setTotalLifetimeAccessDensity(NewTLAD); |
| 307 | + Alloc.Info.setTotalLifetime(NewTL); |
| 308 | + } |
| 309 | + } |
| 310 | + auto [Iter, Inserted] = MemProfData.Records.insert({Id, NewRecord}); |
277 | 311 | // If we inserted a new record then we are done. |
278 | 312 | if (Inserted) { |
279 | 313 | return; |
280 | 314 | } |
281 | 315 | memprof::IndexedMemProfRecord &Existing = Iter->second; |
282 | | - Existing.merge(Record); |
| 316 | + Existing.merge(NewRecord); |
283 | 317 | } |
284 | 318 |
|
285 | 319 | bool InstrProfWriter::addMemProfFrame(const memprof::FrameId Id, |
|
0 commit comments