92 changes: 75 additions & 17 deletions llvm/lib/ProfileData/SampleProfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,16 +319,33 @@ ErrorOr<StringRef> SampleProfileReaderBinary::readString() {
return Str;
}

ErrorOr<StringRef> SampleProfileReaderBinary::readStringFromTable() {
template <typename T>
inline ErrorOr<uint32_t> SampleProfileReaderBinary::readStringIndex(T &Table) {
std::error_code EC;
auto Idx = readNumber<uint32_t>();
if (std::error_code EC = Idx.getError())
return EC;
if (*Idx >= NameTable.size())
if (*Idx >= Table.size())
return sampleprof_error::truncated_name_table;
return *Idx;
}

ErrorOr<StringRef> SampleProfileReaderRawBinary::readStringFromTable() {
auto Idx = readStringIndex(NameTable);
if (std::error_code EC = Idx.getError())
return EC;

return NameTable[*Idx];
}

ErrorOr<StringRef> SampleProfileReaderCompactBinary::readStringFromTable() {
auto Idx = readStringIndex(NameTable);
if (std::error_code EC = Idx.getError())
return EC;

return StringRef(NameTable[*Idx]);
}

std::error_code
SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) {
auto NumSamples = readNumber<uint64_t>();
Expand Down Expand Up @@ -429,6 +446,48 @@ std::error_code SampleProfileReaderBinary::read() {
return sampleprof_error::success;
}

std::error_code SampleProfileReaderRawBinary::verifySPMagic(uint64_t Magic) {
if (Magic == SPMagic())
return sampleprof_error::success;
return sampleprof_error::bad_magic;
}

std::error_code
SampleProfileReaderCompactBinary::verifySPMagic(uint64_t Magic) {
if (Magic == SPMagic(SPF_Compact_Binary))
return sampleprof_error::success;
return sampleprof_error::bad_magic;
}

std::error_code SampleProfileReaderRawBinary::readNameTable() {
auto Size = readNumber<uint32_t>();
if (std::error_code EC = Size.getError())
return EC;
NameTable.reserve(*Size);
for (uint32_t I = 0; I < *Size; ++I) {
auto Name(readString());
if (std::error_code EC = Name.getError())
return EC;
NameTable.push_back(*Name);
}

return sampleprof_error::success;
}

std::error_code SampleProfileReaderCompactBinary::readNameTable() {
auto Size = readNumber<uint64_t>();
if (std::error_code EC = Size.getError())
return EC;
NameTable.reserve(*Size);
for (uint32_t I = 0; I < *Size; ++I) {
auto FID = readNumber<uint64_t>();
if (std::error_code EC = FID.getError())
return EC;
NameTable.push_back(std::to_string(*FID));
}
return sampleprof_error::success;
}

std::error_code SampleProfileReaderBinary::readHeader() {
Data = reinterpret_cast<const uint8_t *>(Buffer->getBufferStart());
End = Data + Buffer->getBufferSize();
Expand All @@ -437,7 +496,7 @@ std::error_code SampleProfileReaderBinary::readHeader() {
auto Magic = readNumber<uint64_t>();
if (std::error_code EC = Magic.getError())
return EC;
else if (*Magic != SPMagic())
else if (std::error_code EC = verifySPMagic(*Magic))
return sampleprof_error::bad_magic;

// Read the version number.
Expand All @@ -450,18 +509,8 @@ std::error_code SampleProfileReaderBinary::readHeader() {
if (std::error_code EC = readSummary())
return EC;

// Read the name table.
auto Size = readNumber<uint32_t>();
if (std::error_code EC = Size.getError())
if (std::error_code EC = readNameTable())
return EC;
NameTable.reserve(*Size);
for (uint32_t I = 0; I < *Size; ++I) {
auto Name(readString());
if (std::error_code EC = Name.getError())
return EC;
NameTable.push_back(*Name);
}

return sampleprof_error::success;
}

Expand Down Expand Up @@ -521,13 +570,20 @@ std::error_code SampleProfileReaderBinary::readSummary() {
return sampleprof_error::success;
}

bool SampleProfileReaderBinary::hasFormat(const MemoryBuffer &Buffer) {
bool SampleProfileReaderRawBinary::hasFormat(const MemoryBuffer &Buffer) {
const uint8_t *Data =
reinterpret_cast<const uint8_t *>(Buffer.getBufferStart());
uint64_t Magic = decodeULEB128(Data);
return Magic == SPMagic();
}

bool SampleProfileReaderCompactBinary::hasFormat(const MemoryBuffer &Buffer) {
const uint8_t *Data =
reinterpret_cast<const uint8_t *>(Buffer.getBufferStart());
uint64_t Magic = decodeULEB128(Data);
return Magic == SPMagic(SPF_Compact_Binary);
}

std::error_code SampleProfileReaderGCC::skipNextWord() {
uint32_t dummy;
if (!GcovBuffer.readInt(dummy))
Expand Down Expand Up @@ -813,8 +869,10 @@ SampleProfileReader::create(const Twine &Filename, LLVMContext &C) {
ErrorOr<std::unique_ptr<SampleProfileReader>>
SampleProfileReader::create(std::unique_ptr<MemoryBuffer> &B, LLVMContext &C) {
std::unique_ptr<SampleProfileReader> Reader;
if (SampleProfileReaderBinary::hasFormat(*B))
Reader.reset(new SampleProfileReaderBinary(std::move(B), C));
if (SampleProfileReaderRawBinary::hasFormat(*B))
Reader.reset(new SampleProfileReaderRawBinary(std::move(B), C));
else if (SampleProfileReaderCompactBinary::hasFormat(*B))
Reader.reset(new SampleProfileReaderCompactBinary(std::move(B), C));
else if (SampleProfileReaderGCC::hasFormat(*B))
Reader.reset(new SampleProfileReaderGCC(std::move(B), C));
else if (SampleProfileReaderText::hasFormat(*B))
Expand Down
76 changes: 57 additions & 19 deletions llvm/lib/ProfileData/SampleProfWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstdint>
Expand Down Expand Up @@ -144,13 +145,61 @@ void SampleProfileWriterBinary::addNames(const FunctionSamples &S) {
}
}

std::error_code SampleProfileWriterBinary::writeHeader(
const StringMap<FunctionSamples> &ProfileMap) {
void SampleProfileWriterBinary::stablizeNameTable(std::set<StringRef> &V) {
// Sort the names to make NameTable deterministic.
for (const auto &I : NameTable)
V.insert(I.first);
int i = 0;
for (const StringRef &N : V)
NameTable[N] = i++;
}

std::error_code SampleProfileWriterRawBinary::writeNameTable() {
auto &OS = *OutputStream;
std::set<StringRef> V;
stablizeNameTable(V);

// Write out the name table.
encodeULEB128(NameTable.size(), OS);
for (auto N : V) {
OS << N;
encodeULEB128(0, OS);
}
return sampleprof_error::success;
}

std::error_code SampleProfileWriterCompactBinary::writeNameTable() {
auto &OS = *OutputStream;
std::set<StringRef> V;
stablizeNameTable(V);

// Write out the name table.
encodeULEB128(NameTable.size(), OS);
for (auto N : V) {
encodeULEB128(MD5Hash(N), OS);
}
return sampleprof_error::success;
}

std::error_code SampleProfileWriterRawBinary::writeMagicIdent() {
auto &OS = *OutputStream;
// Write file magic identifier.
encodeULEB128(SPMagic(), OS);
encodeULEB128(SPVersion(), OS);
return sampleprof_error::success;
}

std::error_code SampleProfileWriterCompactBinary::writeMagicIdent() {
auto &OS = *OutputStream;
// Write file magic identifier.
encodeULEB128(SPMagic(SPF_Compact_Binary), OS);
encodeULEB128(SPVersion(), OS);
return sampleprof_error::success;
}

std::error_code SampleProfileWriterBinary::writeHeader(
const StringMap<FunctionSamples> &ProfileMap) {
writeMagicIdent();

computeSummary(ProfileMap);
if (auto EC = writeSummary())
Expand All @@ -162,20 +211,7 @@ std::error_code SampleProfileWriterBinary::writeHeader(
addNames(I.second);
}

// Sort the names to make NameTable is deterministic.
std::set<StringRef> V;
for (const auto &I : NameTable)
V.insert(I.first);
int i = 0;
for (const StringRef &N : V)
NameTable[N] = i++;

// Write out the name table.
encodeULEB128(NameTable.size(), OS);
for (auto N : V) {
OS << N;
encodeULEB128(0, OS);
}
writeNameTable();
return sampleprof_error::success;
}

Expand Down Expand Up @@ -258,7 +294,7 @@ ErrorOr<std::unique_ptr<SampleProfileWriter>>
SampleProfileWriter::create(StringRef Filename, SampleProfileFormat Format) {
std::error_code EC;
std::unique_ptr<raw_ostream> OS;
if (Format == SPF_Binary)
if (Format == SPF_Raw_Binary || Format == SPF_Compact_Binary)
OS.reset(new raw_fd_ostream(Filename, EC, sys::fs::F_None));
else
OS.reset(new raw_fd_ostream(Filename, EC, sys::fs::F_Text));
Expand All @@ -281,8 +317,10 @@ SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
std::error_code EC;
std::unique_ptr<SampleProfileWriter> Writer;

if (Format == SPF_Binary)
Writer.reset(new SampleProfileWriterBinary(OS));
if (Format == SPF_Raw_Binary)
Writer.reset(new SampleProfileWriterRawBinary(OS));
else if (Format == SPF_Compact_Binary)
Writer.reset(new SampleProfileWriterCompactBinary(OS));
else if (Format == SPF_Text)
Writer.reset(new SampleProfileWriterText(OS));
else if (Format == SPF_GCC)
Expand Down
13 changes: 10 additions & 3 deletions llvm/lib/Transforms/IPO/SampleProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,8 @@ SampleProfileLoader::findCalleeFunctionSamples(const Instruction &Inst) const {
if (FS == nullptr)
return nullptr;

std::string CalleeGUID;
CalleeName = getRepInFormat(CalleeName, Reader->getFormat(), CalleeGUID);
return FS->findFunctionSamplesAt(LineLocation(FunctionSamples::getOffset(DIL),
DIL->getBaseDiscriminator()),
CalleeName);
Expand Down Expand Up @@ -753,6 +755,7 @@ bool SampleProfileLoader::inlineHotFunctions(
Function &F, DenseSet<GlobalValue::GUID> &InlinedGUIDs) {
DenseSet<Instruction *> PromotedInsns;
bool Changed = false;
bool isCompact = (Reader->getFormat() == SPF_Compact_Binary);
while (true) {
bool LocalChanged = false;
SmallVector<Instruction *, 10> CIS;
Expand Down Expand Up @@ -784,7 +787,8 @@ bool SampleProfileLoader::inlineHotFunctions(
for (const auto *FS : findIndirectCallFunctionSamples(*I, Sum)) {
if (IsThinLTOPreLink) {
FS->findInlinedFunctions(InlinedGUIDs, F.getParent(),
PSI->getOrCompHotCountThreshold());
PSI->getOrCompHotCountThreshold(),
isCompact);
continue;
}
auto CalleeFunctionName = FS->getName();
Expand All @@ -793,7 +797,9 @@ bool SampleProfileLoader::inlineHotFunctions(
// clone the caller first, and inline the cloned caller if it is
// recursive. As llvm does not inline recursive calls, we will
// simply ignore it instead of handling it explicitly.
if (CalleeFunctionName == F.getName())
std::string FGUID;
auto Fname = getRepInFormat(F.getName(), Reader->getFormat(), FGUID);
if (CalleeFunctionName == Fname)
continue;

const char *Reason = "Callee function not available";
Expand Down Expand Up @@ -823,7 +829,8 @@ bool SampleProfileLoader::inlineHotFunctions(
LocalChanged = true;
} else if (IsThinLTOPreLink) {
findCalleeFunctionSamples(*I)->findInlinedFunctions(
InlinedGUIDs, F.getParent(), PSI->getOrCompHotCountThreshold());
InlinedGUIDs, F.getParent(), PSI->getOrCompHotCountThreshold(),
isCompact);
}
}
if (LocalChanged) {
Expand Down
Binary file not shown.
121 changes: 121 additions & 0 deletions llvm/test/Transforms/SampleProfile/compact-binary-profile.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/inline.prof -S | FileCheck %s
; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/inline.prof -S | FileCheck %s
; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/inline.compactbinary.afdo -S | FileCheck %s
; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/inline.compactbinary.afdo -S | FileCheck %s

; Original C++ test case
;
; #include <stdio.h>
;
; int sum(int x, int y) {
; return x + y;
; }
;
; int main() {
; int s, i = 0;
; while (i++ < 20000 * 20000)
; if (i != 100) s = sum(i, s); else s = 30;
; printf("sum is %d\n", s);
; return 0;
; }
;
@.str = private unnamed_addr constant [11 x i8] c"sum is %d\0A\00", align 1

; Check sample-profile phase using compactbinary format profile will annotate
; the IR with exactly the same result as using text format.
; CHECK: br i1 %cmp, label %while.body, label %while.end{{.*}} !prof ![[IDX1:[0-9]*]]
; CHECK: br i1 %cmp1, label %if.then, label %if.else{{.*}} !prof ![[IDX2:[0-9]*]]
; CHECK: call i32 (i8*, ...) @printf{{.*}} !prof ![[IDX3:[0-9]*]]
; CHECK: = !{!"TotalCount", i64 10944}
; CHECK: = !{!"MaxCount", i64 5553}
; CHECK: ![[IDX1]] = !{!"branch_weights", i32 5392, i32 163}
; CHECK: ![[IDX2]] = !{!"branch_weights", i32 5280, i32 113}
; CHECK: ![[IDX3]] = !{!"branch_weights", i32 1}

; Function Attrs: nounwind uwtable
define i32 @_Z3sumii(i32 %x, i32 %y) !dbg !4 {
entry:
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
store i32 %x, i32* %x.addr, align 4
store i32 %y, i32* %y.addr, align 4
%0 = load i32, i32* %x.addr, align 4, !dbg !11
%1 = load i32, i32* %y.addr, align 4, !dbg !11
%add = add nsw i32 %0, %1, !dbg !11
ret i32 %add, !dbg !11
}

; Function Attrs: uwtable
define i32 @main() !dbg !7 {
entry:
%retval = alloca i32, align 4
%s = alloca i32, align 4
%i = alloca i32, align 4
store i32 0, i32* %retval
store i32 0, i32* %i, align 4, !dbg !12
br label %while.cond, !dbg !13

while.cond: ; preds = %if.end, %entry
%0 = load i32, i32* %i, align 4, !dbg !14
%inc = add nsw i32 %0, 1, !dbg !14
store i32 %inc, i32* %i, align 4, !dbg !14
%cmp = icmp slt i32 %0, 400000000, !dbg !14
br i1 %cmp, label %while.body, label %while.end, !dbg !14

while.body: ; preds = %while.cond
%1 = load i32, i32* %i, align 4, !dbg !16
%cmp1 = icmp ne i32 %1, 100, !dbg !16
br i1 %cmp1, label %if.then, label %if.else, !dbg !16


if.then: ; preds = %while.body
%2 = load i32, i32* %i, align 4, !dbg !18
%3 = load i32, i32* %s, align 4, !dbg !18
%call = call i32 @_Z3sumii(i32 %2, i32 %3), !dbg !18
store i32 %call, i32* %s, align 4, !dbg !18
br label %if.end, !dbg !18

if.else: ; preds = %while.body
store i32 30, i32* %s, align 4, !dbg !20
br label %if.end

if.end: ; preds = %if.else, %if.then
br label %while.cond, !dbg !22

while.end: ; preds = %while.cond
%4 = load i32, i32* %s, align 4, !dbg !24
%call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i32 0, i32 0), i32 %4), !dbg !24
ret i32 0, !dbg !25
}

declare i32 @printf(i8*, ...) #2

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!8, !9}
!llvm.ident = !{!10}

!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5 ", isOptimized: false, emissionKind: NoDebug, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
!1 = !DIFile(filename: "calls.cc", directory: ".")
!2 = !{}
!4 = distinct !DISubprogram(name: "sum", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 3, file: !1, scope: !5, type: !6, retainedNodes: !2)
!5 = !DIFile(filename: "calls.cc", directory: ".")
!6 = !DISubroutineType(types: !2)
!7 = distinct !DISubprogram(name: "main", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 7, file: !1, scope: !5, type: !6, retainedNodes: !2)
!8 = !{i32 2, !"Dwarf Version", i32 4}
!9 = !{i32 1, !"Debug Info Version", i32 3}
!10 = !{!"clang version 3.5 "}
!11 = !DILocation(line: 4, scope: !4)
!12 = !DILocation(line: 8, scope: !7)
!13 = !DILocation(line: 9, scope: !7)
!14 = !DILocation(line: 9, scope: !15)
!15 = !DILexicalBlockFile(discriminator: 2, file: !1, scope: !7)
!16 = !DILocation(line: 10, scope: !17)
!17 = distinct !DILexicalBlock(line: 10, column: 0, file: !1, scope: !7)
!18 = !DILocation(line: 10, scope: !19)
!19 = !DILexicalBlockFile(discriminator: 2, file: !1, scope: !17)
!20 = !DILocation(line: 10, scope: !21)
!21 = !DILexicalBlockFile(discriminator: 4, file: !1, scope: !17)
!22 = !DILocation(line: 10, scope: !23)
!23 = !DILexicalBlockFile(discriminator: 6, file: !1, scope: !17)
!24 = !DILocation(line: 11, scope: !7)
!25 = !DILocation(line: 12, scope: !7)
28 changes: 19 additions & 9 deletions llvm/tools/llvm-profdata/llvm-profdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@

using namespace llvm;

enum ProfileFormat { PF_None = 0, PF_Text, PF_Binary, PF_GCC };
enum ProfileFormat {
PF_None = 0,
PF_Text,
PF_Compact_Binary,
PF_GCC,
PF_Raw_Binary
};

static void warn(Twine Message, std::string Whence = "",
std::string Hint = "") {
Expand Down Expand Up @@ -236,7 +242,8 @@ static void mergeInstrProfile(const WeightedFileVector &Inputs,
if (OutputFilename.compare("-") == 0)
exitWithError("Cannot write indexed profdata format to stdout.");

if (OutputFormat != PF_Binary && OutputFormat != PF_Text)
if (OutputFormat != PF_Raw_Binary && OutputFormat != PF_Compact_Binary &&
OutputFormat != PF_Text)
exitWithError("Unknown format is specified.");

std::error_code EC;
Expand Down Expand Up @@ -316,8 +323,8 @@ static void mergeInstrProfile(const WeightedFileVector &Inputs,
}

static sampleprof::SampleProfileFormat FormatMap[] = {
sampleprof::SPF_None, sampleprof::SPF_Text, sampleprof::SPF_Binary,
sampleprof::SPF_GCC};
sampleprof::SPF_None, sampleprof::SPF_Text, sampleprof::SPF_Compact_Binary,
sampleprof::SPF_GCC, sampleprof::SPF_Raw_Binary};

static void mergeSampleProfile(const WeightedFileVector &Inputs,
StringRef OutputFilename,
Expand Down Expand Up @@ -464,11 +471,14 @@ static int merge_main(int argc, const char *argv[]) {
cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
clEnumVal(sample, "Sample profile")));
cl::opt<ProfileFormat> OutputFormat(
cl::desc("Format of output profile"), cl::init(PF_Binary),
cl::values(clEnumValN(PF_Binary, "binary", "Binary encoding (default)"),
clEnumValN(PF_Text, "text", "Text encoding"),
clEnumValN(PF_GCC, "gcc",
"GCC encoding (only meaningful for -sample)")));
cl::desc("Format of output profile"), cl::init(PF_Raw_Binary),
cl::values(
clEnumValN(PF_Raw_Binary, "binary", "Binary encoding (default)"),
clEnumValN(PF_Compact_Binary, "compbinary",
"Compact binary encoding (default)"),
clEnumValN(PF_Text, "text", "Text encoding"),
clEnumValN(PF_GCC, "gcc",
"GCC encoding (only meaningful for -sample)")));
cl::opt<bool> OutputSparse("sparse", cl::init(false),
cl::desc("Generate a sparse profile (only meaningful for -instr)"));
cl::opt<unsigned> NumThreads(
Expand Down
35 changes: 26 additions & 9 deletions llvm/unittests/ProfileData/SampleProfTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,11 @@ struct SampleProfTest : ::testing::Test {
BarSamples.addTotalSamples(20301);
BarSamples.addHeadSamples(1437);
BarSamples.addBodySamples(1, 0, 1437);
BarSamples.addCalledTargetSamples(1, 0, "_M_construct<char *>", 1000);
BarSamples.addCalledTargetSamples(
1, 0, "string_view<std::allocator<char> >", 437);
// Test how reader/writer handles unmangled names.
StringRef MconstructName("_M_construct<char *>");
StringRef StringviewName("string_view<std::allocator<char> >");
BarSamples.addCalledTargetSamples(1, 0, MconstructName, 1000);
BarSamples.addCalledTargetSamples(1, 0, StringviewName, 437);

StringMap<FunctionSamples> Profiles;
Profiles[FooName] = std::move(FooSamples);
Expand All @@ -100,18 +102,29 @@ struct SampleProfTest : ::testing::Test {
StringMap<FunctionSamples> &ReadProfiles = Reader->getProfiles();
ASSERT_EQ(2u, ReadProfiles.size());

FunctionSamples &ReadFooSamples = ReadProfiles[FooName];
std::string FooGUID;
StringRef FooRep = getRepInFormat(FooName, Format, FooGUID);
FunctionSamples &ReadFooSamples = ReadProfiles[FooRep];
ASSERT_EQ(7711u, ReadFooSamples.getTotalSamples());
ASSERT_EQ(610u, ReadFooSamples.getHeadSamples());

FunctionSamples &ReadBarSamples = ReadProfiles[BarName];
std::string BarGUID;
StringRef BarRep = getRepInFormat(BarName, Format, BarGUID);
FunctionSamples &ReadBarSamples = ReadProfiles[BarRep];
ASSERT_EQ(20301u, ReadBarSamples.getTotalSamples());
ASSERT_EQ(1437u, ReadBarSamples.getHeadSamples());
ErrorOr<SampleRecord::CallTargetMap> CTMap =
ReadBarSamples.findCallTargetMapAt(1, 0);
ASSERT_FALSE(CTMap.getError());
ASSERT_EQ(1000u, CTMap.get()["_M_construct<char *>"]);
ASSERT_EQ(437u, CTMap.get()["string_view<std::allocator<char> >"]);

std::string MconstructGUID;
StringRef MconstructRep =
getRepInFormat(MconstructName, Format, MconstructGUID);
std::string StringviewGUID;
StringRef StringviewRep =
getRepInFormat(StringviewName, Format, StringviewGUID);
ASSERT_EQ(1000u, CTMap.get()[MconstructRep]);
ASSERT_EQ(437u, CTMap.get()[StringviewRep]);

auto VerifySummary = [](ProfileSummary &Summary) mutable {
ASSERT_EQ(ProfileSummary::PSK_Sample, Summary.getKind());
Expand Down Expand Up @@ -166,8 +179,12 @@ TEST_F(SampleProfTest, roundtrip_text_profile) {
testRoundTrip(SampleProfileFormat::SPF_Text);
}

TEST_F(SampleProfTest, roundtrip_binary_profile) {
testRoundTrip(SampleProfileFormat::SPF_Binary);
TEST_F(SampleProfTest, roundtrip_raw_binary_profile) {
testRoundTrip(SampleProfileFormat::SPF_Raw_Binary);
}

TEST_F(SampleProfTest, roundtrip_compact_binary_profile) {
testRoundTrip(SampleProfileFormat::SPF_Compact_Binary);
}

TEST_F(SampleProfTest, sample_overflow_saturation) {
Expand Down