diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/ProfileData/InstrProfWriter.h | 10 | ||||
-rw-r--r-- | llvm/include/llvm/ProfileData/MemProf.h | 9 | ||||
-rw-r--r-- | llvm/lib/ProfileData/InstrProfWriter.cpp | 42 | ||||
-rw-r--r-- | llvm/test/Transforms/PGOProfile/memprof.ll | 19 | ||||
-rw-r--r-- | llvm/tools/llvm-profdata/llvm-profdata.cpp | 12 |
5 files changed, 86 insertions, 6 deletions
diff --git a/llvm/include/llvm/ProfileData/InstrProfWriter.h b/llvm/include/llvm/ProfileData/InstrProfWriter.h index b8b6c68..559549b 100644 --- a/llvm/include/llvm/ProfileData/InstrProfWriter.h +++ b/llvm/include/llvm/ProfileData/InstrProfWriter.h @@ -78,12 +78,20 @@ private: // Whether to serialize the full schema. bool MemProfFullSchema; + // Whether to generated random memprof hotness for testing. + bool MemprofGenerateRandomHotness; + public: + // For memprof testing, random hotness can be assigned to the contexts if + // MemprofGenerateRandomHotness is enabled. The random seed can be either + // provided by MemprofGenerateRandomHotnessSeed, or if that is 0, one will be + // generated in the writer using the current time. InstrProfWriter( bool Sparse = false, uint64_t TemporalProfTraceReservoirSize = 0, uint64_t MaxTemporalProfTraceLength = 0, bool WritePrevVersion = false, memprof::IndexedVersion MemProfVersionRequested = memprof::Version0, - bool MemProfFullSchema = false); + bool MemProfFullSchema = false, bool MemprofGenerateRandomHotness = false, + unsigned MemprofGenerateRandomHotnessSeed = 0); ~InstrProfWriter(); StringMap<ProfilingData> &getProfileData() { return FunctionData; } diff --git a/llvm/include/llvm/ProfileData/MemProf.h b/llvm/include/llvm/ProfileData/MemProf.h index f8121d3..da2cc80 100644 --- a/llvm/include/llvm/ProfileData/MemProf.h +++ b/llvm/include/llvm/ProfileData/MemProf.h @@ -149,6 +149,15 @@ struct PortableMemInfoBlock { #include "llvm/ProfileData/MIBEntryDef.inc" #undef MIBEntryDef + // Define setters for each type which can be called by the writer. +#define MIBEntryDef(NameTag, Name, Type) \ + void set##Name(Type NewVal) { \ + assert(Schema[llvm::to_underlying(Meta::Name)]); \ + Name = NewVal; \ + } +#include "llvm/ProfileData/MIBEntryDef.inc" +#undef MIBEntryDef + void clear() { *this = PortableMemInfoBlock(); } bool operator==(const PortableMemInfoBlock &Other) const { diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp index 1a3721b..f092416 100644 --- a/llvm/lib/ProfileData/InstrProfWriter.cpp +++ b/llvm/lib/ProfileData/InstrProfWriter.cpp @@ -19,6 +19,7 @@ #include "llvm/ProfileData/InstrProf.h" #include "llvm/ProfileData/MemProf.h" #include "llvm/ProfileData/ProfileCommon.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compression.h" #include "llvm/Support/Endian.h" #include "llvm/Support/EndianStream.h" @@ -184,13 +185,25 @@ public: InstrProfWriter::InstrProfWriter( bool Sparse, uint64_t TemporalProfTraceReservoirSize, uint64_t MaxTemporalProfTraceLength, bool WritePrevVersion, - memprof::IndexedVersion MemProfVersionRequested, bool MemProfFullSchema) + memprof::IndexedVersion MemProfVersionRequested, bool MemProfFullSchema, + bool MemprofGenerateRandomHotness, + unsigned MemprofGenerateRandomHotnessSeed) : Sparse(Sparse), MaxTemporalProfTraceLength(MaxTemporalProfTraceLength), TemporalProfTraceReservoirSize(TemporalProfTraceReservoirSize), InfoObj(new InstrProfRecordWriterTrait()), WritePrevVersion(WritePrevVersion), MemProfVersionRequested(MemProfVersionRequested), - MemProfFullSchema(MemProfFullSchema) {} + MemProfFullSchema(MemProfFullSchema), + MemprofGenerateRandomHotness(MemprofGenerateRandomHotness) { + // Set up the random number seed if requested. + if (MemprofGenerateRandomHotness) { + unsigned seed = MemprofGenerateRandomHotnessSeed + ? MemprofGenerateRandomHotnessSeed + : std::time(nullptr); + errs() << "random hotness seed = " << seed << "\n"; + std::srand(seed); + } +} InstrProfWriter::~InstrProfWriter() { delete InfoObj; } @@ -273,13 +286,34 @@ void InstrProfWriter::addRecord(StringRef Name, uint64_t Hash, void InstrProfWriter::addMemProfRecord( const Function::GUID Id, const memprof::IndexedMemProfRecord &Record) { - auto [Iter, Inserted] = MemProfData.Records.insert({Id, Record}); + auto NewRecord = Record; + // Provoke random hotness values if requested. We specify the lifetime access + // density and lifetime length that will result in a cold or not cold hotness. + // See the logic in getAllocType() in Analysis/MemoryProfileInfo.cpp. + if (MemprofGenerateRandomHotness) { + for (auto &Alloc : NewRecord.AllocSites) { + // To get a not cold context, set the lifetime access density to the + // maximum value and the lifetime to 0. + uint64_t NewTLAD = std::numeric_limits<uint64_t>::max(); + uint64_t NewTL = 0; + bool IsCold = std::rand() % 2; + if (IsCold) { + // To get a cold context, set the lifetime access density to 0 and the + // lifetime to the maximum value. + NewTLAD = 0; + NewTL = std::numeric_limits<uint64_t>::max(); + } + Alloc.Info.setTotalLifetimeAccessDensity(NewTLAD); + Alloc.Info.setTotalLifetime(NewTL); + } + } + auto [Iter, Inserted] = MemProfData.Records.insert({Id, NewRecord}); // If we inserted a new record then we are done. if (Inserted) { return; } memprof::IndexedMemProfRecord &Existing = Iter->second; - Existing.merge(Record); + Existing.merge(NewRecord); } bool InstrProfWriter::addMemProfFrame(const memprof::FrameId Id, diff --git a/llvm/test/Transforms/PGOProfile/memprof.ll b/llvm/test/Transforms/PGOProfile/memprof.ll index e1457ca..205eeb8 100644 --- a/llvm/test/Transforms/PGOProfile/memprof.ll +++ b/llvm/test/Transforms/PGOProfile/memprof.ll @@ -66,6 +66,18 @@ ;; Check that the total sizes are reported if requested. ; RUN: opt < %s -passes='memprof-use<profile-filename=%t.memprofdata>' -pgo-warn-missing-function -S -memprof-report-hinted-sizes 2>&1 | FileCheck %s --check-prefixes=TOTALSIZES +;; Make sure we emit a random hotness seed if requested. +; RUN: llvm-profdata merge -memprof-random-hotness %S/Inputs/memprof.memprofraw --profiled-binary %S/Inputs/memprof.exe -o %t.memprofdatarand 2>&1 | FileCheck %s --check-prefix=RAND +; RAND: random hotness seed = +;; Can't check the exact values, but make sure applying the random profile +;; succeeds with the same stats +; RUN: opt < %s -passes='memprof-use<profile-filename=%t.memprofdatarand>' -pgo-warn-missing-function -S -stats 2>&1 | FileCheck %s --check-prefixes=ALL,MEMPROFONLY,MEMPROFSTATS + +;; Make sure we use a specific random hotness seed if requested. +; RUN: llvm-profdata merge -memprof-random-hotness -memprof-random-hotness-seed=1730170724 %S/Inputs/memprof.memprofraw --profiled-binary %S/Inputs/memprof.exe -o %t.memprofdatarand2 2>&1 | FileCheck %s --check-prefix=RAND2 +; RAND2: random hotness seed = 1730170724 +; RUN: opt < %s -passes='memprof-use<profile-filename=%t.memprofdatarand2>' -pgo-warn-missing-function -S -stats 2>&1 | FileCheck %s --check-prefixes=MEMPROFRAND2,ALL,MEMPROFONLY,MEMPROFSTATS + ; MEMPROFMATCHINFO: MemProf notcold context with id 1093248920606587996 has total profiled size 10 is matched ; MEMPROFMATCHINFO: MemProf notcold context with id 5725971306423925017 has total profiled size 10 is matched ; MEMPROFMATCHINFO: MemProf notcold context with id 6792096022461663180 has total profiled size 10 is matched @@ -372,6 +384,13 @@ for.end: ; preds = %for.cond ; MEMPROFNOCOLINFO: ![[C10]] = !{i64 -4535090212904553409} ; MEMPROFNOCOLINFO: ![[C11]] = !{i64 3577763375057267810} +;; For the specific random seed, this is the expected order of hotness +; MEMPROFRAND2: !"cold" +; MEMPROFRAND2: !"cold" +; MEMPROFRAND2: !"cold" +; MEMPROFRAND2: !"hot" +; MEMPROFRAND2: !"hot" + ; MEMPROFSTATS: 8 memprof - Number of alloc contexts in memory profile. ; MEMPROFSTATS: 10 memprof - Number of callsites in memory profile. ; MEMPROFSTATS: 6 memprof - Number of functions having valid memory profile. diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp index 59f0f1f..f7023aa 100644 --- a/llvm/tools/llvm-profdata/llvm-profdata.cpp +++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp @@ -342,6 +342,15 @@ cl::opt<bool> MemProfFullSchema( "memprof-full-schema", cl::Hidden, cl::sub(MergeSubcommand), cl::desc("Use the full schema for serialization"), cl::init(false)); +static cl::opt<bool> + MemprofGenerateRandomHotness("memprof-random-hotness", cl::init(false), + cl::Hidden, cl::sub(MergeSubcommand), + cl::desc("Generate random hotness values")); +static cl::opt<unsigned> MemprofGenerateRandomHotnessSeed( + "memprof-random-hotness-seed", cl::init(0), cl::Hidden, + cl::sub(MergeSubcommand), + cl::desc("Random hotness seed to use (0 to generate new seed)")); + // Options specific to overlap subcommand. cl::opt<std::string> BaseFilename(cl::Positional, cl::Required, cl::desc("<base profile file>"), @@ -641,7 +650,8 @@ struct WriterContext { SmallSet<instrprof_error, 4> &WriterErrorCodes, uint64_t ReservoirSize = 0, uint64_t MaxTraceLength = 0) : Writer(IsSparse, ReservoirSize, MaxTraceLength, DoWritePrevVersion, - MemProfVersionRequested, MemProfFullSchema), + MemProfVersionRequested, MemProfFullSchema, + MemprofGenerateRandomHotness, MemprofGenerateRandomHotnessSeed), ErrLock(ErrLock), WriterErrorCodes(WriterErrorCodes) {} }; |