aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
authorMatthew Weingarten <matt@weingarten.org>2024-06-26 08:37:22 -0700
committerGitHub <noreply@github.com>2024-06-26 08:37:22 -0700
commit30b93db5476e3ae2efdaba25fb53fcc3c081da77 (patch)
tree470b3fdc2acefeb16d837ac0f9e18fa191621b82 /llvm
parent3e1ebd77e4e9a772e4f06f12d19c64860fb1f070 (diff)
downloadllvm-30b93db5476e3ae2efdaba25fb53fcc3c081da77.zip
llvm-30b93db5476e3ae2efdaba25fb53fcc3c081da77.tar.gz
llvm-30b93db5476e3ae2efdaba25fb53fcc3c081da77.tar.bz2
[Memprof] Adds the option to collect AccessCountHistograms for memprof. (#94264)
Adds compile time flag -mllvm -memprof-histogram and runtime flag histogram=true|false to turn Histogram collection on and off. The -memprof-histogram flag relies on -memprof-use-callbacks=true to work. Updates shadow mapping logic in histogram mode from having one 8 byte counter for 64 bytes, to 1 byte for 8 bytes, capped at 255. Only supports this granularity as of now. Updates the RawMemprofReader and serializing MemoryInfoBlocks to binary format, including changing to a new version of the raw binary format from version 3 to version 4. Updates creating MemoryInfoBlocks with and without Histograms. When two MemoryInfoBlocks are merged, AccessCounts are summed up and the shorter Histogram is removed. Adds a memprof_histogram test case. Initial commit for adding AccessCountHistograms up until RawProfile for memprof
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/ProfileData/MIBEntryDef.inc2
-rw-r--r--llvm/include/llvm/ProfileData/MemProf.h7
-rw-r--r--llvm/include/llvm/ProfileData/MemProfData.inc31
-rw-r--r--llvm/include/llvm/ProfileData/MemProfReader.h8
-rw-r--r--llvm/lib/ProfileData/MemProfReader.cpp108
-rw-r--r--llvm/lib/Transforms/Instrumentation/MemProfiler.cpp41
-rwxr-xr-xllvm/test/Transforms/PGOProfile/Inputs/memprof.exebin1396000 -> 5281088 bytes
-rw-r--r--llvm/test/Transforms/PGOProfile/Inputs/memprof.memprofrawbin2352 -> 2456 bytes
-rwxr-xr-xllvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.exebin1520760 -> 5280864 bytes
-rw-r--r--llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.memprofrawbin2352 -> 2456 bytes
-rwxr-xr-xllvm/test/Transforms/PGOProfile/Inputs/memprof_internal_linkage.exebin1519520 -> 5279848 bytes
-rw-r--r--llvm/test/Transforms/PGOProfile/Inputs/memprof_internal_linkage.memprofrawbin1136 -> 968 bytes
-rwxr-xr-xllvm/test/Transforms/PGOProfile/Inputs/memprof_loop_unroll.exebin1578176 -> 5280664 bytes
-rw-r--r--llvm/test/Transforms/PGOProfile/Inputs/memprof_loop_unroll.memprofrawbin1328 -> 1168 bytes
-rwxr-xr-xllvm/test/Transforms/PGOProfile/Inputs/memprof_missing_leaf.exebin1519576 -> 5279784 bytes
-rw-r--r--llvm/test/Transforms/PGOProfile/Inputs/memprof_missing_leaf.memprofrawbin936 -> 960 bytes
-rw-r--r--llvm/test/Transforms/PGOProfile/memprof_internal_linkage.ll6
-rwxr-xr-xllvm/test/tools/llvm-profdata/Inputs/basic-histogram.memprofexebin0 -> 5283216 bytes
-rw-r--r--llvm/test/tools/llvm-profdata/Inputs/basic-histogram.memprofrawbin0 -> 75792 bytes
-rwxr-xr-xllvm/test/tools/llvm-profdata/Inputs/basic.memprofexebin1379856 -> 5276856 bytes
-rw-r--r--llvm/test/tools/llvm-profdata/Inputs/basic.memprofrawbin880 -> 1152 bytes
-rwxr-xr-xllvm/test/tools/llvm-profdata/Inputs/basic_v3.memprofexebin0 -> 1379856 bytes
-rw-r--r--llvm/test/tools/llvm-profdata/Inputs/basic_v3.memprofrawbin0 -> 880 bytes
-rwxr-xr-xllvm/test/tools/llvm-profdata/Inputs/buildid.memprofexebin1379880 -> 5276856 bytes
-rw-r--r--llvm/test/tools/llvm-profdata/Inputs/buildid.memprofrawbin880 -> 1152 bytes
-rwxr-xr-xllvm/test/tools/llvm-profdata/Inputs/inline.memprofexebin1380360 -> 5277456 bytes
-rw-r--r--llvm/test/tools/llvm-profdata/Inputs/inline.memprofrawbin720 -> 976 bytes
-rwxr-xr-xllvm/test/tools/llvm-profdata/Inputs/multi.memprofexebin1379872 -> 5276888 bytes
-rw-r--r--llvm/test/tools/llvm-profdata/Inputs/multi.memprofrawbin1408 -> 1920 bytes
-rwxr-xr-xllvm/test/tools/llvm-profdata/Inputs/padding-histogram.memprofexebin0 -> 5278536 bytes
-rw-r--r--llvm/test/tools/llvm-profdata/Inputs/padding-histogram.memprofrawbin0 -> 74952 bytes
-rwxr-xr-xllvm/test/tools/llvm-profdata/Inputs/pic.memprofexebin1382552 -> 5279688 bytes
-rw-r--r--llvm/test/tools/llvm-profdata/Inputs/pic.memprofrawbin880 -> 1152 bytes
-rwxr-xr-xllvm/test/tools/llvm-profdata/Inputs/update_memprof_inputs.sh203
-rw-r--r--llvm/test/tools/llvm-profdata/memprof-basic-histogram.test244
-rw-r--r--llvm/test/tools/llvm-profdata/memprof-basic.test6
-rw-r--r--llvm/test/tools/llvm-profdata/memprof-basic_v3.test102
-rw-r--r--llvm/test/tools/llvm-profdata/memprof-inline.test57
-rw-r--r--llvm/test/tools/llvm-profdata/memprof-multi.test2
-rw-r--r--llvm/test/tools/llvm-profdata/memprof-padding-histogram.test99
-rw-r--r--llvm/test/tools/llvm-profdata/memprof-pic.test7
-rw-r--r--llvm/unittests/ProfileData/MemProfTest.cpp6
42 files changed, 878 insertions, 51 deletions
diff --git a/llvm/include/llvm/ProfileData/MIBEntryDef.inc b/llvm/include/llvm/ProfileData/MIBEntryDef.inc
index 794163a..58c1fc4 100644
--- a/llvm/include/llvm/ProfileData/MIBEntryDef.inc
+++ b/llvm/include/llvm/ProfileData/MIBEntryDef.inc
@@ -51,3 +51,5 @@ MIBEntryDef(MaxAccessDensity = 22, MaxAccessDensity, uint32_t)
MIBEntryDef(TotalLifetimeAccessDensity = 23, TotalLifetimeAccessDensity, uint64_t)
MIBEntryDef(MinLifetimeAccessDensity = 24, MinLifetimeAccessDensity, uint32_t)
MIBEntryDef(MaxLifetimeAccessDensity = 25, MaxLifetimeAccessDensity, uint32_t)
+MIBEntryDef(AccessHistogramSize = 26, AccessHistogramSize, uint32_t)
+MIBEntryDef(AccessHistogram = 27, AccessHistogram, uintptr_t) \ No newline at end of file
diff --git a/llvm/include/llvm/ProfileData/MemProf.h b/llvm/include/llvm/ProfileData/MemProf.h
index 5cd74be..cee8e5e 100644
--- a/llvm/include/llvm/ProfileData/MemProf.h
+++ b/llvm/include/llvm/ProfileData/MemProf.h
@@ -124,6 +124,13 @@ struct PortableMemInfoBlock {
OS << " " << #Name << ": " << Name << "\n";
#include "llvm/ProfileData/MIBEntryDef.inc"
#undef MIBEntryDef
+ if (AccessHistogramSize > 0) {
+ OS << " " << "AccessHistogramValues" << ":";
+ for (uint32_t I = 0; I < AccessHistogramSize; ++I) {
+ OS << " " << ((uint64_t *)AccessHistogram)[I];
+ }
+ OS << "\n";
+ }
}
// Return the schema, only for unit tests.
diff --git a/llvm/include/llvm/ProfileData/MemProfData.inc b/llvm/include/llvm/ProfileData/MemProfData.inc
index b82a4ba..3f785bd 100644
--- a/llvm/include/llvm/ProfileData/MemProfData.inc
+++ b/llvm/include/llvm/ProfileData/MemProfData.inc
@@ -33,7 +33,13 @@
(uint64_t)'o' << 24 | (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129)
// The version number of the raw binary format.
-#define MEMPROF_RAW_VERSION 3ULL
+#define MEMPROF_RAW_VERSION 4ULL
+
+// Currently supported versions.
+#define MEMPROF_RAW_SUPPORTED_VERSIONS \
+ { 3ULL, 4ULL }
+
+#define MEMPROF_V3_MIB_SIZE 132ULL;
#define MEMPROF_BUILDID_MAX_SIZE 32ULL
@@ -119,7 +125,8 @@ MemInfoBlock() {
}
MemInfoBlock(uint32_t Size, uint64_t AccessCount, uint32_t AllocTs,
- uint32_t DeallocTs, uint32_t AllocCpu, uint32_t DeallocCpu)
+ uint32_t DeallocTs, uint32_t AllocCpu, uint32_t DeallocCpu,
+ uintptr_t Histogram, uint32_t HistogramSize)
: MemInfoBlock() {
AllocCount = 1U;
TotalAccessCount = AccessCount;
@@ -149,6 +156,8 @@ MemInfoBlock(uint32_t Size, uint64_t AccessCount, uint32_t AllocTs,
AllocCpuId = AllocCpu;
DeallocCpuId = DeallocCpu;
NumMigratedCpu = AllocCpuId != DeallocCpuId;
+ AccessHistogramSize = HistogramSize;
+ AccessHistogram = Histogram;
}
void Merge(const MemInfoBlock &newMIB) {
@@ -194,6 +203,24 @@ void Merge(const MemInfoBlock &newMIB) {
NumSameDeallocCpu += DeallocCpuId == newMIB.DeallocCpuId;
AllocCpuId = newMIB.AllocCpuId;
DeallocCpuId = newMIB.DeallocCpuId;
+
+ // For merging histograms, we always keep the longer histogram, and add
+ // values of shorter histogram to larger one.
+ uintptr_t ShorterHistogram;
+ uint32_t ShorterHistogramSize;
+ if (newMIB.AccessHistogramSize > AccessHistogramSize) {
+ ShorterHistogram = AccessHistogram;
+ ShorterHistogramSize = AccessHistogramSize;
+ // Swap histogram of current to larger histogram
+ AccessHistogram = newMIB.AccessHistogram;
+ AccessHistogramSize = newMIB.AccessHistogramSize;
+ } else {
+ ShorterHistogram = newMIB.AccessHistogram;
+ ShorterHistogramSize = newMIB.AccessHistogramSize;
+ }
+ for (size_t i = 0; i < ShorterHistogramSize; ++i) {
+ ((uint64_t *)AccessHistogram)[i] += ((uint64_t *)ShorterHistogram)[i];
+ }
}
#ifdef _MSC_VER
diff --git a/llvm/include/llvm/ProfileData/MemProfReader.h b/llvm/include/llvm/ProfileData/MemProfReader.h
index fbba6483..da2f14b 100644
--- a/llvm/include/llvm/ProfileData/MemProfReader.h
+++ b/llvm/include/llvm/ProfileData/MemProfReader.h
@@ -137,7 +137,7 @@ class RawMemProfReader final : public MemProfReader {
public:
RawMemProfReader(const RawMemProfReader &) = delete;
RawMemProfReader &operator=(const RawMemProfReader &) = delete;
- ~RawMemProfReader() override = default;
+ virtual ~RawMemProfReader() override;
// Prints the contents of the profile in YAML format.
void printYAML(raw_ostream &OS);
@@ -205,8 +205,14 @@ private:
object::SectionedAddress getModuleOffset(uint64_t VirtualAddress);
+ llvm::SmallVector<std::pair<uint64_t, MemInfoBlock>>
+ readMemInfoBlocks(const char *Ptr);
+
// The profiled binary.
object::OwningBinary<object::Binary> Binary;
+ // Version of raw memprof binary currently being read. Defaults to most up
+ // to date version.
+ uint64_t MemprofRawVersion = MEMPROF_RAW_VERSION;
// The preferred load address of the executable segment.
uint64_t PreferredTextSegmentAddress = 0;
// The base address of the text segment in the process during profiling.
diff --git a/llvm/lib/ProfileData/MemProfReader.cpp b/llvm/lib/ProfileData/MemProfReader.cpp
index de58cb6..9112e19 100644
--- a/llvm/lib/ProfileData/MemProfReader.cpp
+++ b/llvm/lib/ProfileData/MemProfReader.cpp
@@ -41,7 +41,6 @@
#include "llvm/Support/Path.h"
#define DEBUG_TYPE "memprof"
-
namespace llvm {
namespace memprof {
namespace {
@@ -68,7 +67,14 @@ Error checkBuffer(const MemoryBuffer &Buffer) {
const char *Next = Buffer.getBufferStart();
while (Next < Buffer.getBufferEnd()) {
const auto *H = reinterpret_cast<const Header *>(Next);
- if (H->Version != MEMPROF_RAW_VERSION) {
+
+ // Check if the version in header is among the supported versions.
+ bool IsSupported = false;
+ for (auto SupportedVersion : MEMPROF_RAW_SUPPORTED_VERSIONS) {
+ if (H->Version == SupportedVersion)
+ IsSupported = true;
+ }
+ if (!IsSupported) {
return make_error<InstrProfError>(instrprof_error::unsupported_version);
}
@@ -96,19 +102,63 @@ llvm::SmallVector<SegmentEntry> readSegmentEntries(const char *Ptr) {
}
llvm::SmallVector<std::pair<uint64_t, MemInfoBlock>>
-readMemInfoBlocks(const char *Ptr) {
+readMemInfoBlocksV3(const char *Ptr) {
using namespace support;
const uint64_t NumItemsToRead =
- endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
+ endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
+
llvm::SmallVector<std::pair<uint64_t, MemInfoBlock>> Items;
for (uint64_t I = 0; I < NumItemsToRead; I++) {
const uint64_t Id =
- endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
- const MemInfoBlock MIB = *reinterpret_cast<const MemInfoBlock *>(Ptr);
+ endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
+
+ // We cheat a bit here and remove the const from cast to set the
+ // Histogram Pointer to newly allocated buffer. We also cheat, since V3 and
+ // V4 do not have the same fields. V3 is missing AccessHistogramSize and
+ // AccessHistogram. This means we read "dirty" data in here, but it should
+ // not segfault, since there will be callstack data placed after this in the
+ // binary format.
+ MemInfoBlock MIB = *reinterpret_cast<const MemInfoBlock *>(Ptr);
+ // Overwrite dirty data.
+ MIB.AccessHistogramSize = 0;
+ MIB.AccessHistogram = 0;
+
Items.push_back({Id, MIB});
+ // Only increment by the size of MIB in V3.
+ Ptr += MEMPROF_V3_MIB_SIZE;
+ }
+ return Items;
+}
+
+llvm::SmallVector<std::pair<uint64_t, MemInfoBlock>>
+readMemInfoBlocksV4(const char *Ptr) {
+ using namespace support;
+
+ const uint64_t NumItemsToRead =
+ endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
+
+ llvm::SmallVector<std::pair<uint64_t, MemInfoBlock>> Items;
+ for (uint64_t I = 0; I < NumItemsToRead; I++) {
+ const uint64_t Id =
+ endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
+ // We cheat a bit here and remove the const from cast to set the
+ // Histogram Pointer to newly allocated buffer.
+ MemInfoBlock MIB = *reinterpret_cast<const MemInfoBlock *>(Ptr);
+
// Only increment by size of MIB since readNext implicitly increments.
Ptr += sizeof(MemInfoBlock);
+
+ if (MIB.AccessHistogramSize > 0) {
+ MIB.AccessHistogram =
+ (uintptr_t)malloc(MIB.AccessHistogramSize * sizeof(uint64_t));
+ }
+
+ for (uint64_t J = 0; J < MIB.AccessHistogramSize; J++) {
+ ((uint64_t *)MIB.AccessHistogram)[J] =
+ endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
+ }
+ Items.push_back({Id, MIB});
}
return Items;
}
@@ -251,6 +301,16 @@ RawMemProfReader::create(std::unique_ptr<MemoryBuffer> Buffer,
return std::move(Reader);
}
+// We need to make sure that all leftover MIB histograms that have not been
+// freed by merge are freed here.
+RawMemProfReader::~RawMemProfReader() {
+ for (auto &[_, MIB] : CallstackProfileData) {
+ if (MemprofRawVersion >= 4ULL && MIB.AccessHistogramSize > 0) {
+ free((void *)MIB.AccessHistogram);
+ }
+ }
+}
+
bool RawMemProfReader::hasFormat(const StringRef Path) {
auto BufferOr = MemoryBuffer::getFileOrSTDIN(Path);
if (!BufferOr)
@@ -281,7 +341,7 @@ void RawMemProfReader::printYAML(raw_ostream &OS) {
OS << "MemprofProfile:\n";
OS << " Summary:\n";
- OS << " Version: " << MEMPROF_RAW_VERSION << "\n";
+ OS << " Version: " << MemprofRawVersion << "\n";
OS << " NumSegments: " << SegmentInfo.size() << "\n";
OS << " NumMibInfo: " << NumMibInfo << "\n";
OS << " NumAllocFunctions: " << NumAllocFunctions << "\n";
@@ -610,6 +670,20 @@ RawMemProfReader::peekBuildIds(MemoryBuffer *DataBuffer) {
return BuildIds.takeVector();
}
+// FIXME: Add a schema for serializing similiar to IndexedMemprofReader. This
+// will help being able to deserialize different versions raw memprof versions
+// more easily.
+llvm::SmallVector<std::pair<uint64_t, MemInfoBlock>>
+RawMemProfReader::readMemInfoBlocks(const char *Ptr) {
+ if (MemprofRawVersion == 3ULL)
+ return readMemInfoBlocksV3(Ptr);
+ else if (MemprofRawVersion == 4ULL)
+ return readMemInfoBlocksV4(Ptr);
+ else
+ assert(false &&
+ "Panic: Unsupported version number when reading MemInfoBlocks");
+}
+
Error RawMemProfReader::readRawProfile(
std::unique_ptr<MemoryBuffer> DataBuffer) {
const char *Next = DataBuffer->getBufferStart();
@@ -617,6 +691,10 @@ Error RawMemProfReader::readRawProfile(
while (Next < DataBuffer->getBufferEnd()) {
const auto *Header = reinterpret_cast<const memprof::Header *>(Next);
+ // Set Reader version to memprof raw version of profile. Checking if version
+ // is supported is checked before creating the reader.
+ MemprofRawVersion = Header->Version;
+
// Read in the segment information, check whether its the same across all
// profiles in this binary file.
const llvm::SmallVector<SegmentEntry> Entries =
@@ -636,7 +714,21 @@ Error RawMemProfReader::readRawProfile(
// stackdepot ids are the same.
for (const auto &[Id, MIB] : readMemInfoBlocks(Next + Header->MIBOffset)) {
if (CallstackProfileData.count(Id)) {
- CallstackProfileData[Id].Merge(MIB);
+
+ if (MemprofRawVersion >= 4ULL &&
+ (CallstackProfileData[Id].AccessHistogramSize > 0 ||
+ MIB.AccessHistogramSize > 0)) {
+ uintptr_t ShorterHistogram;
+ if (CallstackProfileData[Id].AccessHistogramSize >
+ MIB.AccessHistogramSize)
+ ShorterHistogram = MIB.AccessHistogram;
+ else
+ ShorterHistogram = CallstackProfileData[Id].AccessHistogram;
+ CallstackProfileData[Id].Merge(MIB);
+ free((void *)ShorterHistogram);
+ } else {
+ CallstackProfileData[Id].Merge(MIB);
+ }
} else {
CallstackProfileData[Id] = MIB;
}
diff --git a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
index 8a12fa1..1880928 100644
--- a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
@@ -77,6 +77,8 @@ constexpr char MemProfShadowMemoryDynamicAddress[] =
constexpr char MemProfFilenameVar[] = "__memprof_profile_filename";
+constexpr char MemProfHistogramFlagVar[] = "__memprof_histogram";
+
// Command-line flags.
static cl::opt<bool> ClInsertVersionCheck(
@@ -145,10 +147,14 @@ static cl::opt<int> ClDebugMax("memprof-debug-max", cl::desc("Debug max inst"),
// override these hints anyway.
static cl::opt<bool> ClMemProfMatchHotColdNew(
"memprof-match-hot-cold-new",
- cl::desc(
+ cl::desc(
"Match allocation profiles onto existing hot/cold operator new calls"),
cl::Hidden, cl::init(false));
+static cl::opt<bool> ClHistogram("memprof-histogram",
+ cl::desc("Collect access count histograms"),
+ cl::Hidden, cl::init(false));
+
static cl::opt<bool>
ClPrintMemProfMatchInfo("memprof-print-match-info",
cl::desc("Print matching stats for each allocation "
@@ -279,6 +285,11 @@ ModuleMemProfilerPass::ModuleMemProfilerPass() = default;
PreservedAnalyses ModuleMemProfilerPass::run(Module &M,
AnalysisManager<Module> &AM) {
+
+ assert((!ClHistogram || (ClHistogram && ClUseCalls)) &&
+ "Cannot use -memprof-histogram without Callbacks. Set "
+ "memprof-use-callbacks");
+
ModuleMemProfiler Profiler(M);
if (Profiler.instrumentModule(M))
return PreservedAnalyses::none();
@@ -508,7 +519,24 @@ void createProfileFileNameVar(Module &M) {
}
}
+// Set MemprofHistogramFlag as a Global veriable in IR. This makes it accessible
+// to the runtime, changing shadow count behavior.
+void createMemprofHistogramFlagVar(Module &M) {
+ const StringRef VarName(MemProfHistogramFlagVar);
+ Type *IntTy1 = Type::getInt1Ty(M.getContext());
+ auto MemprofHistogramFlag = new GlobalVariable(
+ M, IntTy1, true, GlobalValue::WeakAnyLinkage,
+ Constant::getIntegerValue(IntTy1, APInt(1, ClHistogram)), VarName);
+ Triple TT(M.getTargetTriple());
+ if (TT.supportsCOMDAT()) {
+ MemprofHistogramFlag->setLinkage(GlobalValue::ExternalLinkage);
+ MemprofHistogramFlag->setComdat(M.getOrInsertComdat(VarName));
+ }
+ appendToCompilerUsed(M, MemprofHistogramFlag);
+}
+
bool ModuleMemProfiler::instrumentModule(Module &M) {
+
// Create a module constructor.
std::string MemProfVersion = std::to_string(LLVM_MEM_PROFILER_VERSION);
std::string VersionCheckName =
@@ -524,6 +552,8 @@ bool ModuleMemProfiler::instrumentModule(Module &M) {
createProfileFileNameVar(M);
+ createMemprofHistogramFlagVar(M);
+
return true;
}
@@ -532,11 +562,12 @@ void MemProfiler::initializeCallbacks(Module &M) {
for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
const std::string TypeStr = AccessIsWrite ? "store" : "load";
+ const std::string HistPrefix = ClHistogram ? "hist_" : "";
SmallVector<Type *, 2> Args1{1, IntptrTy};
- MemProfMemoryAccessCallback[AccessIsWrite] =
- M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + TypeStr,
- FunctionType::get(IRB.getVoidTy(), Args1, false));
+ MemProfMemoryAccessCallback[AccessIsWrite] = M.getOrInsertFunction(
+ ClMemoryAccessCallbackPrefix + HistPrefix + TypeStr,
+ FunctionType::get(IRB.getVoidTy(), Args1, false));
}
MemProfMemmove = M.getOrInsertFunction(
ClMemoryAccessCallbackPrefix + "memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
@@ -1024,4 +1055,4 @@ PreservedAnalyses MemProfUsePass::run(Module &M, ModuleAnalysisManager &AM) {
}
return PreservedAnalyses::none();
-}
+} \ No newline at end of file
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof.exe b/llvm/test/Transforms/PGOProfile/Inputs/memprof.exe
index b10c2f9..361354d 100755
--- a/llvm/test/Transforms/PGOProfile/Inputs/memprof.exe
+++ b/llvm/test/Transforms/PGOProfile/Inputs/memprof.exe
Binary files differ
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof.memprofraw b/llvm/test/Transforms/PGOProfile/Inputs/memprof.memprofraw
index 790249a..1ff4352 100644
--- a/llvm/test/Transforms/PGOProfile/Inputs/memprof.memprofraw
+++ b/llvm/test/Transforms/PGOProfile/Inputs/memprof.memprofraw
Binary files differ
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.exe b/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.exe
index 3000e2b..e9e6897 100755
--- a/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.exe
+++ b/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.exe
Binary files differ
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.memprofraw b/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.memprofraw
index c0db6d2..1ff4f1d 100644
--- a/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.memprofraw
+++ b/llvm/test/Transforms/PGOProfile/Inputs/memprof.nocolinfo.memprofraw
Binary files differ
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof_internal_linkage.exe b/llvm/test/Transforms/PGOProfile/Inputs/memprof_internal_linkage.exe
index 6e0eaaf..c9f81fc 100755
--- a/llvm/test/Transforms/PGOProfile/Inputs/memprof_internal_linkage.exe
+++ b/llvm/test/Transforms/PGOProfile/Inputs/memprof_internal_linkage.exe
Binary files differ
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof_internal_linkage.memprofraw b/llvm/test/Transforms/PGOProfile/Inputs/memprof_internal_linkage.memprofraw
index 43bd116..c496a13 100644
--- a/llvm/test/Transforms/PGOProfile/Inputs/memprof_internal_linkage.memprofraw
+++ b/llvm/test/Transforms/PGOProfile/Inputs/memprof_internal_linkage.memprofraw
Binary files differ
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof_loop_unroll.exe b/llvm/test/Transforms/PGOProfile/Inputs/memprof_loop_unroll.exe
index 6bb4279..d555a8c 100755
--- a/llvm/test/Transforms/PGOProfile/Inputs/memprof_loop_unroll.exe
+++ b/llvm/test/Transforms/PGOProfile/Inputs/memprof_loop_unroll.exe
Binary files differ
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof_loop_unroll.memprofraw b/llvm/test/Transforms/PGOProfile/Inputs/memprof_loop_unroll.memprofraw
index e74f966..923d309 100644
--- a/llvm/test/Transforms/PGOProfile/Inputs/memprof_loop_unroll.memprofraw
+++ b/llvm/test/Transforms/PGOProfile/Inputs/memprof_loop_unroll.memprofraw
Binary files differ
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof_missing_leaf.exe b/llvm/test/Transforms/PGOProfile/Inputs/memprof_missing_leaf.exe
index 212f8f8..1b4ca7f 100755
--- a/llvm/test/Transforms/PGOProfile/Inputs/memprof_missing_leaf.exe
+++ b/llvm/test/Transforms/PGOProfile/Inputs/memprof_missing_leaf.exe
Binary files differ
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/memprof_missing_leaf.memprofraw b/llvm/test/Transforms/PGOProfile/Inputs/memprof_missing_leaf.memprofraw
index 3a06639..a2cfc3f 100644
--- a/llvm/test/Transforms/PGOProfile/Inputs/memprof_missing_leaf.memprofraw
+++ b/llvm/test/Transforms/PGOProfile/Inputs/memprof_missing_leaf.memprofraw
Binary files differ
diff --git a/llvm/test/Transforms/PGOProfile/memprof_internal_linkage.ll b/llvm/test/Transforms/PGOProfile/memprof_internal_linkage.ll
index 3d4b93c..3c4138f 100644
--- a/llvm/test/Transforms/PGOProfile/memprof_internal_linkage.ll
+++ b/llvm/test/Transforms/PGOProfile/memprof_internal_linkage.ll
@@ -28,12 +28,12 @@ entry:
store i32 0, ptr %retval, align 4
store i32 %argc, ptr %argc.addr, align 4
store ptr %argv, ptr %argv.addr, align 8
- call void @_ZL3foov.__uniq.231888424933890731874095357293037629092() #4, !dbg !14
+ call void @_ZL3foov.__uniq.50354172613129440706982166615384819716() #4, !dbg !14
ret i32 0, !dbg !15
}
; Function Attrs: mustprogress noinline optnone uwtable
-define internal void @_ZL3foov.__uniq.231888424933890731874095357293037629092() #1 !dbg !16 {
+define internal void @_ZL3foov.__uniq.50354172613129440706982166615384819716() #1 !dbg !16 {
entry:
%a = alloca ptr, align 8
%call = call noalias noundef nonnull ptr @_Znam(i64 noundef 20) #5, !dbg !17
@@ -76,7 +76,7 @@ attributes #5 = { builtin allocsize(0) }
!13 = !{}
!14 = !DILocation(line: 8, column: 3, scope: !10)
!15 = !DILocation(line: 9, column: 3, scope: !10)
-!16 = distinct !DISubprogram(name: "foo", linkageName: "_ZL3foov.__uniq.231888424933890731874095357293037629092", scope: !11, file: !11, line: 3, type: !12, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0)
+!16 = distinct !DISubprogram(name: "foo", linkageName: "_ZL3foov.__uniq.50354172613129440706982166615384819716", scope: !11, file: !11, line: 3, type: !12, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0)
!17 = !DILocation(line: 4, column: 12, scope: !16)
!18 = !DILocation(line: 4, column: 8, scope: !16)
!19 = !DILocation(line: 5, column: 10, scope: !16)
diff --git a/llvm/test/tools/llvm-profdata/Inputs/basic-histogram.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/basic-histogram.memprofexe
new file mode 100755
index 0000000..502472c
--- /dev/null
+++ b/llvm/test/tools/llvm-profdata/Inputs/basic-histogram.memprofexe
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/basic-histogram.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/basic-histogram.memprofraw
new file mode 100644
index 0000000..850da9e
--- /dev/null
+++ b/llvm/test/tools/llvm-profdata/Inputs/basic-histogram.memprofraw
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/basic.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/basic.memprofexe
index d03894b..32b52c8 100755
--- a/llvm/test/tools/llvm-profdata/Inputs/basic.memprofexe
+++ b/llvm/test/tools/llvm-profdata/Inputs/basic.memprofexe
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/basic.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/basic.memprofraw
index 62b7d29..dae9b4d 100644
--- a/llvm/test/tools/llvm-profdata/Inputs/basic.memprofraw
+++ b/llvm/test/tools/llvm-profdata/Inputs/basic.memprofraw
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/basic_v3.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/basic_v3.memprofexe
new file mode 100755
index 0000000..d03894b
--- /dev/null
+++ b/llvm/test/tools/llvm-profdata/Inputs/basic_v3.memprofexe
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/basic_v3.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/basic_v3.memprofraw
new file mode 100644
index 0000000..62b7d29
--- /dev/null
+++ b/llvm/test/tools/llvm-profdata/Inputs/basic_v3.memprofraw
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofexe
index 5687d06..3de26f6 100755
--- a/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofexe
+++ b/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofexe
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofraw
index 43f9ca9..56926cb 100644
--- a/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofraw
+++ b/llvm/test/tools/llvm-profdata/Inputs/buildid.memprofraw
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/inline.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/inline.memprofexe
index 766d2c47..2953080 100755
--- a/llvm/test/tools/llvm-profdata/Inputs/inline.memprofexe
+++ b/llvm/test/tools/llvm-profdata/Inputs/inline.memprofexe
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/inline.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/inline.memprofraw
index 26254ae..453b059 100644
--- a/llvm/test/tools/llvm-profdata/Inputs/inline.memprofraw
+++ b/llvm/test/tools/llvm-profdata/Inputs/inline.memprofraw
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/multi.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/multi.memprofexe
index d5c3ec6..3ba9f8a 100755
--- a/llvm/test/tools/llvm-profdata/Inputs/multi.memprofexe
+++ b/llvm/test/tools/llvm-profdata/Inputs/multi.memprofexe
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/multi.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/multi.memprofraw
index a1018aa..792edb7 100644
--- a/llvm/test/tools/llvm-profdata/Inputs/multi.memprofraw
+++ b/llvm/test/tools/llvm-profdata/Inputs/multi.memprofraw
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/padding-histogram.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/padding-histogram.memprofexe
new file mode 100755
index 0000000..fad3fc1
--- /dev/null
+++ b/llvm/test/tools/llvm-profdata/Inputs/padding-histogram.memprofexe
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/padding-histogram.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/padding-histogram.memprofraw
new file mode 100644
index 0000000..0d540ca
--- /dev/null
+++ b/llvm/test/tools/llvm-profdata/Inputs/padding-histogram.memprofraw
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/pic.memprofexe b/llvm/test/tools/llvm-profdata/Inputs/pic.memprofexe
index d854186..b92ed10 100755
--- a/llvm/test/tools/llvm-profdata/Inputs/pic.memprofexe
+++ b/llvm/test/tools/llvm-profdata/Inputs/pic.memprofexe
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/pic.memprofraw b/llvm/test/tools/llvm-profdata/Inputs/pic.memprofraw
index 992022f..1994b49 100644
--- a/llvm/test/tools/llvm-profdata/Inputs/pic.memprofraw
+++ b/llvm/test/tools/llvm-profdata/Inputs/pic.memprofraw
Binary files differ
diff --git a/llvm/test/tools/llvm-profdata/Inputs/update_memprof_inputs.sh b/llvm/test/tools/llvm-profdata/Inputs/update_memprof_inputs.sh
index 5365a0b..10c36a8 100755
--- a/llvm/test/tools/llvm-profdata/Inputs/update_memprof_inputs.sh
+++ b/llvm/test/tools/llvm-profdata/Inputs/update_memprof_inputs.sh
@@ -31,7 +31,7 @@ read -r -d '' INLINE << EOF
__attribute__((always_inline))
void qux(int x) {
- char *ptr = malloc(x);
+ char *ptr = (char*) malloc(x);
memset(ptr, 0, x);
free(ptr);
}
@@ -64,6 +64,190 @@ int main(int argc, char **argv) {
}
EOF
+read -r -d '' BASIC_HISTOGRAM << EOF
+struct A {
+ long int a;
+ long int b;
+ long int c;
+ long int d;
+ long int e;
+ long int f;
+ long int g;
+ long int h;
+ A() {};
+};
+
+void foo() {
+ long int acc = 0;
+ A *a = new A();
+ acc += a->a;
+ acc += a->b;
+ acc += a->c;
+ acc += a->d;
+ acc += a->e;
+ acc += a->f;
+ acc += a->g;
+ acc += a->h;
+ delete a;
+}
+void bar() {
+ long int acc = 0;
+ A *a = new A();
+ acc += a->a;
+ acc += a->a;
+ acc += a->a;
+ acc += a->a;
+ acc += a->a;
+ acc += a->a;
+ acc += a->a;
+ acc += a->a;
+ acc += a->b;
+ acc += a->b;
+ acc += a->b;
+ acc += a->b;
+ acc += a->b;
+ acc += a->b;
+ acc += a->b;
+ acc += a->c;
+ acc += a->c;
+ acc += a->c;
+ acc += a->c;
+ acc += a->c;
+ acc += a->c;
+ acc += a->d;
+ acc += a->d;
+ acc += a->d;
+ acc += a->d;
+ acc += a->d;
+ acc += a->e;
+ acc += a->e;
+ acc += a->e;
+ acc += a->e;
+ acc += a->f;
+ acc += a->f;
+ acc += a->f;
+ acc += a->g;
+ acc += a->g;
+ acc += a->h;
+
+ delete a;
+}
+
+int main(int argc, char **argv) {
+ long int acc = 0;
+ A *a = new A();
+ acc += a->a;
+ acc += a->b;
+ acc += a->c;
+ acc += a->d;
+ acc += a->e;
+ acc += a->f;
+ acc += a->g;
+ acc += a->h;
+
+ delete a;
+
+ A *b = new A();
+ acc += b->a;
+ acc += b->a;
+ acc += b->a;
+ acc += b->a;
+ acc += b->a;
+ acc += b->a;
+ acc += b->a;
+ acc += b->a;
+ acc += b->b;
+ acc += b->b;
+ acc += b->b;
+ acc += b->b;
+ acc += b->b;
+ acc += b->b;
+ acc += b->b;
+ acc += b->c;
+ acc += b->c;
+ acc += b->c;
+ acc += b->c;
+ acc += b->c;
+ acc += b->c;
+ acc += b->d;
+ acc += b->d;
+ acc += b->d;
+ acc += b->d;
+ acc += b->d;
+ acc += b->e;
+ acc += b->e;
+ acc += b->e;
+ acc += b->e;
+ acc += b->f;
+ acc += b->f;
+ acc += b->f;
+ acc += b->g;
+ acc += b->g;
+ acc += b->h;
+
+ delete b;
+
+ A *c = new A();
+ acc += c->a;
+
+ for (int i = 0; i < 21; ++i) {
+
+ foo();
+ }
+
+ for (int i = 0; i < 21; ++i) {
+
+ bar();
+ }
+
+ return 0;
+}
+EOF
+
+read -r -d '' PADDING_HISTOGRAM << EOF
+struct A {
+ char a;
+ char b;
+ long int c;
+ char d;
+ int e;
+ A() {};
+};
+
+struct B {
+ double x;
+ double y;
+ B() {};
+};
+
+struct C {
+ A a;
+ char z;
+ B b;
+ C() {};
+};
+
+int main(int argc, char **argv) {
+ long int acc = 0;
+
+ A *a = new A();
+ acc += a->a;
+ acc += a->b;
+ acc += a->c;
+ acc += a->d;
+ acc += a->e;
+
+ C *c = new C();
+ acc += c->a.a;
+ acc += c->a.a;
+ acc += c->b.x;
+ acc += c->b.y;
+
+ return 0;
+}
+EOF
+
+
DEFAULT_MEMPROF_FLAGS="-fuse-ld=lld -Wl,--no-rosegment -gmlt -fdebug-info-for-profiling -fmemory-profile -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls -m64 -Wl,-build-id -no-pie"
# Map each test to their source and any additional flags separated by ;
@@ -81,3 +265,20 @@ for name in "${!INPUTS[@]}"; do
env MEMPROF_OPTIONS=log_path=stdout ${OUTDIR}/${name}.memprofexe > ${OUTDIR}/${name}.memprofraw
rm ${OUTDIR}/${name}.c
done
+
+
+DEFAULT_HIST_FLAGS="${DEFAULT_MEMPROF_FLAGS} -mllvm -memprof-use-callbacks=true -mllvm -memprof-histogram"
+
+
+# Map each test to their source and any additional flags separated by ;
+declare -A HISTOGRAM_INPUTS
+HISTOGRAM_INPUTS["basic-histogram"]="BASIC_HISTOGRAM"
+HISTOGRAM_INPUTS["padding-histogram"]="PADDING_HISTOGRAM"
+
+for name in "${!HISTOGRAM_INPUTS[@]}"; do
+ IFS=";" read -r src flags <<< "${HISTOGRAM_INPUTS[$name]}"
+ echo "${!src}" > ${OUTDIR}/${name}.c
+ ${CLANG} ${DEFAULT_HIST_FLAGS} ${flags} ${OUTDIR}/${name}.c -o ${OUTDIR}/${name}.memprofexe
+ env MEMPROF_OPTIONS=log_path=stdout ${OUTDIR}/${name}.memprofexe > ${OUTDIR}/${name}.memprofraw
+ rm ${OUTDIR}/${name}.c
+done \ No newline at end of file
diff --git a/llvm/test/tools/llvm-profdata/memprof-basic-histogram.test b/llvm/test/tools/llvm-profdata/memprof-basic-histogram.test
new file mode 100644
index 0000000..3d30a62
--- /dev/null
+++ b/llvm/test/tools/llvm-profdata/memprof-basic-histogram.test
@@ -0,0 +1,244 @@
+REQUIRES: x86_64-linux
+
+To update the inputs used below run Inputs/update_memprof_inputs.sh /path/to/updated/clang
+RUN: llvm-profdata show --memory %p/Inputs/basic-histogram.memprofraw --profiled-binary %p/Inputs/basic-histogram.memprofexe -o - | FileCheck %s
+
+We expect 5 MIBs, each with different AccessHistogramValues.
+
+CHECK: MemprofProfile:
+CHECK-NEXT: Summary:
+CHECK-NEXT: Version: 4
+CHECK-NEXT: NumSegments: {{[0-9]+}}
+CHECK-NEXT: NumMibInfo: 5
+CHECK-NEXT: NumAllocFunctions: 3
+CHECK-NEXT: NumStackOffsets: 5
+CHECK-NEXT: Segments:
+CHECK-NEXT: -
+CHECK-NEXT: BuildId: {{[[:xdigit:]]+}}
+CHECK-NEXT: Start: 0x{{[[:xdigit:]]+}}
+CHECK-NEXT: End: 0x{{[[:xdigit:]]+}}
+CHECK-NEXT: Offset: 0x{{[[:xdigit:]]+}}
+CHECK-NEXT: -
+
+CHECK: Records:
+CHECK-NEXT: -
+CHECK-NEXT: FunctionGUID: {{[0-9]+}}
+CHECK-NEXT: AllocSites:
+CHECK-NEXT: -
+CHECK-NEXT: Callstack:
+CHECK-NEXT: -
+CHECK-NEXT: Function: {{[0-9]+}}
+CHECK-NEXT: SymbolName: main
+CHECK-NEXT: LineOffset: 2
+CHECK-NEXT: Column: 10
+CHECK-NEXT: Inline: 0
+CHECK-NEXT: MemInfoBlock:
+CHECK-NEXT: AllocCount: 1
+CHECK-NEXT: TotalAccessCount: 8
+CHECK-NEXT: MinAccessCount: 8
+CHECK-NEXT: MaxAccessCount: 8
+CHECK-NEXT: TotalSize: 64
+CHECK-NEXT: MinSize: 64
+CHECK-NEXT: MaxSize: 64
+CHECK-NEXT: AllocTimestamp: {{[0-9]+}}
+CHECK-NEXT: DeallocTimestamp: {{[0-9]+}}
+CHECK-NEXT: TotalLifetime: 0
+CHECK-NEXT: MinLifetime: 0
+CHECK-NEXT: MaxLifetime: 0
+CHECK-NEXT: AllocCpuId: {{[0-9]+}}
+CHECK-NEXT: DeallocCpuId: {{[0-9]+}}
+CHECK-NEXT: NumMigratedCpu: 0
+CHECK-NEXT: NumLifetimeOverlaps: 0
+CHECK-NEXT: NumSameAllocCpu: 0
+CHECK-NEXT: NumSameDeallocCpu: 0
+CHECK-NEXT: DataTypeId: {{[0-9]+}}
+CHECK-NEXT: TotalAccessDensity: 12
+CHECK-NEXT: MinAccessDensity: 12
+CHECK-NEXT: MaxAccessDensity: 12
+CHECK-NEXT: TotalLifetimeAccessDensity: 12000
+CHECK-NEXT: MinLifetimeAccessDensity: 12000
+CHECK-NEXT: MaxLifetimeAccessDensity: 12000
+CHECK-NEXT: AccessHistogramSize: 8
+CHECK-NEXT: AccessHistogram: {{[0-9]+}}
+CHECK-NEXT: AccessHistogramValues: 1 1 1 1 1 1 1 1
+CHECK-NEXT: -
+CHECK-NEXT: Callstack:
+CHECK-NEXT: -
+CHECK-NEXT: Function: {{[0-9]+}}
+CHECK-NEXT: SymbolName: main
+CHECK-NEXT: LineOffset: 14
+CHECK-NEXT: Column: 10
+CHECK-NEXT: Inline: 0
+CHECK-NEXT: MemInfoBlock:
+CHECK-NEXT: AllocCount: 1
+CHECK-NEXT: TotalAccessCount: 36
+CHECK-NEXT: MinAccessCount: 36
+CHECK-NEXT: MaxAccessCount: 36
+CHECK-NEXT: TotalSize: 64
+CHECK-NEXT: MinSize: 64
+CHECK-NEXT: MaxSize: 64
+CHECK-NEXT: AllocTimestamp: {{[0-9]+}}
+CHECK-NEXT: DeallocTimestamp: {{[0-9]+}}
+CHECK-NEXT: TotalLifetime: 0
+CHECK-NEXT: MinLifetime: 0
+CHECK-NEXT: MaxLifetime: 0
+CHECK-NEXT: AllocCpuId: {{[0-9]+}}
+CHECK-NEXT: DeallocCpuId: {{[0-9]+}}
+CHECK-NEXT: NumMigratedCpu: 0
+CHECK-NEXT: NumLifetimeOverlaps: 0
+CHECK-NEXT: NumSameAllocCpu: 0
+CHECK-NEXT: NumSameDeallocCpu: 0
+CHECK-NEXT: DataTypeId: {{[0-9]+}}
+CHECK-NEXT: TotalAccessDensity: 56
+CHECK-NEXT: MinAccessDensity: 56
+CHECK-NEXT: MaxAccessDensity: 56
+CHECK-NEXT: TotalLifetimeAccessDensity: 56000
+CHECK-NEXT: MinLifetimeAccessDensity: 56000
+CHECK-NEXT: MaxLifetimeAccessDensity: 56000
+CHECK-NEXT: AccessHistogramSize: 8
+CHECK-NEXT: AccessHistogram: {{[0-9]+}}
+CHECK-NEXT: AccessHistogramValues: 8 7 6 5 4 3 2 1
+CHECK-NEXT: -
+CHECK-NEXT: Callstack:
+CHECK-NEXT: -
+CHECK-NEXT: Function: {{[0-9]+}}
+CHECK-NEXT: SymbolName: main
+CHECK-NEXT: LineOffset: 54
+CHECK-NEXT: Column: 10
+CHECK-NEXT: Inline: 0
+CHECK-NEXT: MemInfoBlock:
+CHECK-NEXT: AllocCount: 1
+CHECK-NEXT: TotalAccessCount: 1
+CHECK-NEXT: MinAccessCount: 1
+CHECK-NEXT: MaxAccessCount: 1
+CHECK-NEXT: TotalSize: 64
+CHECK-NEXT: MinSize: 64
+CHECK-NEXT: MaxSize: 64
+CHECK-NEXT: AllocTimestamp: {{[0-9]+}}
+CHECK-NEXT: DeallocTimestamp: {{[0-9]+}}
+CHECK-NEXT: TotalLifetime: 0
+CHECK-NEXT: MinLifetime: 0
+CHECK-NEXT: MaxLifetime: 0
+CHECK-NEXT: AllocCpuId: {{[0-9]+}}
+CHECK-NEXT: DeallocCpuId: {{[0-9]+}}
+CHECK-NEXT: NumMigratedCpu: 0
+CHECK-NEXT: NumLifetimeOverlaps: 0
+CHECK-NEXT: NumSameAllocCpu: 0
+CHECK-NEXT: NumSameDeallocCpu: 0
+CHECK-NEXT: DataTypeId: {{[0-9]+}}
+CHECK-NEXT: TotalAccessDensity: 1
+CHECK-NEXT: MinAccessDensity: 1
+CHECK-NEXT: MaxAccessDensity: 1
+CHECK-NEXT: TotalLifetimeAccessDensity: 1000
+CHECK-NEXT: MinLifetimeAccessDensity: 1000
+CHECK-NEXT: MaxLifetimeAccessDensity: 1000
+CHECK-NEXT: AccessHistogramSize: 8
+CHECK-NEXT: AccessHistogram: {{[0-9]+}}
+CHECK-NEXT: AccessHistogramValues: 1 0 0 0 0 0 0 0
+CHECK-NEXT: CallSites:
+CHECK-NEXT: -
+CHECK-NEXT: -
+CHECK-NEXT: Function: {{[0-9]+}}
+CHECK-NEXT: SymbolName: main
+CHECK-NEXT: LineOffset: 59
+CHECK-NEXT: Column: 5
+CHECK-NEXT: Inline: 0
+CHECK-NEXT: -
+CHECK-NEXT: -
+CHECK-NEXT: Function: {{[0-9]+}}
+CHECK-NEXT: SymbolName: main
+CHECK-NEXT: LineOffset: 64
+CHECK-NEXT: Column: 5
+CHECK-NEXT: Inline: 0
+CHECK-NEXT: -
+CHECK-NEXT: FunctionGUID: {{[0-9]+}}
+CHECK-NEXT: AllocSites:
+CHECK-NEXT: -
+CHECK-NEXT: Callstack:
+CHECK-NEXT: -
+CHECK-NEXT: Function: {{[0-9]+}}
+CHECK-NEXT: SymbolName: _Z3foov
+CHECK-NEXT: LineOffset: 2
+CHECK-NEXT: Column: 10
+CHECK-NEXT: Inline: 0
+CHECK-NEXT: -
+CHECK-NEXT: Function: {{[0-9]+}}
+CHECK-NEXT: SymbolName: main
+CHECK-NEXT: LineOffset: 59
+CHECK-NEXT: Column: 5
+CHECK-NEXT: Inline: 0
+CHECK-NEXT: MemInfoBlock:
+CHECK-NEXT: AllocCount: 21
+CHECK-NEXT: TotalAccessCount: 168
+CHECK-NEXT: MinAccessCount: 8
+CHECK-NEXT: MaxAccessCount: 8
+CHECK-NEXT: TotalSize: 1344
+CHECK-NEXT: MinSize: 64
+CHECK-NEXT: MaxSize: 64
+CHECK-NEXT: AllocTimestamp: {{[0-9]+}}
+CHECK-NEXT: DeallocTimestamp: {{[0-9]+}}
+CHECK-NEXT: TotalLifetime: 0
+CHECK-NEXT: MinLifetime: 0
+CHECK-NEXT: MaxLifetime: 0
+CHECK-NEXT: AllocCpuId: {{[0-9]+}}
+CHECK-NEXT: DeallocCpuId: {{[0-9]+}}
+CHECK-NEXT: NumMigratedCpu: 0
+CHECK-NEXT: NumLifetimeOverlaps: 0
+CHECK-NEXT: NumSameAllocCpu: 20
+CHECK-NEXT: NumSameDeallocCpu: 20
+CHECK-NEXT: DataTypeId: {{[0-9]+}}
+CHECK-NEXT: TotalAccessDensity: 252
+CHECK-NEXT: MinAccessDensity: 12
+CHECK-NEXT: MaxAccessDensity: 12
+CHECK-NEXT: TotalLifetimeAccessDensity: 252000
+CHECK-NEXT: MinLifetimeAccessDensity: 12000
+CHECK-NEXT: MaxLifetimeAccessDensity: 12000
+CHECK-NEXT: AccessHistogramSize: 8
+CHECK-NEXT: AccessHistogram: {{[0-9]+}}
+CHECK-NEXT: AccessHistogramValues: 21 21 21 21 21 21 21 21
+CHECK-NEXT: -
+CHECK-NEXT: FunctionGUID: {{[0-9]+}}
+CHECK-NEXT: AllocSites:
+CHECK-NEXT: -
+CHECK-NEXT: Callstack:
+CHECK-NEXT: -
+CHECK-NEXT: Function: {{[0-9]+}}
+CHECK-NEXT: SymbolName: _Z3barv
+CHECK-NEXT: LineOffset: 2
+CHECK-NEXT: Column: 10
+CHECK-NEXT: Inline: 0
+CHECK-NEXT: -
+CHECK-NEXT: Function: {{[0-9]+}}
+CHECK-NEXT: SymbolName: main
+CHECK-NEXT: LineOffset: 64
+CHECK-NEXT: Column: 5
+CHECK-NEXT: Inline: 0
+CHECK-NEXT: MemInfoBlock:
+CHECK-NEXT: AllocCount: 21
+CHECK-NEXT: TotalAccessCount: 756
+CHECK-NEXT: MinAccessCount: 36
+CHECK-NEXT: MaxAccessCount: 36
+CHECK-NEXT: TotalSize: 1344
+CHECK-NEXT: MinSize: 64
+CHECK-NEXT: MaxSize: 64
+CHECK-NEXT: AllocTimestamp: {{[0-9]+}}
+CHECK-NEXT: DeallocTimestamp: {{[0-9]+}}
+CHECK-NEXT: TotalLifetime: 0
+CHECK-NEXT: MinLifetime: 0
+CHECK-NEXT: MaxLifetime: 0
+CHECK-NEXT: AllocCpuId: {{[0-9]+}}
+CHECK-NEXT: DeallocCpuId: {{[0-9]+}}
+CHECK-NEXT: NumMigratedCpu: 0
+CHECK-NEXT: NumLifetimeOverlaps: 0
+CHECK-NEXT: NumSameAllocCpu: 20
+CHECK-NEXT: NumSameDeallocCpu: 20
+CHECK-NEXT: DataTypeId: {{[0-9]+}}
+CHECK-NEXT: TotalAccessDensity: 1176
+CHECK-NEXT: MinAccessDensity: 56
+CHECK-NEXT: MaxAccessDensity: 56
+CHECK-NEXT: TotalLifetimeAccessDensity: 1176000
+CHECK-NEXT: MinLifetimeAccessDensity: 56000
+CHECK-NEXT: MaxLifetimeAccessDensity: 56000
+CHECK-NEXT: AccessHistogramSize: 8
+CHECK-NEXT: AccessHistogram: {{[0-9]+}}
+CHECK-NEXT: AccessHistogramValues: 168 147 126 105 84 63 42 21 \ No newline at end of file
diff --git a/llvm/test/tools/llvm-profdata/memprof-basic.test b/llvm/test/tools/llvm-profdata/memprof-basic.test
index 8eaa2fa..e15df50 100644
--- a/llvm/test/tools/llvm-profdata/memprof-basic.test
+++ b/llvm/test/tools/llvm-profdata/memprof-basic.test
@@ -8,7 +8,7 @@ additional allocations which do not originate from the main binary are pruned.
CHECK: MemprofProfile:
CHECK-NEXT: Summary:
-CHECK-NEXT: Version: 3
+CHECK-NEXT: Version: 4
CHECK-NEXT: NumSegments: {{[0-9]+}}
CHECK-NEXT: NumMibInfo: 2
CHECK-NEXT: NumAllocFunctions: 1
@@ -59,6 +59,8 @@ CHECK-NEXT: MaxAccessDensity: 20
CHECK-NEXT: TotalLifetimeAccessDensity: 20000
CHECK-NEXT: MinLifetimeAccessDensity: 20000
CHECK-NEXT: MaxLifetimeAccessDensity: 20000
+CHECK-NEXT: AccessHistogramSize: 0
+CHECK-NEXT: AccessHistogram: 0
CHECK-NEXT: -
CHECK-NEXT: Callstack:
CHECK-NEXT: -
@@ -93,3 +95,5 @@ CHECK-NEXT: MaxAccessDensity: 20
CHECK-NEXT: TotalLifetimeAccessDensity: 20000
CHECK-NEXT: MinLifetimeAccessDensity: 20000
CHECK-NEXT: MaxLifetimeAccessDensity: 20000
+CHECK-NEXT: AccessHistogramSize: 0
+CHECK-NEXT: AccessHistogram: 0 \ No newline at end of file
diff --git a/llvm/test/tools/llvm-profdata/memprof-basic_v3.test b/llvm/test/tools/llvm-profdata/memprof-basic_v3.test
new file mode 100644
index 0000000..3c10c57
--- /dev/null
+++ b/llvm/test/tools/llvm-profdata/memprof-basic_v3.test
@@ -0,0 +1,102 @@
+REQUIRES: x86_64-linux
+
+This is a copy of memprof-basic.test with slight changes to check that we can still read v3 of memprofraw.
+
+Inputs cannot and should not be updated.
+
+RUN: llvm-profdata show --memory %p/Inputs/basic_v3.memprofraw --profiled-binary %p/Inputs/basic_v3.memprofexe -o - | FileCheck %s
+
+We expect 2 MIB entries, 1 each for the malloc calls in the program. Any
+additional allocations which do not originate from the main binary are pruned.
+
+CHECK: MemprofProfile:
+CHECK-NEXT: Summary:
+CHECK-NEXT: Version: 3
+CHECK-NEXT: NumSegments: {{[0-9]+}}
+CHECK-NEXT: NumMibInfo: 2
+CHECK-NEXT: NumAllocFunctions: 1
+CHECK-NEXT: NumStackOffsets: 2
+CHECK-NEXT: Segments:
+CHECK-NEXT: -
+CHECK-NEXT: BuildId: {{[[:xdigit:]]+}}
+CHECK-NEXT: Start: 0x{{[[:xdigit:]]+}}
+CHECK-NEXT: End: 0x{{[[:xdigit:]]+}}
+CHECK-NEXT: Offset: 0x{{[[:xdigit:]]+}}
+CHECK-NEXT: -
+
+CHECK: Records:
+CHECK-NEXT: -
+CHECK-NEXT: FunctionGUID: {{[0-9]+}}
+CHECK-NEXT: AllocSites:
+CHECK-NEXT: -
+CHECK-NEXT: Callstack:
+CHECK-NEXT: -
+CHECK-NEXT: Function: {{[0-9]+}}
+CHECK-NEXT: SymbolName: main
+CHECK-NEXT: LineOffset: 1
+CHECK-NEXT: Column: 21
+CHECK-NEXT: Inline: 0
+CHECK-NEXT: MemInfoBlock:
+CHECK-NEXT: AllocCount: 1
+CHECK-NEXT: TotalAccessCount: 2
+CHECK-NEXT: MinAccessCount: 2
+CHECK-NEXT: MaxAccessCount: 2
+CHECK-NEXT: TotalSize: 10
+CHECK-NEXT: MinSize: 10
+CHECK-NEXT: MaxSize: 10
+CHECK-NEXT: AllocTimestamp: {{[0-9]+}}
+CHECK-NEXT: DeallocTimestamp: {{[0-9]+}}
+CHECK-NEXT: TotalLifetime: 0
+CHECK-NEXT: MinLifetime: 0
+CHECK-NEXT: MaxLifetime: 0
+CHECK-NEXT: AllocCpuId: {{[0-9]+}}
+CHECK-NEXT: DeallocCpuId: {{[0-9]+}}
+CHECK-NEXT: NumMigratedCpu: 0
+CHECK-NEXT: NumLifetimeOverlaps: 0
+CHECK-NEXT: NumSameAllocCpu: 0
+CHECK-NEXT: NumSameDeallocCpu: 0
+CHECK-NEXT: DataTypeId: {{[0-9]+}}
+CHECK-NEXT: TotalAccessDensity: 20
+CHECK-NEXT: MinAccessDensity: 20
+CHECK-NEXT: MaxAccessDensity: 20
+CHECK-NEXT: TotalLifetimeAccessDensity: 20000
+CHECK-NEXT: MinLifetimeAccessDensity: 20000
+CHECK-NEXT: MaxLifetimeAccessDensity: 20000
+CHECK-NEXT: AccessHistogramSize: 0
+CHECK-NEXT: AccessHistogram: 0
+CHECK-NEXT: -
+CHECK-NEXT: Callstack:
+CHECK-NEXT: -
+CHECK-NEXT: Function: {{[0-9]+}}
+CHECK-NEXT: SymbolName: main
+CHECK-NEXT: LineOffset: 4
+CHECK-NEXT: Column: 15
+CHECK-NEXT: Inline: 0
+CHECK-NEXT: MemInfoBlock:
+CHECK-NEXT: AllocCount: 1
+CHECK-NEXT: TotalAccessCount: 2
+CHECK-NEXT: MinAccessCount: 2
+CHECK-NEXT: MaxAccessCount: 2
+CHECK-NEXT: TotalSize: 10
+CHECK-NEXT: MinSize: 10
+CHECK-NEXT: MaxSize: 10
+CHECK-NEXT: AllocTimestamp: {{[0-9]+}}
+CHECK-NEXT: DeallocTimestamp: {{[0-9]+}}
+CHECK-NEXT: TotalLifetime: 0
+CHECK-NEXT: MinLifetime: 0
+CHECK-NEXT: MaxLifetime: 0
+CHECK-NEXT: AllocCpuId: {{[0-9]+}}
+CHECK-NEXT: DeallocCpuId: {{[0-9]+}}
+CHECK-NEXT: NumMigratedCpu: 0
+CHECK-NEXT: NumLifetimeOverlaps: 0
+CHECK-NEXT: NumSameAllocCpu: 0
+CHECK-NEXT: NumSameDeallocCpu: 0
+CHECK-NEXT: DataTypeId: {{[0-9]+}}
+CHECK-NEXT: TotalAccessDensity: 20
+CHECK-NEXT: MinAccessDensity: 20
+CHECK-NEXT: MaxAccessDensity: 20
+CHECK-NEXT: TotalLifetimeAccessDensity: 20000
+CHECK-NEXT: MinLifetimeAccessDensity: 20000
+CHECK-NEXT: MaxLifetimeAccessDensity: 20000
+CHECK-NEXT: AccessHistogramSize: 0
+CHECK-NEXT: AccessHistogram: 0 \ No newline at end of file
diff --git a/llvm/test/tools/llvm-profdata/memprof-inline.test b/llvm/test/tools/llvm-profdata/memprof-inline.test
index dd842c0..79ce2ad 100644
--- a/llvm/test/tools/llvm-profdata/memprof-inline.test
+++ b/llvm/test/tools/llvm-profdata/memprof-inline.test
@@ -5,7 +5,7 @@ RUN: llvm-profdata show --memory %p/Inputs/inline.memprofraw --profiled-binary %
CHECK: MemprofProfile:
CHECK-NEXT: Summary:
-CHECK-NEXT: Version: 3
+CHECK-NEXT: Version: 4
CHECK-NEXT: NumSegments: {{[0-9]+}}
CHECK-NEXT: NumMibInfo: 2
CHECK-NEXT: NumAllocFunctions: 2
@@ -20,25 +20,25 @@ CHECK-NEXT: -
CHECK: Records:
CHECK-NEXT: -
-CHECK-NEXT: FunctionGUID: 15505678318020221912
+CHECK-NEXT: FunctionGUID: 3873612792189045660
CHECK-NEXT: AllocSites:
CHECK-NEXT: -
CHECK-NEXT: Callstack:
CHECK-NEXT: -
-CHECK-NEXT: Function: 15505678318020221912
-CHECK-NEXT: SymbolName: qux
+CHECK-NEXT: Function: 3873612792189045660
+CHECK-NEXT: SymbolName: _Z3quxi
CHECK-NEXT: LineOffset: 1
-CHECK-NEXT: Column: 15
+CHECK-NEXT: Column: 23
CHECK-NEXT: Inline: 1
CHECK-NEXT: -
-CHECK-NEXT: Function: 6699318081062747564
-CHECK-NEXT: SymbolName: foo
+CHECK-NEXT: Function: 1228452328526475178
+CHECK-NEXT: SymbolName: _Z3fooi
CHECK-NEXT: LineOffset: 0
CHECK-NEXT: Column: 18
CHECK-NEXT: Inline: 0
CHECK-NEXT: -
-CHECK-NEXT: Function: 16434608426314478903
-CHECK-NEXT: SymbolName: bar
+CHECK-NEXT: Function: 3727899762981752933
+CHECK-NEXT: SymbolName: _Z3bari
CHECK-NEXT: LineOffset: 0
CHECK-NEXT: Column: 19
CHECK-NEXT: Inline: 0
@@ -74,26 +74,30 @@ CHECK-NEXT: MaxAccessDensity: 100
CHECK-NEXT: TotalLifetimeAccessDensity: 100000
CHECK-NEXT: MinLifetimeAccessDensity: 100000
CHECK-NEXT: MaxLifetimeAccessDensity: 100000
+CHECK-NEXT: AccessHistogramSize: 0
+CHECK-NEXT: AccessHistogram: 0
+
+
CHECK-NEXT: -
-CHECK-NEXT: FunctionGUID: 6699318081062747564
+CHECK-NEXT: FunctionGUID: 1228452328526475178
CHECK-NEXT: AllocSites:
CHECK-NEXT: -
CHECK-NEXT: Callstack:
CHECK-NEXT: -
-CHECK-NEXT: Function: 15505678318020221912
-CHECK-NEXT: SymbolName: qux
+CHECK-NEXT: Function: 3873612792189045660
+CHECK-NEXT: SymbolName: _Z3quxi
CHECK-NEXT: LineOffset: 1
-CHECK-NEXT: Column: 15
+CHECK-NEXT: Column: 23
CHECK-NEXT: Inline: 1
CHECK-NEXT: -
-CHECK-NEXT: Function: 6699318081062747564
-CHECK-NEXT: SymbolName: foo
+CHECK-NEXT: Function: 1228452328526475178
+CHECK-NEXT: SymbolName: _Z3fooi
CHECK-NEXT: LineOffset: 0
CHECK-NEXT: Column: 18
CHECK-NEXT: Inline: 0
CHECK-NEXT: -
-CHECK-NEXT: Function: 16434608426314478903
-CHECK-NEXT: SymbolName: bar
+CHECK-NEXT: Function: 3727899762981752933
+CHECK-NEXT: SymbolName: _Z3bari
CHECK-NEXT: LineOffset: 0
CHECK-NEXT: Column: 19
CHECK-NEXT: Inline: 0
@@ -129,28 +133,31 @@ CHECK-NEXT: MaxAccessDensity: 100
CHECK-NEXT: TotalLifetimeAccessDensity: 100000
CHECK-NEXT: MinLifetimeAccessDensity: 100000
CHECK-NEXT: MaxLifetimeAccessDensity: 100000
+CHECK-NEXT: AccessHistogramSize: 0
+CHECK-NEXT: AccessHistogram: 0
+
CHECK-NEXT: CallSites:
CHECK-NEXT: -
CHECK-NEXT: -
-CHECK-NEXT: Function: 15505678318020221912
-CHECK-NEXT: SymbolName: qux
+CHECK-NEXT: Function: 3873612792189045660
+CHECK-NEXT: SymbolName: _Z3quxi
CHECK-NEXT: LineOffset: 1
-CHECK-NEXT: Column: 15
+CHECK-NEXT: Column: 23
CHECK-NEXT: Inline: 1
CHECK-NEXT: -
CHECK-NEXT: -
-CHECK-NEXT: Function: 6699318081062747564
-CHECK-NEXT: SymbolName: foo
+CHECK-NEXT: Function: 1228452328526475178
+CHECK-NEXT: SymbolName: _Z3fooi
CHECK-NEXT: LineOffset: 0
CHECK-NEXT: Column: 18
CHECK-NEXT: Inline: 0
CHECK-NEXT: -
-CHECK-NEXT: FunctionGUID: 16434608426314478903
+CHECK-NEXT: FunctionGUID: 3727899762981752933
CHECK-NEXT: CallSites:
CHECK-NEXT: -
CHECK-NEXT: -
-CHECK-NEXT: Function: 16434608426314478903
-CHECK-NEXT: SymbolName: bar
+CHECK-NEXT: Function: 3727899762981752933
+CHECK-NEXT: SymbolName: _Z3bari
CHECK-NEXT: LineOffset: 0
CHECK-NEXT: Column: 19
CHECK-NEXT: Inline: 0
diff --git a/llvm/test/tools/llvm-profdata/memprof-multi.test b/llvm/test/tools/llvm-profdata/memprof-multi.test
index f3cdbd1..6243982 100644
--- a/llvm/test/tools/llvm-profdata/memprof-multi.test
+++ b/llvm/test/tools/llvm-profdata/memprof-multi.test
@@ -7,7 +7,7 @@ We expect 2 MIB entries, 1 each for the malloc calls in the program.
CHECK: MemprofProfile:
CHECK-NEXT: Summary:
-CHECK-NEXT: Version: 3
+CHECK-NEXT: Version: 4
CHECK-NEXT: NumSegments: {{[0-9]+}}
CHECK-NEXT: NumMibInfo: 2
CHECK-NEXT: NumAllocFunctions: 1
diff --git a/llvm/test/tools/llvm-profdata/memprof-padding-histogram.test b/llvm/test/tools/llvm-profdata/memprof-padding-histogram.test
new file mode 100644
index 0000000..4ba58e3
--- /dev/null
+++ b/llvm/test/tools/llvm-profdata/memprof-padding-histogram.test
@@ -0,0 +1,99 @@
+REQUIRES: x86_64-linux
+
+To update the inputs used below run Inputs/update_memprof_inputs.sh /path/to/updated/clang
+RUN: llvm-profdata show --memory %p/Inputs/padding-histogram.memprofraw --profiled-binary %p/Inputs/padding-histogram.memprofexe -o - | FileCheck %s
+
+We expect 2 different MIBs with histogram values. This test is to make sure we properly deal with padding.
+
+CHECK: MemprofProfile:
+CHECK-NEXT: Summary:
+CHECK-NEXT: Version: 4
+CHECK-NEXT: NumSegments: {{[0-9]+}}
+CHECK-NEXT: NumMibInfo: 2
+CHECK-NEXT: NumAllocFunctions: 1
+CHECK-NEXT: NumStackOffsets: 2
+CHECK-NEXT: Segments:
+CHECK-NEXT: -
+CHECK-NEXT: BuildId: {{[[:xdigit:]]+}}
+CHECK-NEXT: Start: 0x{{[[:xdigit:]]+}}
+CHECK-NEXT: End: 0x{{[[:xdigit:]]+}}
+CHECK-NEXT: Offset: 0x{{[[:xdigit:]]+}}
+CHECK-NEXT: -
+
+CHECK: Records:
+CHEC-NEXT FunctionGUID: {{[0-9]+}}
+CHEC-NEXT AllocSites:
+CHEC-NEXT -
+CHEC-NEXT Callstack:
+CHEC-NEXT -
+CHEC-NEXT Function: {{[0-9]+}}
+CHEC-NEXT SymbolName: main
+CHEC-NEXT LineOffset: 3
+CHEC-NEXT Column: 10
+CHEC-NEXT Inline: 0
+CHEC-NEXT MemInfoBlock:
+CHEC-NEXT AllocCount: 1
+CHEC-NEXT TotalAccessCount: 5
+CHEC-NEXT MinAccessCount: 5
+CHEC-NEXT MaxAccessCount: 5
+CHEC-NEXT TotalSize: 24
+CHEC-NEXT MinSize: 24
+CHEC-NEXT MaxSize: 24
+CHEC-NEXT AllocTimestamp: {{[0-9]+}}
+CHEC-NEXT DeallocTimestamp: {{[0-9]+}}
+CHEC-NEXT TotalLifetime: 0
+CHEC-NEXT MinLifetime: 0
+CHEC-NEXT MaxLifetime: 0
+CHEC-NEXT AllocCpuId: 11
+CHEC-NEXT DeallocCpuId: 11
+CHEC-NEXT NumMigratedCpu: 0
+CHEC-NEXT NumLifetimeOverlaps: 0
+CHEC-NEXT NumSameAllocCpu: 0
+CHEC-NEXT NumSameDeallocCpu: 0
+CHEC-NEXT DataTypeId: 0
+CHEC-NEXT TotalAccessDensity: 20
+CHEC-NEXT MinAccessDensity: 20
+CHEC-NEXT MaxAccessDensity: 20
+CHEC-NEXT TotalLifetimeAccessDensity: 20000
+CHEC-NEXT MinLifetimeAccessDensity: 20000
+CHEC-NEXT MaxLifetimeAccessDensity: 20000
+CHEC-NEXT AccessHistogramSize: 3
+CHEC-NEXT AccessHistogram: {{[0-9]+}}
+CHEC-NEXT AccessHistogramValues: -2 -1 -2
+CHEC-NEXT -
+CHEC-NEXT Callstack:
+CHEC-NEXT -
+CHEC-NEXT Function: {{[0-9]+}}
+CHEC-NEXT SymbolName: main
+CHEC-NEXT LineOffset: 10
+CHEC-NEXT Column: 10
+CHEC-NEXT Inline: 0
+CHEC-NEXT MemInfoBlock:
+CHEC-NEXT AllocCount: 1
+CHEC-NEXT TotalAccessCount: 4
+CHEC-NEXT MinAccessCount: 4
+CHEC-NEXT MaxAccessCount: 4
+CHEC-NEXT TotalSize: 48
+CHEC-NEXT MinSize: 48
+CHEC-NEXT MaxSize: 48
+CHEC-NEXT AllocTimestamp: {{[0-9]+}}
+CHEC-NEXT DeallocTimestamp: {{[0-9]+}}
+CHEC-NEXT TotalLifetime: 0
+CHEC-NEXT MinLifetime: 0
+CHEC-NEXT MaxLifetime: 0
+CHEC-NEXT AllocCpuId: 11
+CHEC-NEXT DeallocCpuId: 11
+CHEC-NEXT NumMigratedCpu: 0
+CHEC-NEXT NumLifetimeOverlaps: 0
+CHEC-NEXT NumSameAllocCpu: 0
+CHEC-NEXT NumSameDeallocCpu: 0
+CHEC-NEXT DataTypeId: 0
+CHEC-NEXT TotalAccessDensity: 8
+CHEC-NEXT MinAccessDensity: 8
+CHEC-NEXT MaxAccessDensity: 8
+CHEC-NEXT TotalLifetimeAccessDensity: 8000
+CHEC-NEXT MinLifetimeAccessDensity: 8000
+CHEC-NEXT MaxLifetimeAccessDensity: 8000
+CHEC-NEXT AccessHistogramSize: 6
+CHEC-NEXT AccessHistogram: {{[0-9]+}}
+CHEC-NEXT AccessHistogramValues: -2 -0 -0 -0 -1 -1 \ No newline at end of file
diff --git a/llvm/test/tools/llvm-profdata/memprof-pic.test b/llvm/test/tools/llvm-profdata/memprof-pic.test
index 03c98ed9..78d2c5c 100644
--- a/llvm/test/tools/llvm-profdata/memprof-pic.test
+++ b/llvm/test/tools/llvm-profdata/memprof-pic.test
@@ -11,7 +11,7 @@ RUN: llvm-profdata show --memory %p/Inputs/pic.memprofraw --profiled-binary %p/I
CHECK: MemprofProfile:
CHECK-NEXT: Summary:
-CHECK-NEXT: Version: 3
+CHECK-NEXT: Version: 4
CHECK-NEXT: NumSegments: {{[0-9]+}}
CHECK-NEXT: NumMibInfo: 2
CHECK-NEXT: NumAllocFunctions: 1
@@ -62,6 +62,9 @@ CHECK-NEXT: MaxAccessDensity: 20
CHECK-NEXT: TotalLifetimeAccessDensity: 20000
CHECK-NEXT: MinLifetimeAccessDensity: 20000
CHECK-NEXT: MaxLifetimeAccessDensity: 20000
+CHECK-NEXT: AccessHistogramSize: 0
+CHECK-NEXT: AccessHistogram: 0
+
CHECK-NEXT: -
CHECK-NEXT: Callstack:
CHECK-NEXT: -
@@ -96,3 +99,5 @@ CHECK-NEXT: MaxAccessDensity: 20
CHECK-NEXT: TotalLifetimeAccessDensity: 20000
CHECK-NEXT: MinLifetimeAccessDensity: 20000
CHECK-NEXT: MaxLifetimeAccessDensity: 20000
+CHECK-NEXT: AccessHistogramSize: 0
+CHECK-NEXT: AccessHistogram: 0 \ No newline at end of file
diff --git a/llvm/unittests/ProfileData/MemProfTest.cpp b/llvm/unittests/ProfileData/MemProfTest.cpp
index 15eb59e..14623e18 100644
--- a/llvm/unittests/ProfileData/MemProfTest.cpp
+++ b/llvm/unittests/ProfileData/MemProfTest.cpp
@@ -247,7 +247,7 @@ TEST(MemProf, FillsValue) {
TEST(MemProf, PortableWrapper) {
MemInfoBlock Info(/*size=*/16, /*access_count=*/7, /*alloc_timestamp=*/1000,
/*dealloc_timestamp=*/2000, /*alloc_cpu=*/3,
- /*dealloc_cpu=*/4);
+ /*dealloc_cpu=*/4, /*Histogram=*/0, /*HistogramSize=*/0);
const auto Schema = llvm::memprof::getFullSchema();
PortableMemInfoBlock WriteBlock(Info, Schema);
@@ -276,7 +276,7 @@ TEST(MemProf, RecordSerializationRoundTripVersion0And1) {
MemInfoBlock Info(/*size=*/16, /*access_count=*/7, /*alloc_timestamp=*/1000,
/*dealloc_timestamp=*/2000, /*alloc_cpu=*/3,
- /*dealloc_cpu=*/4);
+ /*dealloc_cpu=*/4, /*Histogram=*/0, /*HistogramSize=*/0);
llvm::SmallVector<llvm::SmallVector<FrameId>> AllocCallStacks = {
{0x123, 0x345}, {0x123, 0x567}};
@@ -310,7 +310,7 @@ TEST(MemProf, RecordSerializationRoundTripVerion2) {
MemInfoBlock Info(/*size=*/16, /*access_count=*/7, /*alloc_timestamp=*/1000,
/*dealloc_timestamp=*/2000, /*alloc_cpu=*/3,
- /*dealloc_cpu=*/4);
+ /*dealloc_cpu=*/4, /*Histogram=*/0, /*HistogramSize=*/0);
llvm::SmallVector<llvm::memprof::CallStackId> CallStackIds = {0x123, 0x456};