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 21 namespace llvm { 22 enum PGOCtxProfileRecords { Invalid = 0, Version, Guid, CalleeIndex, Counters }; 23 24 enum PGOCtxProfileBlockIDs { 25 ProfileMetadataBlockID = bitc::FIRST_APPLICATION_BLOCKID, 26 ContextNodeBlockID = ProfileMetadataBlockID + 1 27 }; 28 29 /// Write one or more ContextNodes to the provided raw_fd_stream. 30 /// The caller must destroy the PGOCtxProfileWriter object before closing the 31 /// stream. 32 /// The design allows serializing a bunch of contexts embedded in some other 33 /// file. The overall format is: 34 /// 35 /// [... other data written to the stream...] 36 /// SubBlock(ProfileMetadataBlockID) 37 /// Version 38 /// SubBlock(ContextNodeBlockID) 39 /// [RECORDS] 40 /// SubBlock(ContextNodeBlockID) 41 /// [RECORDS] 42 /// [... more SubBlocks] 43 /// EndBlock 44 /// EndBlock 45 /// 46 /// The "RECORDS" are bitsream records. The IDs are in CtxProfileCodes (except) 47 /// for Version, which is just for metadata). All contexts will have Guid and 48 /// Counters, and all but the roots have CalleeIndex. The order in which the 49 /// records appear does not matter, but they must precede any subcontexts, 50 /// because that helps keep the reader code simpler. 51 /// 52 /// Subblock containment captures the context->subcontext relationship. The 53 /// "next()" relationship in the raw profile, between call targets of indirect 54 /// calls, are just modeled as peer subblocks where the callee index is the 55 /// same. 56 /// 57 /// Versioning: the writer may produce additional records not known by the 58 /// reader. The version number indicates a more structural change. 59 /// The current version, in particular, is set up to expect optional extensions 60 /// like value profiling - which would appear as additional records. For 61 /// example, value profiling would produce a new record with a new record ID, 62 /// containing the profiled values (much like the counters) 63 class PGOCtxProfileWriter final { 64 BitstreamWriter Writer; 65 66 void writeCounters(const ctx_profile::ContextNode &Node); 67 void writeImpl(std::optional<uint32_t> CallerIndex, 68 const ctx_profile::ContextNode &Node); 69 70 public: 71 PGOCtxProfileWriter(raw_ostream &Out, 72 std::optional<unsigned> VersionOverride = std::nullopt); 73 ~PGOCtxProfileWriter() { Writer.ExitBlock(); } 74 75 void write(const ctx_profile::ContextNode &); 76 77 // constants used in writing which a reader may find useful. 78 static constexpr unsigned CodeLen = 2; 79 static constexpr uint32_t CurrentVersion = 1; 80 static constexpr unsigned VBREncodingBits = 6; 81 static constexpr StringRef ContainerMagic = "CTXP"; 82 }; 83 84 Error createCtxProfFromYAML(StringRef Profile, raw_ostream &Out); 85 } // namespace llvm 86 #endif 87