diff --git a/compiler-rt/include/profile/MIBEntryDef.inc b/compiler-rt/include/profile/MIBEntryDef.inc new file mode 100644 --- /dev/null +++ b/compiler-rt/include/profile/MIBEntryDef.inc @@ -0,0 +1,51 @@ +/*===-- MemEntryDef.inc - MemProf profiling runtime macros -*- C++ -*-======== *\ +|* +|* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +|* See https://llvm.org/LICENSE.txt for license information. +|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +|* +\*===----------------------------------------------------------------------===*/ +/* + * This file defines the macros for memprof profiling data structures. + * Eg. usage to define the memprof meminfoblock struct: + * + * struct MemInfoBlock { + * #define MIBEntryDef(NameTag, Name, Type) Type Name; + * #include MIBEntryDef.inc + * #undef MIBEntryDef + * }; + * + * This file has two identical copies. The primary copy lives in LLVM and + * the other one sits in compiler-rt/include/profile directory. To make changes + * in this file, first modify the primary copy and copy it over to compiler-rt. + * Testing of any change in this file can start only after the two copies are + * synced up. + * +\*===----------------------------------------------------------------------===*/ + +#ifndef MIBEntryDef +#define MIBEntryDef(NameTag, Name, Type) +#endif + +MIBEntryDef(AllocCount = 1, AllocCount, uint32_t) +MIBEntryDef(TotalAccessCount = 2, TotalAccessCount, uint64_t) +MIBEntryDef(MinAccessCount = 3, MinAccessCount, uint64_t) +MIBEntryDef(MaxAccessCount = 4, MaxAccessCount, uint64_t) +MIBEntryDef(TotalSize = 5, TotalSize, uint64_t) +MIBEntryDef(MinSize = 6, MinSize, uint32_t) +MIBEntryDef(MaxSize = 7, MaxSize, uint32_t) +MIBEntryDef(AllocTimestamp = 8, AllocTimestamp, uint32_t) +MIBEntryDef(DeallocTimestamp = 9, DeallocTimestamp, uint32_t) +MIBEntryDef(TotalLifetime = 10, TotalLifetime, uint64_t) +MIBEntryDef(MinLifetime = 11, MinLifetime, uint32_t) +MIBEntryDef(MaxLifetime = 12, MaxLifetime, uint32_t) +MIBEntryDef(AllocCpuId = 13, AllocCpuId, uint32_t) +MIBEntryDef(DeallocCpuId = 14, DeallocCpuId, uint32_t) +MIBEntryDef(NumMigratedCpu = 15, NumMigratedCpu, uint32_t) +MIBEntryDef(NumLifetimeOverlaps = 16, NumLifetimeOverlaps, uint32_t) +MIBEntryDef(NumSameAllocCpu = 17, NumSameAllocCpu, uint32_t) +MIBEntryDef(NumSameDeallocCpu = 18, NumSameDeallocCpu, uint32_t) +MIBEntryDef(DataTypeId = 19, DataTypeId, uint64_t) + + + diff --git a/compiler-rt/include/profile/MemProfData.inc b/compiler-rt/include/profile/MemProfData.inc --- a/compiler-rt/include/profile/MemProfData.inc +++ b/compiler-rt/include/profile/MemProfData.inc @@ -80,71 +80,80 @@ } }); +// Packed struct definition for MSVC. We can't use the PACKED macro defined in +// MemProfData.inc since it would mean we are embedding a directive (the +// #include for MIBEntryDef) into the macros which is undefined behaviour. +#ifdef _MSC_VER +__pragma(pack(push,1)) +#endif + // A struct representing the heap allocation characteristics of a particular // runtime context. This struct is shared between the compiler-rt runtime and // the raw profile reader. The indexed format uses a separate, self-describing // backwards compatible format. -PACKED(struct MemInfoBlock { - uint32_t alloc_count; - uint64_t total_access_count, min_access_count, max_access_count; - uint64_t total_size; - uint32_t min_size, max_size; - uint32_t alloc_timestamp, dealloc_timestamp; - uint64_t total_lifetime; - uint32_t min_lifetime, max_lifetime; - uint32_t alloc_cpu_id, dealloc_cpu_id; - uint32_t num_migrated_cpu; - - // Only compared to prior deallocated object currently. - uint32_t num_lifetime_overlaps; - uint32_t num_same_alloc_cpu; - uint32_t num_same_dealloc_cpu; - - uint64_t data_type_id; // TODO: hash of type name - - MemInfoBlock() : alloc_count(0) {} - - MemInfoBlock(uint32_t size, uint64_t access_count, uint32_t alloc_timestamp, - uint32_t dealloc_timestamp, uint32_t alloc_cpu, uint32_t dealloc_cpu) - : alloc_count(1), total_access_count(access_count), - min_access_count(access_count), max_access_count(access_count), - total_size(size), min_size(size), max_size(size), - alloc_timestamp(alloc_timestamp), dealloc_timestamp(dealloc_timestamp), - total_lifetime(dealloc_timestamp - alloc_timestamp), - min_lifetime(total_lifetime), max_lifetime(total_lifetime), - alloc_cpu_id(alloc_cpu), dealloc_cpu_id(dealloc_cpu), - num_lifetime_overlaps(0), num_same_alloc_cpu(0), - num_same_dealloc_cpu(0) { - num_migrated_cpu = alloc_cpu_id != dealloc_cpu_id; - } - - void Merge(const MemInfoBlock &newMIB) { - alloc_count += newMIB.alloc_count; - - total_access_count += newMIB.total_access_count; - min_access_count = newMIB.min_access_count < min_access_count ? newMIB.min_access_count : min_access_count; - max_access_count = newMIB.max_access_count < max_access_count ? newMIB.max_access_count : max_access_count; - - total_size += newMIB.total_size; - min_size = newMIB.min_size < min_size ? newMIB.min_size : min_size; - max_size = newMIB.max_size < max_size ? newMIB.max_size : max_size; +struct MemInfoBlock{ + +#define MIBEntryDef(NameTag, Name, Type) Type Name; +#include "MIBEntryDef.inc" +#undef MIBEntryDef + +bool operator==(const MemInfoBlock& Other) const { + bool IsEqual = true; +#define MIBEntryDef(NameTag, Name, Type) \ + IsEqual = (IsEqual && Name == Other.Name); +#include "MIBEntryDef.inc" +#undef MIBEntryDef + return IsEqual; +} + +MemInfoBlock() : AllocCount(0) {} + +MemInfoBlock(uint32_t size, uint64_t access_count, uint32_t alloc_timestamp, + uint32_t dealloc_timestamp, uint32_t alloc_cpu, uint32_t dealloc_cpu) + : AllocCount(1), TotalAccessCount(access_count), + MinAccessCount(access_count), MaxAccessCount(access_count), + TotalSize(size), MinSize(size), MaxSize(size), + AllocTimestamp(alloc_timestamp), DeallocTimestamp(dealloc_timestamp), + TotalLifetime(dealloc_timestamp - alloc_timestamp), + MinLifetime(TotalLifetime), MaxLifetime(TotalLifetime), + AllocCpuId(alloc_cpu), DeallocCpuId(dealloc_cpu), + NumLifetimeOverlaps(0), NumSameAllocCpu(0), + NumSameDeallocCpu(0) { + NumMigratedCpu = AllocCpuId != DeallocCpuId; +} + +void Merge(const MemInfoBlock &newMIB) { + AllocCount += newMIB.AllocCount; + + TotalAccessCount += newMIB.TotalAccessCount; + MinAccessCount = newMIB.MinAccessCount < MinAccessCount ? newMIB.MinAccessCount : MinAccessCount; + MaxAccessCount = newMIB.MaxAccessCount < MaxAccessCount ? newMIB.MaxAccessCount : MaxAccessCount; + + TotalSize += newMIB.TotalSize; + MinSize = newMIB.MinSize < MinSize ? newMIB.MinSize : MinSize; + MaxSize = newMIB.MaxSize < MaxSize ? newMIB.MaxSize : MaxSize; + + TotalLifetime += newMIB.TotalLifetime; + MinLifetime = newMIB.MinLifetime < MinLifetime ? newMIB.MinLifetime : MinLifetime; + MaxLifetime = newMIB.MaxLifetime > MaxLifetime ? newMIB.MaxLifetime : MaxLifetime; + + // We know newMIB was deallocated later, so just need to check if it was + // allocated before last one deallocated. + NumLifetimeOverlaps += newMIB.AllocTimestamp < DeallocTimestamp; + AllocTimestamp = newMIB.AllocTimestamp; + DeallocTimestamp = newMIB.DeallocTimestamp; + + NumSameAllocCpu += AllocCpuId == newMIB.AllocCpuId; + NumSameDeallocCpu += DeallocCpuId == newMIB.DeallocCpuId; + AllocCpuId = newMIB.AllocCpuId; + DeallocCpuId = newMIB.DeallocCpuId; +} - total_lifetime += newMIB.total_lifetime; - min_lifetime = newMIB.min_lifetime < min_lifetime ? newMIB.min_lifetime : min_lifetime; - max_lifetime = newMIB.max_lifetime > max_lifetime ? newMIB.max_lifetime : max_lifetime; - - // We know newMIB was deallocated later, so just need to check if it was - // allocated before last one deallocated. - num_lifetime_overlaps += newMIB.alloc_timestamp < dealloc_timestamp; - alloc_timestamp = newMIB.alloc_timestamp; - dealloc_timestamp = newMIB.dealloc_timestamp; - - num_same_alloc_cpu += alloc_cpu_id == newMIB.alloc_cpu_id; - num_same_dealloc_cpu += dealloc_cpu_id == newMIB.dealloc_cpu_id; - alloc_cpu_id = newMIB.alloc_cpu_id; - dealloc_cpu_id = newMIB.dealloc_cpu_id; - } -}); +#ifdef _MSC_VER +} __pragma(pack(pop)); +#else +} __attribute__((__packed__)); +#endif } // namespace memprof } // namespace llvm diff --git a/compiler-rt/lib/memprof/memprof_allocator.cpp b/compiler-rt/lib/memprof/memprof_allocator.cpp --- a/compiler-rt/lib/memprof/memprof_allocator.cpp +++ b/compiler-rt/lib/memprof/memprof_allocator.cpp @@ -43,32 +43,32 @@ u64 p; if (print_terse) { - p = M.total_size * 100 / M.alloc_count; - Printf("MIB:%llu/%u/%llu.%02llu/%u/%u/", id, M.alloc_count, p / 100, - p % 100, M.min_size, M.max_size); - p = M.total_access_count * 100 / M.alloc_count; - Printf("%llu.%02llu/%llu/%llu/", p / 100, p % 100, M.min_access_count, - M.max_access_count); - p = M.total_lifetime * 100 / M.alloc_count; - Printf("%llu.%02llu/%u/%u/", p / 100, p % 100, M.min_lifetime, - M.max_lifetime); - Printf("%u/%u/%u/%u\n", M.num_migrated_cpu, M.num_lifetime_overlaps, - M.num_same_alloc_cpu, M.num_same_dealloc_cpu); + p = M.TotalSize * 100 / M.AllocCount; + Printf("MIB:%llu/%u/%llu.%02llu/%u/%u/", id, M.AllocCount, p / 100, p % 100, + M.MinSize, M.MaxSize); + p = M.TotalAccessCount * 100 / M.AllocCount; + Printf("%llu.%02llu/%llu/%llu/", p / 100, p % 100, M.MinAccessCount, + M.MaxAccessCount); + p = M.TotalLifetime * 100 / M.AllocCount; + Printf("%llu.%02llu/%u/%u/", p / 100, p % 100, M.MinLifetime, + M.MaxLifetime); + Printf("%u/%u/%u/%u\n", M.NumMigratedCpu, M.NumLifetimeOverlaps, + M.NumSameAllocCpu, M.NumSameDeallocCpu); } else { - p = M.total_size * 100 / M.alloc_count; + p = M.TotalSize * 100 / M.AllocCount; Printf("Memory allocation stack id = %llu\n", id); Printf("\talloc_count %u, size (ave/min/max) %llu.%02llu / %u / %u\n", - M.alloc_count, p / 100, p % 100, M.min_size, M.max_size); - p = M.total_access_count * 100 / M.alloc_count; + M.AllocCount, p / 100, p % 100, M.MinSize, M.MaxSize); + p = M.TotalAccessCount * 100 / M.AllocCount; Printf("\taccess_count (ave/min/max): %llu.%02llu / %llu / %llu\n", p / 100, - p % 100, M.min_access_count, M.max_access_count); - p = M.total_lifetime * 100 / M.alloc_count; + p % 100, M.MinAccessCount, M.MaxAccessCount); + p = M.TotalLifetime * 100 / M.AllocCount; Printf("\tlifetime (ave/min/max): %llu.%02llu / %u / %u\n", p / 100, - p % 100, M.min_lifetime, M.max_lifetime); + p % 100, M.MinLifetime, M.MaxLifetime); Printf("\tnum migrated: %u, num lifetime overlaps: %u, num same alloc " "cpu: %u, num same dealloc_cpu: %u\n", - M.num_migrated_cpu, M.num_lifetime_overlaps, M.num_same_alloc_cpu, - M.num_same_dealloc_cpu); + M.NumMigratedCpu, M.NumLifetimeOverlaps, M.NumSameAllocCpu, + M.NumSameDeallocCpu); } } } // namespace diff --git a/compiler-rt/lib/memprof/tests/rawprofile.cpp b/compiler-rt/lib/memprof/tests/rawprofile.cpp --- a/compiler-rt/lib/memprof/tests/rawprofile.cpp +++ b/compiler-rt/lib/memprof/tests/rawprofile.cpp @@ -82,8 +82,8 @@ // Since we want to override the constructor set vals to make it easier to // test. memset(&FakeMIB, 0, sizeof(MemInfoBlock)); - FakeMIB.alloc_count = 0x1; - FakeMIB.total_access_count = 0x2; + FakeMIB.AllocCount = 0x1; + FakeMIB.TotalAccessCount = 0x2; uint64_t FakeIds[2]; FakeIds[0] = PopulateFakeMap(FakeMIB, /*StackPCBegin=*/2, FakeMap); diff --git a/llvm/include/llvm/ProfileData/MIBEntryDef.inc b/llvm/include/llvm/ProfileData/MIBEntryDef.inc new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/ProfileData/MIBEntryDef.inc @@ -0,0 +1,51 @@ +/*===-- MemEntryDef.inc - MemProf profiling runtime macros -*- C++ -*-======== *\ +|* +|* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +|* See https://llvm.org/LICENSE.txt for license information. +|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +|* +\*===----------------------------------------------------------------------===*/ +/* + * This file defines the macros for memprof profiling data structures. + * Eg. usage to define the memprof meminfoblock struct: + * + * struct MemInfoBlock { + * #define MIBEntryDef(NameTag, Name, Type) Type Name; + * #include MIBEntryDef.inc + * #undef MIBEntryDef + * }; + * + * This file has two identical copies. The primary copy lives in LLVM and + * the other one sits in compiler-rt/include/profile directory. To make changes + * in this file, first modify the primary copy and copy it over to compiler-rt. + * Testing of any change in this file can start only after the two copies are + * synced up. + * +\*===----------------------------------------------------------------------===*/ + +#ifndef MIBEntryDef +#define MIBEntryDef(NameTag, Name, Type) +#endif + +MIBEntryDef(AllocCount = 1, AllocCount, uint32_t) +MIBEntryDef(TotalAccessCount = 2, TotalAccessCount, uint64_t) +MIBEntryDef(MinAccessCount = 3, MinAccessCount, uint64_t) +MIBEntryDef(MaxAccessCount = 4, MaxAccessCount, uint64_t) +MIBEntryDef(TotalSize = 5, TotalSize, uint64_t) +MIBEntryDef(MinSize = 6, MinSize, uint32_t) +MIBEntryDef(MaxSize = 7, MaxSize, uint32_t) +MIBEntryDef(AllocTimestamp = 8, AllocTimestamp, uint32_t) +MIBEntryDef(DeallocTimestamp = 9, DeallocTimestamp, uint32_t) +MIBEntryDef(TotalLifetime = 10, TotalLifetime, uint64_t) +MIBEntryDef(MinLifetime = 11, MinLifetime, uint32_t) +MIBEntryDef(MaxLifetime = 12, MaxLifetime, uint32_t) +MIBEntryDef(AllocCpuId = 13, AllocCpuId, uint32_t) +MIBEntryDef(DeallocCpuId = 14, DeallocCpuId, uint32_t) +MIBEntryDef(NumMigratedCpu = 15, NumMigratedCpu, uint32_t) +MIBEntryDef(NumLifetimeOverlaps = 16, NumLifetimeOverlaps, uint32_t) +MIBEntryDef(NumSameAllocCpu = 17, NumSameAllocCpu, uint32_t) +MIBEntryDef(NumSameDeallocCpu = 18, NumSameDeallocCpu, uint32_t) +MIBEntryDef(DataTypeId = 19, DataTypeId, uint64_t) + + + diff --git a/llvm/include/llvm/ProfileData/MemProf.h b/llvm/include/llvm/ProfileData/MemProf.h --- a/llvm/include/llvm/ProfileData/MemProf.h +++ b/llvm/include/llvm/ProfileData/MemProf.h @@ -50,24 +50,42 @@ OS << " MemInfoBlock:\n"; // TODO: Replace this once the format is updated to be version agnostic. - OS << " " << "AllocCount: " << Info.alloc_count << "\n"; - OS << " " << "TotalAccessCount: " << Info.total_access_count << "\n"; - OS << " " << "MinAccessCount: " << Info.min_access_count << "\n"; - OS << " " << "MaxAccessCount: " << Info.max_access_count << "\n"; - OS << " " << "TotalSize: " << Info.total_size << "\n"; - OS << " " << "MinSize: " << Info.min_size << "\n"; - OS << " " << "MaxSize: " << Info.max_size << "\n"; - OS << " " << "AllocTimestamp: " << Info.alloc_timestamp << "\n"; - OS << " " << "DeallocTimestamp: " << Info.dealloc_timestamp << "\n"; - OS << " " << "TotalLifetime: " << Info.total_lifetime << "\n"; - OS << " " << "MinLifetime: " << Info.min_lifetime << "\n"; - OS << " " << "MaxLifetime: " << Info.max_lifetime << "\n"; - OS << " " << "AllocCpuId: " << Info.alloc_cpu_id << "\n"; - OS << " " << "DeallocCpuId: " << Info.dealloc_cpu_id << "\n"; - OS << " " << "NumMigratedCpu: " << Info.num_migrated_cpu << "\n"; - OS << " " << "NumLifetimeOverlaps: " << Info.num_lifetime_overlaps << "\n"; - OS << " " << "NumSameAllocCpu: " << Info.num_same_alloc_cpu << "\n"; - OS << " " << "NumSameDeallocCpu: " << Info.num_same_dealloc_cpu << "\n"; + OS << " " + << "AllocCount: " << Info.AllocCount << "\n"; + OS << " " + << "TotalAccessCount: " << Info.TotalAccessCount << "\n"; + OS << " " + << "MinAccessCount: " << Info.MinAccessCount << "\n"; + OS << " " + << "MaxAccessCount: " << Info.MaxAccessCount << "\n"; + OS << " " + << "TotalSize: " << Info.TotalSize << "\n"; + OS << " " + << "MinSize: " << Info.MinSize << "\n"; + OS << " " + << "MaxSize: " << Info.MaxSize << "\n"; + OS << " " + << "AllocTimestamp: " << Info.AllocTimestamp << "\n"; + OS << " " + << "DeallocTimestamp: " << Info.DeallocTimestamp << "\n"; + OS << " " + << "TotalLifetime: " << Info.TotalLifetime << "\n"; + OS << " " + << "MinLifetime: " << Info.MinLifetime << "\n"; + OS << " " + << "MaxLifetime: " << Info.MaxLifetime << "\n"; + OS << " " + << "AllocCpuId: " << Info.AllocCpuId << "\n"; + OS << " " + << "DeallocCpuId: " << Info.DeallocCpuId << "\n"; + OS << " " + << "NumMigratedCpu: " << Info.NumMigratedCpu << "\n"; + OS << " " + << "NumLifetimeOverlaps: " << Info.NumLifetimeOverlaps << "\n"; + OS << " " + << "NumSameAllocCpu: " << Info.NumSameAllocCpu << "\n"; + OS << " " + << "NumSameDeallocCpu: " << Info.NumSameDeallocCpu << "\n"; } }; diff --git a/llvm/include/llvm/ProfileData/MemProfData.inc b/llvm/include/llvm/ProfileData/MemProfData.inc --- a/llvm/include/llvm/ProfileData/MemProfData.inc +++ b/llvm/include/llvm/ProfileData/MemProfData.inc @@ -80,71 +80,80 @@ } }); +// Packed struct definition for MSVC. We can't use the PACKED macro defined in +// MemProfData.inc since it would mean we are embedding a directive (the +// #include for MIBEntryDef) into the macros which is undefined behaviour. +#ifdef _MSC_VER +__pragma(pack(push,1)) +#endif + // A struct representing the heap allocation characteristics of a particular // runtime context. This struct is shared between the compiler-rt runtime and // the raw profile reader. The indexed format uses a separate, self-describing // backwards compatible format. -PACKED(struct MemInfoBlock { - uint32_t alloc_count; - uint64_t total_access_count, min_access_count, max_access_count; - uint64_t total_size; - uint32_t min_size, max_size; - uint32_t alloc_timestamp, dealloc_timestamp; - uint64_t total_lifetime; - uint32_t min_lifetime, max_lifetime; - uint32_t alloc_cpu_id, dealloc_cpu_id; - uint32_t num_migrated_cpu; - - // Only compared to prior deallocated object currently. - uint32_t num_lifetime_overlaps; - uint32_t num_same_alloc_cpu; - uint32_t num_same_dealloc_cpu; - - uint64_t data_type_id; // TODO: hash of type name - - MemInfoBlock() : alloc_count(0) {} - - MemInfoBlock(uint32_t size, uint64_t access_count, uint32_t alloc_timestamp, - uint32_t dealloc_timestamp, uint32_t alloc_cpu, uint32_t dealloc_cpu) - : alloc_count(1), total_access_count(access_count), - min_access_count(access_count), max_access_count(access_count), - total_size(size), min_size(size), max_size(size), - alloc_timestamp(alloc_timestamp), dealloc_timestamp(dealloc_timestamp), - total_lifetime(dealloc_timestamp - alloc_timestamp), - min_lifetime(total_lifetime), max_lifetime(total_lifetime), - alloc_cpu_id(alloc_cpu), dealloc_cpu_id(dealloc_cpu), - num_lifetime_overlaps(0), num_same_alloc_cpu(0), - num_same_dealloc_cpu(0) { - num_migrated_cpu = alloc_cpu_id != dealloc_cpu_id; - } - - void Merge(const MemInfoBlock &newMIB) { - alloc_count += newMIB.alloc_count; - - total_access_count += newMIB.total_access_count; - min_access_count = newMIB.min_access_count < min_access_count ? newMIB.min_access_count : min_access_count; - max_access_count = newMIB.max_access_count < max_access_count ? newMIB.max_access_count : max_access_count; - - total_size += newMIB.total_size; - min_size = newMIB.min_size < min_size ? newMIB.min_size : min_size; - max_size = newMIB.max_size < max_size ? newMIB.max_size : max_size; +struct MemInfoBlock{ + +#define MIBEntryDef(NameTag, Name, Type) Type Name; +#include "MIBEntryDef.inc" +#undef MIBEntryDef + +bool operator==(const MemInfoBlock& Other) const { + bool IsEqual = true; +#define MIBEntryDef(NameTag, Name, Type) \ + IsEqual = (IsEqual && Name == Other.Name); +#include "MIBEntryDef.inc" +#undef MIBEntryDef + return IsEqual; +} + +MemInfoBlock() : AllocCount(0) {} + +MemInfoBlock(uint32_t size, uint64_t access_count, uint32_t alloc_timestamp, + uint32_t dealloc_timestamp, uint32_t alloc_cpu, uint32_t dealloc_cpu) + : AllocCount(1), TotalAccessCount(access_count), + MinAccessCount(access_count), MaxAccessCount(access_count), + TotalSize(size), MinSize(size), MaxSize(size), + AllocTimestamp(alloc_timestamp), DeallocTimestamp(dealloc_timestamp), + TotalLifetime(dealloc_timestamp - alloc_timestamp), + MinLifetime(TotalLifetime), MaxLifetime(TotalLifetime), + AllocCpuId(alloc_cpu), DeallocCpuId(dealloc_cpu), + NumLifetimeOverlaps(0), NumSameAllocCpu(0), + NumSameDeallocCpu(0) { + NumMigratedCpu = AllocCpuId != DeallocCpuId; +} + +void Merge(const MemInfoBlock &newMIB) { + AllocCount += newMIB.AllocCount; + + TotalAccessCount += newMIB.TotalAccessCount; + MinAccessCount = newMIB.MinAccessCount < MinAccessCount ? newMIB.MinAccessCount : MinAccessCount; + MaxAccessCount = newMIB.MaxAccessCount < MaxAccessCount ? newMIB.MaxAccessCount : MaxAccessCount; + + TotalSize += newMIB.TotalSize; + MinSize = newMIB.MinSize < MinSize ? newMIB.MinSize : MinSize; + MaxSize = newMIB.MaxSize < MaxSize ? newMIB.MaxSize : MaxSize; + + TotalLifetime += newMIB.TotalLifetime; + MinLifetime = newMIB.MinLifetime < MinLifetime ? newMIB.MinLifetime : MinLifetime; + MaxLifetime = newMIB.MaxLifetime > MaxLifetime ? newMIB.MaxLifetime : MaxLifetime; + + // We know newMIB was deallocated later, so just need to check if it was + // allocated before last one deallocated. + NumLifetimeOverlaps += newMIB.AllocTimestamp < DeallocTimestamp; + AllocTimestamp = newMIB.AllocTimestamp; + DeallocTimestamp = newMIB.DeallocTimestamp; + + NumSameAllocCpu += AllocCpuId == newMIB.AllocCpuId; + NumSameDeallocCpu += DeallocCpuId == newMIB.DeallocCpuId; + AllocCpuId = newMIB.AllocCpuId; + DeallocCpuId = newMIB.DeallocCpuId; +} - total_lifetime += newMIB.total_lifetime; - min_lifetime = newMIB.min_lifetime < min_lifetime ? newMIB.min_lifetime : min_lifetime; - max_lifetime = newMIB.max_lifetime > max_lifetime ? newMIB.max_lifetime : max_lifetime; - - // We know newMIB was deallocated later, so just need to check if it was - // allocated before last one deallocated. - num_lifetime_overlaps += newMIB.alloc_timestamp < dealloc_timestamp; - alloc_timestamp = newMIB.alloc_timestamp; - dealloc_timestamp = newMIB.dealloc_timestamp; - - num_same_alloc_cpu += alloc_cpu_id == newMIB.alloc_cpu_id; - num_same_dealloc_cpu += dealloc_cpu_id == newMIB.dealloc_cpu_id; - alloc_cpu_id = newMIB.alloc_cpu_id; - dealloc_cpu_id = newMIB.dealloc_cpu_id; - } -}); +#ifdef _MSC_VER +} __pragma(pack(pop)); +#else +} __attribute__((__packed__)); +#endif } // namespace memprof } // namespace llvm diff --git a/llvm/unittests/ProfileData/MemProfTest.cpp b/llvm/unittests/ProfileData/MemProfTest.cpp --- a/llvm/unittests/ProfileData/MemProfTest.cpp +++ b/llvm/unittests/ProfileData/MemProfTest.cpp @@ -122,8 +122,8 @@ CSM[0x2] = {0x6000, 0x2000}; llvm::MapVector Prof; - Prof[0x1].alloc_count = 1; - Prof[0x2].alloc_count = 2; + Prof[0x1].AllocCount = 1; + Prof[0x2].AllocCount = 2; auto Seg = makeSegments(); @@ -135,8 +135,8 @@ } EXPECT_EQ(Records.size(), 2U); - EXPECT_EQ(Records[0].Info.alloc_count, 1U); - EXPECT_EQ(Records[1].Info.alloc_count, 2U); + EXPECT_EQ(Records[0].Info.AllocCount, 1U); + EXPECT_EQ(Records[1].Info.AllocCount, 2U); EXPECT_THAT(Records[0].CallStack[0], FrameContains("foo", 5U, 30U, false)); EXPECT_THAT(Records[0].CallStack[1], FrameContains("bar", 51U, 20U, true));