[llvm-branch-commits] [llvm] 8d8432d - Revert "[ctx_profile] Profile reader and writer (#91859)"
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue May 14 18:07:41 PDT 2024
Author: Mircea Trofin
Date: 2024-05-14T18:07:38-07:00
New Revision: 8d8432d158ca1cb8a138e1cee4d48f23ba9d4c64
URL: https://github.com/llvm/llvm-project/commit/8d8432d158ca1cb8a138e1cee4d48f23ba9d4c64
DIFF: https://github.com/llvm/llvm-project/commit/8d8432d158ca1cb8a138e1cee4d48f23ba9d4c64.diff
LOG: Revert "[ctx_profile] Profile reader and writer (#91859)"
This reverts commit dfdc3dcbe7f38bde64bc83a74b9c3451c50e1ad4.
Added:
Modified:
llvm/lib/ProfileData/CMakeLists.txt
llvm/unittests/ProfileData/CMakeLists.txt
Removed:
llvm/include/llvm/ProfileData/PGOCtxProfReader.h
llvm/include/llvm/ProfileData/PGOCtxProfWriter.h
llvm/lib/ProfileData/PGOCtxProfReader.cpp
llvm/lib/ProfileData/PGOCtxProfWriter.cpp
llvm/unittests/ProfileData/PGOCtxProfReaderWriterTest.cpp
################################################################################
diff --git a/llvm/include/llvm/ProfileData/PGOCtxProfReader.h b/llvm/include/llvm/ProfileData/PGOCtxProfReader.h
deleted file mode 100644
index a19b3f51d642d..0000000000000
--- a/llvm/include/llvm/ProfileData/PGOCtxProfReader.h
+++ /dev/null
@@ -1,92 +0,0 @@
-//===--- PGOCtxProfReader.h - Contextual profile reader ---------*- 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-///
-/// Reader for contextual iFDO profile, which comes in bitstream format.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_PROFILEDATA_CTXINSTRPROFILEREADER_H
-#define LLVM_PROFILEDATA_CTXINSTRPROFILEREADER_H
-
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/Bitstream/BitstreamReader.h"
-#include "llvm/IR/GlobalValue.h"
-#include "llvm/ProfileData/PGOCtxProfWriter.h"
-#include "llvm/Support/Error.h"
-#include <map>
-#include <vector>
-
-namespace llvm {
-/// The loaded contextual profile, suitable for mutation during IPO passes. We
-/// generally expect a fraction of counters and of callsites to be populated.
-/// We continue to model counters as vectors, but callsites are modeled as a map
-/// of a map. The expectation is that, typically, there is a small number of
-/// indirect targets (usually, 1 for direct calls); but potentially a large
-/// number of callsites, and, as inlining progresses, the callsite count of a
-/// caller will grow.
-class PGOContextualProfile final {
-public:
- using CallTargetMapTy = std::map<GlobalValue::GUID, PGOContextualProfile>;
- using CallsiteMapTy = DenseMap<uint32_t, CallTargetMapTy>;
-
-private:
- friend class PGOCtxProfileReader;
- GlobalValue::GUID GUID = 0;
- SmallVector<uint64_t, 16> Counters;
- CallsiteMapTy Callsites;
-
- PGOContextualProfile(GlobalValue::GUID G,
- SmallVectorImpl<uint64_t> &&Counters)
- : GUID(G), Counters(std::move(Counters)) {}
-
- Expected<PGOContextualProfile &>
- getOrEmplace(uint32_t Index, GlobalValue::GUID G,
- SmallVectorImpl<uint64_t> &&Counters);
-
-public:
- PGOContextualProfile(const PGOContextualProfile &) = delete;
- PGOContextualProfile &operator=(const PGOContextualProfile &) = delete;
- PGOContextualProfile(PGOContextualProfile &&) = default;
- PGOContextualProfile &operator=(PGOContextualProfile &&) = default;
-
- GlobalValue::GUID guid() const { return GUID; }
- const SmallVectorImpl<uint64_t> &counters() const { return Counters; }
- const CallsiteMapTy &callsites() const { return Callsites; }
- CallsiteMapTy &callsites() { return Callsites; }
-
- bool hasCallsite(uint32_t I) const {
- return Callsites.find(I) != Callsites.end();
- }
-
- const CallTargetMapTy &callsite(uint32_t I) const {
- assert(hasCallsite(I) && "Callsite not found");
- return Callsites.find(I)->second;
- }
- void getContainedGuids(DenseSet<GlobalValue::GUID> &Guids) const;
-};
-
-class PGOCtxProfileReader final {
- BitstreamCursor &Cursor;
- Expected<BitstreamEntry> advance();
- Error readMetadata();
- Error wrongValue(const Twine &);
- Error unsupported(const Twine &);
-
- Expected<std::pair<std::optional<uint32_t>, PGOContextualProfile>>
- readContext(bool ExpectIndex);
- bool canReadContext();
-
-public:
- PGOCtxProfileReader(BitstreamCursor &Cursor) : Cursor(Cursor) {}
-
- Expected<std::map<GlobalValue::GUID, PGOContextualProfile>> loadContexts();
-};
-} // namespace llvm
-#endif
diff --git a/llvm/include/llvm/ProfileData/PGOCtxProfWriter.h b/llvm/include/llvm/ProfileData/PGOCtxProfWriter.h
deleted file mode 100644
index 15578c51a4957..0000000000000
--- a/llvm/include/llvm/ProfileData/PGOCtxProfWriter.h
+++ /dev/null
@@ -1,91 +0,0 @@
-//===- PGOCtxProfWriter.h - Contextual Profile Writer -----------*- 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 declares a utility for writing a contextual profile to bitstream.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_PROFILEDATA_PGOCTXPROFWRITER_H_
-#define LLVM_PROFILEDATA_PGOCTXPROFWRITER_H_
-
-#include "llvm/Bitstream/BitstreamWriter.h"
-#include "llvm/ProfileData/CtxInstrContextNode.h"
-
-namespace llvm {
-enum PGOCtxProfileRecords { Invalid = 0, Version, Guid, CalleeIndex, Counters };
-
-enum PGOCtxProfileBlockIDs {
- ProfileMetadataBlockID = 100,
- ContextNodeBlockID = ProfileMetadataBlockID + 1
-};
-
-/// Write one or more ContextNodes to the provided raw_fd_stream.
-/// The caller must destroy the PGOCtxProfileWriter object before closing the
-/// stream.
-/// The design allows serializing a bunch of contexts embedded in some other
-/// file. The overall format is:
-///
-/// [... other data written to the stream...]
-/// SubBlock(ProfileMetadataBlockID)
-/// Version
-/// SubBlock(ContextNodeBlockID)
-/// [RECORDS]
-/// SubBlock(ContextNodeBlockID)
-/// [RECORDS]
-/// [... more SubBlocks]
-/// EndBlock
-/// EndBlock
-///
-/// The "RECORDS" are bitsream records. The IDs are in CtxProfileCodes (except)
-/// for Version, which is just for metadata). All contexts will have Guid and
-/// Counters, and all but the roots have CalleeIndex. The order in which the
-/// records appear does not matter, but they must precede any subcontexts,
-/// because that helps keep the reader code simpler.
-///
-/// Subblock containment captures the context->subcontext relationship. The
-/// "next()" relationship in the raw profile, between call targets of indirect
-/// calls, are just modeled as peer subblocks where the callee index is the
-/// same.
-///
-/// Versioning: the writer may produce additional records not known by the
-/// reader. The version number indicates a more structural change.
-/// The current version, in particular, is set up to expect optional extensions
-/// like value profiling - which would appear as additional records. For
-/// example, value profiling would produce a new record with a new record ID,
-/// containing the profiled values (much like the counters)
-class PGOCtxProfileWriter final {
- SmallVector<char, 1 << 20> Buff;
- BitstreamWriter Writer;
-
- void writeCounters(const ctx_profile::ContextNode &Node);
- void writeImpl(std::optional<uint32_t> CallerIndex,
- const ctx_profile::ContextNode &Node);
-
-public:
- PGOCtxProfileWriter(raw_fd_stream &Out,
- std::optional<unsigned> VersionOverride = std::nullopt)
- : Writer(Buff, &Out, 0) {
- Writer.EnterSubblock(PGOCtxProfileBlockIDs::ProfileMetadataBlockID,
- CodeLen);
- const auto Version = VersionOverride ? *VersionOverride : CurrentVersion;
- Writer.EmitRecord(PGOCtxProfileRecords::Version,
- SmallVector<unsigned, 1>({Version}));
- }
-
- ~PGOCtxProfileWriter() { Writer.ExitBlock(); }
-
- void write(const ctx_profile::ContextNode &);
-
- // constants used in writing which a reader may find useful.
- static constexpr unsigned CodeLen = 2;
- static constexpr uint32_t CurrentVersion = 1;
- static constexpr unsigned VBREncodingBits = 6;
-};
-
-} // namespace llvm
-#endif
diff --git a/llvm/lib/ProfileData/CMakeLists.txt b/llvm/lib/ProfileData/CMakeLists.txt
index 2397eebaf7b19..408f9ff01ec87 100644
--- a/llvm/lib/ProfileData/CMakeLists.txt
+++ b/llvm/lib/ProfileData/CMakeLists.txt
@@ -7,8 +7,6 @@ add_llvm_component_library(LLVMProfileData
ItaniumManglingCanonicalizer.cpp
MemProf.cpp
MemProfReader.cpp
- PGOCtxProfReader.cpp
- PGOCtxProfWriter.cpp
ProfileSummaryBuilder.cpp
SampleProf.cpp
SampleProfReader.cpp
diff --git a/llvm/lib/ProfileData/PGOCtxProfReader.cpp b/llvm/lib/ProfileData/PGOCtxProfReader.cpp
deleted file mode 100644
index 3710f2e4b8185..0000000000000
--- a/llvm/lib/ProfileData/PGOCtxProfReader.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-//===- PGOCtxProfReader.cpp - Contextual Instrumentation profile reader ---===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Read a contextual profile into a datastructure suitable for maintenance
-// throughout IPO
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ProfileData/PGOCtxProfReader.h"
-#include "llvm/Bitstream/BitCodeEnums.h"
-#include "llvm/Bitstream/BitstreamReader.h"
-#include "llvm/ProfileData/InstrProf.h"
-#include "llvm/ProfileData/PGOCtxProfWriter.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/Error.h"
-
-using namespace llvm;
-
-// FIXME(#92054) - these Error handling macros are (re-)invented in a few
-// places.
-#define EXPECT_OR_RET(LHS, RHS) \
- auto LHS = RHS; \
- if (!LHS) \
- return LHS.takeError();
-
-#define RET_ON_ERR(EXPR) \
- if (auto Err = (EXPR)) \
- return Err;
-
-Expected<PGOContextualProfile &>
-PGOContextualProfile::getOrEmplace(uint32_t Index, GlobalValue::GUID G,
- SmallVectorImpl<uint64_t> &&Counters) {
- auto [Iter, Inserted] = Callsites[Index].insert(
- {G, PGOContextualProfile(G, std::move(Counters))});
- if (!Inserted)
- return make_error<InstrProfError>(instrprof_error::invalid_prof,
- "Duplicate GUID for same callsite.");
- return Iter->second;
-}
-
-void PGOContextualProfile::getContainedGuids(
- DenseSet<GlobalValue::GUID> &Guids) const {
- Guids.insert(GUID);
- for (const auto &[_, Callsite] : Callsites)
- for (const auto &[_, Callee] : Callsite)
- Callee.getContainedGuids(Guids);
-}
-
-Expected<BitstreamEntry> PGOCtxProfileReader::advance() {
- return Cursor.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
-}
-
-Error PGOCtxProfileReader::wrongValue(const Twine &Msg) {
- return make_error<InstrProfError>(instrprof_error::invalid_prof, Msg);
-}
-
-Error PGOCtxProfileReader::unsupported(const Twine &Msg) {
- return make_error<InstrProfError>(instrprof_error::unsupported_version, Msg);
-}
-
-bool PGOCtxProfileReader::canReadContext() {
- auto Blk = advance();
- if (!Blk) {
- consumeError(Blk.takeError());
- return false;
- }
- return Blk->Kind == BitstreamEntry::SubBlock &&
- Blk->ID == PGOCtxProfileBlockIDs::ContextNodeBlockID;
-}
-
-Expected<std::pair<std::optional<uint32_t>, PGOContextualProfile>>
-PGOCtxProfileReader::readContext(bool ExpectIndex) {
- RET_ON_ERR(Cursor.EnterSubBlock(PGOCtxProfileBlockIDs::ContextNodeBlockID));
-
- std::optional<ctx_profile::GUID> Guid;
- std::optional<SmallVector<uint64_t, 16>> Counters;
- std::optional<uint32_t> CallsiteIndex;
-
- SmallVector<uint64_t, 1> RecordValues;
-
- // We don't prescribe the order in which the records come in, and we are ok
- // if other unsupported records appear. We seek in the current subblock until
- // we get all we know.
- auto GotAllWeNeed = [&]() {
- return Guid.has_value() && Counters.has_value() &&
- (!ExpectIndex || CallsiteIndex.has_value());
- };
- while (!GotAllWeNeed()) {
- RecordValues.clear();
- EXPECT_OR_RET(Entry, advance());
- if (Entry->Kind != BitstreamEntry::Record)
- return wrongValue(
- "Expected records before encountering more subcontexts");
- EXPECT_OR_RET(ReadRecord,
- Cursor.readRecord(bitc::UNABBREV_RECORD, RecordValues));
- switch (*ReadRecord) {
- case PGOCtxProfileRecords::Guid:
- if (RecordValues.size() != 1)
- return wrongValue("The GUID record should have exactly one value");
- Guid = RecordValues[0];
- break;
- case PGOCtxProfileRecords::Counters:
- Counters = std::move(RecordValues);
- if (Counters->empty())
- return wrongValue("Empty counters. At least the entry counter (one "
- "value) was expected");
- break;
- case PGOCtxProfileRecords::CalleeIndex:
- if (!ExpectIndex)
- return wrongValue("The root context should not have a callee index");
- if (RecordValues.size() != 1)
- return wrongValue("The callee index should have exactly one value");
- CallsiteIndex = RecordValues[0];
- break;
- default:
- // OK if we see records we do not understand, like records (profile
- // components) introduced later.
- break;
- }
- }
-
- PGOContextualProfile Ret(*Guid, std::move(*Counters));
-
- while (canReadContext()) {
- EXPECT_OR_RET(SC, readContext(true));
- auto &Targets = Ret.callsites()[*SC->first];
- auto [_, Inserted] =
- Targets.insert({SC->second.guid(), std::move(SC->second)});
- if (!Inserted)
- return wrongValue(
- "Unexpected duplicate target (callee) at the same callsite.");
- }
- return std::make_pair(CallsiteIndex, std::move(Ret));
-}
-
-Error PGOCtxProfileReader::readMetadata() {
- EXPECT_OR_RET(Blk, advance());
- if (Blk->Kind != BitstreamEntry::SubBlock)
- return unsupported("Expected Version record");
- RET_ON_ERR(
- Cursor.EnterSubBlock(PGOCtxProfileBlockIDs::ProfileMetadataBlockID));
- EXPECT_OR_RET(MData, advance());
- if (MData->Kind != BitstreamEntry::Record)
- return unsupported("Expected Version record");
-
- SmallVector<uint64_t, 1> Ver;
- EXPECT_OR_RET(Code, Cursor.readRecord(bitc::UNABBREV_RECORD, Ver));
- if (*Code != PGOCtxProfileRecords::Version)
- return unsupported("Expected Version record");
- if (Ver.size() != 1 || Ver[0] > PGOCtxProfileWriter::CurrentVersion)
- return unsupported("Version " + Twine(*Code) +
- " is higher than supported version " +
- Twine(PGOCtxProfileWriter::CurrentVersion));
- return Error::success();
-}
-
-Expected<std::map<GlobalValue::GUID, PGOContextualProfile>>
-PGOCtxProfileReader::loadContexts() {
- std::map<GlobalValue::GUID, PGOContextualProfile> Ret;
- RET_ON_ERR(readMetadata());
- while (canReadContext()) {
- EXPECT_OR_RET(E, readContext(false));
- auto Key = E->second.guid();
- if (!Ret.insert({Key, std::move(E->second)}).second)
- return wrongValue("Duplicate roots");
- }
- return Ret;
-}
diff --git a/llvm/lib/ProfileData/PGOCtxProfWriter.cpp b/llvm/lib/ProfileData/PGOCtxProfWriter.cpp
deleted file mode 100644
index 5081797564469..0000000000000
--- a/llvm/lib/ProfileData/PGOCtxProfWriter.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-//===- PGOCtxProfWriter.cpp - Contextual Instrumentation profile writer ---===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Write a contextual profile to bitstream.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ProfileData/PGOCtxProfWriter.h"
-#include "llvm/Bitstream/BitCodeEnums.h"
-
-using namespace llvm;
-using namespace llvm::ctx_profile;
-
-void PGOCtxProfileWriter::writeCounters(const ContextNode &Node) {
- Writer.EmitCode(bitc::UNABBREV_RECORD);
- Writer.EmitVBR(PGOCtxProfileRecords::Counters, VBREncodingBits);
- Writer.EmitVBR(Node.counters_size(), VBREncodingBits);
- for (uint32_t I = 0U; I < Node.counters_size(); ++I)
- Writer.EmitVBR64(Node.counters()[I], VBREncodingBits);
-}
-
-// recursively write all the subcontexts. We do need to traverse depth first to
-// model the context->subcontext implicitly, and since this captures call
-// stacks, we don't really need to be worried about stack overflow and we can
-// keep the implementation simple.
-void PGOCtxProfileWriter::writeImpl(std::optional<uint32_t> CallerIndex,
- const ContextNode &Node) {
- Writer.EnterSubblock(PGOCtxProfileBlockIDs::ContextNodeBlockID, CodeLen);
- Writer.EmitRecord(PGOCtxProfileRecords::Guid,
- SmallVector<uint64_t, 1>{Node.guid()});
- if (CallerIndex)
- Writer.EmitRecord(PGOCtxProfileRecords::CalleeIndex,
- SmallVector<uint64_t, 1>{*CallerIndex});
- writeCounters(Node);
- for (uint32_t I = 0U; I < Node.callsites_size(); ++I)
- for (const auto *Subcontext = Node.subContexts()[I]; Subcontext;
- Subcontext = Subcontext->next())
- writeImpl(I, *Subcontext);
- Writer.ExitBlock();
-}
-
-void PGOCtxProfileWriter::write(const ContextNode &RootNode) {
- writeImpl(std::nullopt, RootNode);
-}
diff --git a/llvm/unittests/ProfileData/CMakeLists.txt b/llvm/unittests/ProfileData/CMakeLists.txt
index c92642ded8282..ce3a0a45ccf18 100644
--- a/llvm/unittests/ProfileData/CMakeLists.txt
+++ b/llvm/unittests/ProfileData/CMakeLists.txt
@@ -13,7 +13,6 @@ add_llvm_unittest(ProfileDataTests
InstrProfTest.cpp
ItaniumManglingCanonicalizerTest.cpp
MemProfTest.cpp
- PGOCtxProfReaderWriterTest.cpp
SampleProfTest.cpp
SymbolRemappingReaderTest.cpp
)
diff --git a/llvm/unittests/ProfileData/PGOCtxProfReaderWriterTest.cpp b/llvm/unittests/ProfileData/PGOCtxProfReaderWriterTest.cpp
deleted file mode 100644
index d2cdbb28e2fce..0000000000000
--- a/llvm/unittests/ProfileData/PGOCtxProfReaderWriterTest.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-//===-------------- PGOCtxProfReadWriteTest.cpp ---------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Bitstream/BitstreamReader.h"
-#include "llvm/ProfileData/CtxInstrContextNode.h"
-#include "llvm/ProfileData/PGOCtxProfReader.h"
-#include "llvm/ProfileData/PGOCtxProfWriter.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Testing/Support/SupportHelpers.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-using namespace llvm::ctx_profile;
-
-class PGOCtxProfRWTest : public ::testing::Test {
- std::vector<std::unique_ptr<char[]>> Nodes;
- std::map<GUID, const ContextNode *> Roots;
-
-public:
- ContextNode *createNode(GUID Guid, uint32_t NrCounters, uint32_t NrCallsites,
- ContextNode *Next = nullptr) {
- auto AllocSize = ContextNode::getAllocSize(NrCounters, NrCallsites);
- auto *Mem = Nodes.emplace_back(std::make_unique<char[]>(AllocSize)).get();
- std::memset(Mem, 0, AllocSize);
- auto *Ret = new (Mem) ContextNode(Guid, NrCounters, NrCallsites, Next);
- return Ret;
- }
-
- void SetUp() override {
- // Root (guid 1) has 2 callsites, one used for an indirect call to either
- // guid 2 or 4.
- // guid 2 calls guid 5
- // guid 5 calls guid 2
- // there's also a second root, guid3.
- auto *Root1 = createNode(1, 2, 2);
- Root1->counters()[0] = 10;
- Root1->counters()[1] = 11;
- Roots.insert({1, Root1});
- auto *L1 = createNode(2, 1, 1);
- L1->counters()[0] = 12;
- Root1->subContexts()[1] = createNode(4, 3, 1, L1);
- Root1->subContexts()[1]->counters()[0] = 13;
- Root1->subContexts()[1]->counters()[1] = 14;
- Root1->subContexts()[1]->counters()[2] = 15;
-
- auto *L3 = createNode(5, 6, 3);
- for (auto I = 0; I < 6; ++I)
- L3->counters()[I] = 16 + I;
- L1->subContexts()[0] = L3;
- L3->subContexts()[2] = createNode(2, 1, 1);
- L3->subContexts()[2]->counters()[0] = 30;
- auto *Root2 = createNode(3, 1, 0);
- Root2->counters()[0] = 40;
- Roots.insert({3, Root2});
- }
-
- const std::map<GUID, const ContextNode *> &roots() const { return Roots; }
-};
-
-void checkSame(const ContextNode &Raw, const PGOContextualProfile &Profile) {
- EXPECT_EQ(Raw.guid(), Profile.guid());
- ASSERT_EQ(Raw.counters_size(), Profile.counters().size());
- for (auto I = 0U; I < Raw.counters_size(); ++I)
- EXPECT_EQ(Raw.counters()[I], Profile.counters()[I]);
-
- for (auto I = 0U; I < Raw.callsites_size(); ++I) {
- if (Raw.subContexts()[I] == nullptr)
- continue;
- EXPECT_TRUE(Profile.hasCallsite(I));
- const auto &ProfileTargets = Profile.callsite(I);
-
- std::map<GUID, const ContextNode *> Targets;
- for (const auto *N = Raw.subContexts()[I]; N; N = N->next())
- EXPECT_TRUE(Targets.insert({N->guid(), N}).second);
-
- EXPECT_EQ(Targets.size(), ProfileTargets.size());
- for (auto It : Targets) {
- auto PIt = ProfileTargets.find(It.second->guid());
- EXPECT_NE(PIt, ProfileTargets.end());
- checkSame(*It.second, PIt->second);
- }
- }
-}
-
-TEST_F(PGOCtxProfRWTest, RoundTrip) {
- llvm::unittest::TempFile ProfileFile("ctx_profile", "", "", /*Unique*/ true);
- {
- std::error_code EC;
- raw_fd_stream Out(ProfileFile.path(), EC);
- ASSERT_FALSE(EC);
- {
- PGOCtxProfileWriter Writer(Out);
- for (auto &[_, R] : roots())
- Writer.write(*R);
- }
- }
- {
- ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
- MemoryBuffer::getFile(ProfileFile.path());
- ASSERT_TRUE(!!MB);
- ASSERT_NE(*MB, nullptr);
- BitstreamCursor Cursor((*MB)->getBuffer());
- PGOCtxProfileReader Reader(Cursor);
- auto Expected = Reader.loadContexts();
- ASSERT_TRUE(!!Expected);
- auto &Ctxes = *Expected;
- EXPECT_EQ(Ctxes.size(), roots().size());
- EXPECT_EQ(Ctxes.size(), 2U);
- for (auto &[G, R] : roots())
- checkSame(*R, Ctxes.find(G)->second);
- }
-}
-
-TEST_F(PGOCtxProfRWTest, InvalidCounters) {
- auto *R = createNode(1, 0, 1);
- llvm::unittest::TempFile ProfileFile("ctx_profile", "", "", /*Unique*/ true);
- {
- std::error_code EC;
- raw_fd_stream Out(ProfileFile.path(), EC);
- ASSERT_FALSE(EC);
- {
- PGOCtxProfileWriter Writer(Out);
- Writer.write(*R);
- }
- }
- {
- auto MB = MemoryBuffer::getFile(ProfileFile.path());
- ASSERT_TRUE(!!MB);
- ASSERT_NE(*MB, nullptr);
- BitstreamCursor Cursor((*MB)->getBuffer());
- PGOCtxProfileReader Reader(Cursor);
- auto Expected = Reader.loadContexts();
- EXPECT_FALSE(Expected);
- consumeError(Expected.takeError());
- }
-}
-
-TEST_F(PGOCtxProfRWTest, Empty) {
- BitstreamCursor Cursor("");
- PGOCtxProfileReader Reader(Cursor);
- auto Expected = Reader.loadContexts();
- EXPECT_FALSE(Expected);
- consumeError(Expected.takeError());
-}
-
-TEST_F(PGOCtxProfRWTest, Invalid) {
- BitstreamCursor Cursor("Surely this is not valid");
- PGOCtxProfileReader Reader(Cursor);
- auto Expected = Reader.loadContexts();
- EXPECT_FALSE(Expected);
- consumeError(Expected.takeError());
-}
-
-TEST_F(PGOCtxProfRWTest, ValidButEmpty) {
- llvm::unittest::TempFile ProfileFile("ctx_profile", "", "", /*Unique*/ true);
- {
- std::error_code EC;
- raw_fd_stream Out(ProfileFile.path(), EC);
- ASSERT_FALSE(EC);
- {
- PGOCtxProfileWriter Writer(Out);
- // don't write anything - this will just produce the metadata subblock.
- }
- }
- {
- auto MB = MemoryBuffer::getFile(ProfileFile.path());
- ASSERT_TRUE(!!MB);
- ASSERT_NE(*MB, nullptr);
- BitstreamCursor Cursor((*MB)->getBuffer());
- PGOCtxProfileReader Reader(Cursor);
- auto Expected = Reader.loadContexts();
- EXPECT_TRUE(!!Expected);
- EXPECT_TRUE(Expected->empty());
- }
-}
-
-TEST_F(PGOCtxProfRWTest, WrongVersion) {
- llvm::unittest::TempFile ProfileFile("ctx_profile", "", "", /*Unique*/ true);
- {
- std::error_code EC;
- raw_fd_stream Out(ProfileFile.path(), EC);
- ASSERT_FALSE(EC);
- {
- PGOCtxProfileWriter Writer(Out, PGOCtxProfileWriter::CurrentVersion + 1);
- }
- }
- {
- auto MB = MemoryBuffer::getFile(ProfileFile.path());
- ASSERT_TRUE(!!MB);
- ASSERT_NE(*MB, nullptr);
- BitstreamCursor Cursor((*MB)->getBuffer());
- PGOCtxProfileReader Reader(Cursor);
- auto Expected = Reader.loadContexts();
- EXPECT_FALSE(Expected);
- consumeError(Expected.takeError());
- }
-}
-
-TEST_F(PGOCtxProfRWTest, DuplicateRoots) {
- llvm::unittest::TempFile ProfileFile("ctx_profile", "", "", /*Unique*/ true);
- {
- std::error_code EC;
- raw_fd_stream Out(ProfileFile.path(), EC);
- ASSERT_FALSE(EC);
- {
- PGOCtxProfileWriter Writer(Out);
- Writer.write(*createNode(1, 1, 1));
- Writer.write(*createNode(1, 1, 1));
- }
- }
- {
- auto MB = MemoryBuffer::getFile(ProfileFile.path());
- ASSERT_TRUE(!!MB);
- ASSERT_NE(*MB, nullptr);
- BitstreamCursor Cursor((*MB)->getBuffer());
- PGOCtxProfileReader Reader(Cursor);
- auto Expected = Reader.loadContexts();
- EXPECT_FALSE(Expected);
- consumeError(Expected.takeError());
- }
-}
-
-TEST_F(PGOCtxProfRWTest, DuplicateTargets) {
- llvm::unittest::TempFile ProfileFile("ctx_profile", "", "", /*Unique*/ true);
- {
- std::error_code EC;
- raw_fd_stream Out(ProfileFile.path(), EC);
- ASSERT_FALSE(EC);
- {
- auto *R = createNode(1, 1, 1);
- auto *L1 = createNode(2, 1, 0);
- auto *L2 = createNode(2, 1, 0, L1);
- R->subContexts()[0] = L2;
- PGOCtxProfileWriter Writer(Out);
- Writer.write(*R);
- }
- }
- {
- auto MB = MemoryBuffer::getFile(ProfileFile.path());
- ASSERT_TRUE(!!MB);
- ASSERT_NE(*MB, nullptr);
- BitstreamCursor Cursor((*MB)->getBuffer());
- PGOCtxProfileReader Reader(Cursor);
- auto Expected = Reader.loadContexts();
- EXPECT_FALSE(Expected);
- consumeError(Expected.takeError());
- }
-}
More information about the llvm-branch-commits
mailing list