diff options
Diffstat (limited to 'llvm/lib/ProfileData')
-rw-r--r-- | llvm/lib/ProfileData/DataAccessProf.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/ProfileData/IndexedMemProfData.cpp | 61 | ||||
-rw-r--r-- | llvm/lib/ProfileData/InstrProfReader.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/ProfileData/InstrProfWriter.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/ProfileData/MemProfReader.cpp | 30 |
5 files changed, 112 insertions, 19 deletions
diff --git a/llvm/lib/ProfileData/DataAccessProf.cpp b/llvm/lib/ProfileData/DataAccessProf.cpp index c5d0099..61a73fa 100644 --- a/llvm/lib/ProfileData/DataAccessProf.cpp +++ b/llvm/lib/ProfileData/DataAccessProf.cpp @@ -48,7 +48,8 @@ DataAccessProfData::getProfileRecord(const SymbolHandleRef SymbolID) const { auto It = Records.find(Key); if (It != Records.end()) { - return DataAccessProfRecord(Key, It->second.Locations); + return DataAccessProfRecord(Key, It->second.AccessCount, + It->second.Locations); } return std::nullopt; @@ -111,7 +112,8 @@ Error DataAccessProfData::addKnownSymbolWithoutSamples( auto CanonicalName = getCanonicalName(std::get<StringRef>(SymbolID)); if (!CanonicalName) return CanonicalName.takeError(); - KnownColdSymbols.insert(*CanonicalName); + KnownColdSymbols.insert( + saveStringToMap(StrToIndexMap, Saver, *CanonicalName).first); return Error::success(); } diff --git a/llvm/lib/ProfileData/IndexedMemProfData.cpp b/llvm/lib/ProfileData/IndexedMemProfData.cpp index 3d20f7a..cc1b031 100644 --- a/llvm/lib/ProfileData/IndexedMemProfData.cpp +++ b/llvm/lib/ProfileData/IndexedMemProfData.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ProfileData/DataAccessProf.h" #include "llvm/ProfileData/InstrProf.h" #include "llvm/ProfileData/InstrProfReader.h" #include "llvm/ProfileData/MemProf.h" @@ -216,7 +217,9 @@ static Error writeMemProfV2(ProfOStream &OS, static Error writeMemProfRadixTreeBased( ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, - memprof::IndexedVersion Version, bool MemProfFullSchema) { + memprof::IndexedVersion Version, bool MemProfFullSchema, + std::optional<std::reference_wrapper<data_access_prof::DataAccessProfData>> + DataAccessProfileData) { assert((Version == memprof::Version3 || Version == memprof::Version4) && "Unsupported version for radix tree format"); @@ -225,6 +228,8 @@ static Error writeMemProfRadixTreeBased( OS.write(0ULL); // Reserve space for the memprof call stack payload offset. OS.write(0ULL); // Reserve space for the memprof record payload offset. OS.write(0ULL); // Reserve space for the memprof record table offset. + if (Version == memprof::Version4) + OS.write(0ULL); // Reserve space for the data access profile offset. auto Schema = memprof::getHotColdSchema(); if (MemProfFullSchema) @@ -251,17 +256,26 @@ static Error writeMemProfRadixTreeBased( uint64_t RecordTableOffset = writeMemProfRecords( OS, MemProfData.Records, &Schema, Version, &MemProfCallStackIndexes); + uint64_t DataAccessProfOffset = 0; + if (DataAccessProfileData.has_value()) { + DataAccessProfOffset = OS.tell(); + if (Error E = (*DataAccessProfileData).get().serialize(OS)) + return E; + } + // Verify that the computation for the number of elements in the call stack // array works. assert(CallStackPayloadOffset + NumElements * sizeof(memprof::LinearFrameId) == RecordPayloadOffset); - uint64_t Header[] = { + SmallVector<uint64_t, 4> Header = { CallStackPayloadOffset, RecordPayloadOffset, RecordTableOffset, }; + if (Version == memprof::Version4) + Header.push_back(DataAccessProfOffset); OS.patch({{HeaderUpdatePos, Header}}); return Error::success(); @@ -272,28 +286,33 @@ static Error writeMemProfV3(ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, bool MemProfFullSchema) { return writeMemProfRadixTreeBased(OS, MemProfData, memprof::Version3, - MemProfFullSchema); + MemProfFullSchema, std::nullopt); } // Write out MemProf Version4 -static Error writeMemProfV4(ProfOStream &OS, - memprof::IndexedMemProfData &MemProfData, - bool MemProfFullSchema) { +static Error writeMemProfV4( + ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, + bool MemProfFullSchema, + std::optional<std::reference_wrapper<data_access_prof::DataAccessProfData>> + DataAccessProfileData) { return writeMemProfRadixTreeBased(OS, MemProfData, memprof::Version4, - MemProfFullSchema); + MemProfFullSchema, DataAccessProfileData); } // Write out the MemProf data in a requested version. -Error writeMemProf(ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, - memprof::IndexedVersion MemProfVersionRequested, - bool MemProfFullSchema) { +Error writeMemProf( + ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, + memprof::IndexedVersion MemProfVersionRequested, bool MemProfFullSchema, + std::optional<std::reference_wrapper<data_access_prof::DataAccessProfData>> + DataAccessProfileData) { switch (MemProfVersionRequested) { case memprof::Version2: return writeMemProfV2(OS, MemProfData, MemProfFullSchema); case memprof::Version3: return writeMemProfV3(OS, MemProfData, MemProfFullSchema); case memprof::Version4: - return writeMemProfV4(OS, MemProfData, MemProfFullSchema); + return writeMemProfV4(OS, MemProfData, MemProfFullSchema, + DataAccessProfileData); } return make_error<InstrProfError>( @@ -357,7 +376,10 @@ Error IndexedMemProfReader::deserializeV2(const unsigned char *Start, } Error IndexedMemProfReader::deserializeRadixTreeBased( - const unsigned char *Start, const unsigned char *Ptr) { + const unsigned char *Start, const unsigned char *Ptr, + memprof::IndexedVersion Version) { + assert((Version == memprof::Version3 || Version == memprof::Version4) && + "Unsupported version for radix tree format"); // The offset in the stream right before invoking // CallStackTableGenerator.Emit. const uint64_t CallStackPayloadOffset = @@ -369,6 +391,11 @@ Error IndexedMemProfReader::deserializeRadixTreeBased( const uint64_t RecordTableOffset = support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); + uint64_t DataAccessProfOffset = 0; + if (Version == memprof::Version4) + DataAccessProfOffset = + support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); + // Read the schema. auto SchemaOr = memprof::readMemProfSchema(Ptr); if (!SchemaOr) @@ -390,6 +417,14 @@ Error IndexedMemProfReader::deserializeRadixTreeBased( /*Payload=*/Start + RecordPayloadOffset, /*Base=*/Start, memprof::RecordLookupTrait(Version, Schema))); + if (DataAccessProfOffset > RecordTableOffset) { + DataAccessProfileData = + std::make_unique<data_access_prof::DataAccessProfData>(); + const unsigned char *DAPPtr = Start + DataAccessProfOffset; + if (Error E = DataAccessProfileData->deserialize(DAPPtr)) + return E; + } + return Error::success(); } @@ -423,7 +458,7 @@ Error IndexedMemProfReader::deserialize(const unsigned char *Start, case memprof::Version3: case memprof::Version4: // V3 and V4 share the same high-level structure (radix tree, linear IDs). - if (Error E = deserializeRadixTreeBased(Start, Ptr)) + if (Error E = deserializeRadixTreeBased(Start, Ptr, Version)) return E; break; } diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp index e6c8343..78aba992 100644 --- a/llvm/lib/ProfileData/InstrProfReader.cpp +++ b/llvm/lib/ProfileData/InstrProfReader.cpp @@ -1551,6 +1551,20 @@ memprof::AllMemProfData IndexedMemProfReader::getAllMemProfData() const { Pair.Record = std::move(*Record); AllMemProfData.HeapProfileRecords.push_back(std::move(Pair)); } + // Populate the data access profiles for yaml output. + if (DataAccessProfileData != nullptr) { + for (const auto &[SymHandleRef, RecordRef] : + DataAccessProfileData->getRecords()) + AllMemProfData.YamlifiedDataAccessProfiles.Records.push_back( + data_access_prof::DataAccessProfRecord( + SymHandleRef, RecordRef.AccessCount, RecordRef.Locations)); + for (StringRef ColdSymbol : DataAccessProfileData->getKnownColdSymbols()) + AllMemProfData.YamlifiedDataAccessProfiles.KnownColdSymbols.push_back( + ColdSymbol.str()); + for (uint64_t Hash : DataAccessProfileData->getKnownColdHashes()) + AllMemProfData.YamlifiedDataAccessProfiles.KnownColdHashes.push_back( + Hash); + } return AllMemProfData; } diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp index 2759346..b0012cc 100644 --- a/llvm/lib/ProfileData/InstrProfWriter.cpp +++ b/llvm/lib/ProfileData/InstrProfWriter.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/ProfileSummary.h" +#include "llvm/ProfileData/DataAccessProf.h" #include "llvm/ProfileData/IndexedMemProfData.h" #include "llvm/ProfileData/InstrProf.h" #include "llvm/ProfileData/MemProf.h" @@ -29,6 +30,7 @@ #include "llvm/Support/raw_ostream.h" #include <cstdint> #include <ctime> +#include <functional> #include <memory> #include <string> #include <tuple> @@ -152,9 +154,7 @@ void InstrProfWriter::setValueProfDataEndianness(llvm::endianness Endianness) { InfoObj->ValueProfDataEndianness = Endianness; } -void InstrProfWriter::setOutputSparse(bool Sparse) { - this->Sparse = Sparse; -} +void InstrProfWriter::setOutputSparse(bool Sparse) { this->Sparse = Sparse; } void InstrProfWriter::addRecord(NamedInstrProfRecord &&I, uint64_t Weight, function_ref<void(Error)> Warn) { @@ -329,6 +329,12 @@ void InstrProfWriter::addBinaryIds(ArrayRef<llvm::object::BuildID> BIs) { llvm::append_range(BinaryIds, BIs); } +void InstrProfWriter::addDataAccessProfData( + std::unique_ptr<data_access_prof::DataAccessProfData> + DataAccessProfDataIn) { + DataAccessProfileData = std::move(DataAccessProfDataIn); +} + void InstrProfWriter::addTemporalProfileTrace(TemporalProfTraceTy Trace) { assert(Trace.FunctionNameRefs.size() <= MaxTemporalProfTraceLength); assert(!Trace.FunctionNameRefs.empty()); @@ -614,8 +620,14 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) { uint64_t MemProfSectionStart = 0; if (static_cast<bool>(ProfileKind & InstrProfKind::MemProf)) { MemProfSectionStart = OS.tell(); + std::optional<std::reference_wrapper<data_access_prof::DataAccessProfData>> + DAP = std::nullopt; + if (DataAccessProfileData.get() != nullptr) + DAP = std::ref(*DataAccessProfileData.get()); + if (auto E = writeMemProf(OS, MemProfData, MemProfVersionRequested, - MemProfFullSchema)) + MemProfFullSchema, DAP)) + return E; } diff --git a/llvm/lib/ProfileData/MemProfReader.cpp b/llvm/lib/ProfileData/MemProfReader.cpp index e0f280b..7fe5145 100644 --- a/llvm/lib/ProfileData/MemProfReader.cpp +++ b/llvm/lib/ProfileData/MemProfReader.cpp @@ -37,6 +37,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" @@ -823,6 +824,35 @@ void YAMLMemProfReader::parse(StringRef YAMLData) { MemProfData.Records.try_emplace(GUID, std::move(IndexedRecord)); } + + if (Doc.YamlifiedDataAccessProfiles.isEmpty()) + return; + + auto ToSymHandleRef = [](data_access_prof::SymbolHandle Handle) + -> data_access_prof::SymbolHandleRef { + if (std::holds_alternative<std::string>(Handle)) + return StringRef(std::get<std::string>(Handle)); + return std::get<uint64_t>(Handle); + }; + + auto DataAccessProfileData = + std::make_unique<data_access_prof::DataAccessProfData>(); + for (const auto &Record : Doc.YamlifiedDataAccessProfiles.Records) + if (Error E = DataAccessProfileData->setDataAccessProfile( + ToSymHandleRef(Record.SymHandle), Record.AccessCount, + Record.Locations)) + reportFatalInternalError(std::move(E)); + + for (const uint64_t Hash : Doc.YamlifiedDataAccessProfiles.KnownColdHashes) + if (Error E = DataAccessProfileData->addKnownSymbolWithoutSamples(Hash)) + reportFatalInternalError(std::move(E)); + + for (const std::string &Sym : + Doc.YamlifiedDataAccessProfiles.KnownColdSymbols) + if (Error E = DataAccessProfileData->addKnownSymbolWithoutSamples(Sym)) + reportFatalInternalError(std::move(E)); + + setDataAccessProfileData(std::move(DataAccessProfileData)); } } // namespace memprof } // namespace llvm |