|
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