1 //===- PGOCtxProfWriter.h - Contextual Profile Writer -----------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file declares a utility for writing a contextual profile to bitstream. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_PROFILEDATA_PGOCTXPROFWRITER_H_ 14 #define LLVM_PROFILEDATA_PGOCTXPROFWRITER_H_ 15 16 #include "llvm/ADT/StringExtras.h" 17 #include "llvm/Bitstream/BitCodeEnums.h" 18 #include "llvm/Bitstream/BitstreamWriter.h" 19 #include "llvm/ProfileData/CtxInstrContextNode.h" 20 #include "llvm/Support/Compiler.h" 21 22 namespace llvm { 23 enum PGOCtxProfileRecords { 24 Invalid = 0, 25 Version, 26 Guid, 27 CallsiteIndex, 28 Counters, 29 TotalRootEntryCount 30 }; 31 32 enum PGOCtxProfileBlockIDs { 33 FIRST_VALID = bitc::FIRST_APPLICATION_BLOCKID, 34 ProfileMetadataBlockID = FIRST_VALID, 35 ContextsSectionBlockID = ProfileMetadataBlockID + 1, 36 ContextRootBlockID = ContextsSectionBlockID + 1, 37 ContextNodeBlockID = ContextRootBlockID + 1, 38 FlatProfilesSectionBlockID = ContextNodeBlockID + 1, 39 FlatProfileBlockID = FlatProfilesSectionBlockID + 1, 40 UnhandledBlockID = FlatProfileBlockID + 1, 41 LAST_VALID = UnhandledBlockID 42 }; 43 44 /// Write one or more ContextNodes to the provided raw_fd_stream. 45 /// The caller must destroy the PGOCtxProfileWriter object before closing the 46 /// stream. 47 /// The design allows serializing a bunch of contexts embedded in some other 48 /// file. The overall format is: 49 /// 50 /// [... other data written to the stream...] 51 /// SubBlock(ProfileMetadataBlockID) 52 /// Version 53 /// SubBlock(ContextNodeBlockID) 54 /// [RECORDS] 55 /// SubBlock(ContextNodeBlockID) 56 /// [RECORDS] 57 /// [... more SubBlocks] 58 /// EndBlock 59 /// EndBlock 60 /// 61 /// The "RECORDS" are bitsream records. The IDs are in CtxProfileCodes (except) 62 /// for Version, which is just for metadata). All contexts will have Guid and 63 /// Counters, and all but the roots have CalleeIndex. The order in which the 64 /// records appear does not matter, but they must precede any subcontexts, 65 /// because that helps keep the reader code simpler. 66 /// 67 /// Subblock containment captures the context->subcontext relationship. The 68 /// "next()" relationship in the raw profile, between call targets of indirect 69 /// calls, are just modeled as peer subblocks where the callee index is the 70 /// same. 71 /// 72 /// Versioning: the writer may produce additional records not known by the 73 /// reader. The version number indicates a more structural change. 74 /// The current version, in particular, is set up to expect optional extensions 75 /// like value profiling - which would appear as additional records. For 76 /// example, value profiling would produce a new record with a new record ID, 77 /// containing the profiled values (much like the counters) 78 class LLVM_ABI PGOCtxProfileWriter final : public ctx_profile::ProfileWriter { 79 enum class EmptyContextCriteria { None, EntryIsZero, AllAreZero }; 80 81 BitstreamWriter Writer; 82 const bool IncludeEmpty; 83 84 void writeGuid(ctx_profile::GUID Guid); 85 void writeCallsiteIndex(uint32_t Index); 86 void writeRootEntryCount(uint64_t EntryCount); 87 void writeCounters(ArrayRef<uint64_t> Counters); 88 void writeNode(uint32_t CallerIndex, const ctx_profile::ContextNode &Node); 89 void writeSubcontexts(const ctx_profile::ContextNode &Node); 90 91 public: 92 PGOCtxProfileWriter(raw_ostream &Out, 93 std::optional<unsigned> VersionOverride = std::nullopt, 94 bool IncludeEmpty = false); ~PGOCtxProfileWriter()95 ~PGOCtxProfileWriter() { Writer.ExitBlock(); } 96 97 void startContextSection() override; 98 void writeContextual(const ctx_profile::ContextNode &RootNode, 99 const ctx_profile::ContextNode *Unhandled, 100 uint64_t TotalRootEntryCount) override; 101 void endContextSection() override; 102 103 void startFlatSection() override; 104 void writeFlat(ctx_profile::GUID Guid, const uint64_t *Buffer, 105 size_t BufferSize) override; 106 void endFlatSection() override; 107 108 // constants used in writing which a reader may find useful. 109 static constexpr unsigned CodeLen = 2; 110 static constexpr uint32_t CurrentVersion = 4; 111 static constexpr unsigned VBREncodingBits = 6; 112 static constexpr StringRef ContainerMagic = "CTXP"; 113 }; 114 115 LLVM_ABI Error createCtxProfFromYAML(StringRef Profile, raw_ostream &Out); 116 } // namespace llvm 117 #endif 118