Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:24

0001 #ifndef LLVM_PROFILEDATA_MEMPROFYAML_H_
0002 #define LLVM_PROFILEDATA_MEMPROFYAML_H_
0003 
0004 #include "llvm/ProfileData/MemProf.h"
0005 #include "llvm/Support/Format.h"
0006 #include "llvm/Support/YAMLTraits.h"
0007 
0008 namespace llvm {
0009 namespace memprof {
0010 // A "typedef" for GUID.  See ScalarTraits<memprof::GUIDHex64> for how a GUID is
0011 // serialized and deserialized in YAML.
0012 LLVM_YAML_STRONG_TYPEDEF(uint64_t, GUIDHex64)
0013 
0014 // Helper struct for AllMemProfData.  In YAML, we treat the GUID and the fields
0015 // within MemProfRecord at the same level as if the GUID were part of
0016 // MemProfRecord.
0017 struct GUIDMemProfRecordPair {
0018   GUIDHex64 GUID;
0019   MemProfRecord Record;
0020 };
0021 
0022 // The top-level data structure, only used with YAML for now.
0023 struct AllMemProfData {
0024   std::vector<GUIDMemProfRecordPair> HeapProfileRecords;
0025 };
0026 } // namespace memprof
0027 
0028 namespace yaml {
0029 template <> struct ScalarTraits<memprof::GUIDHex64> {
0030   static void output(const memprof::GUIDHex64 &Val, void *, raw_ostream &Out) {
0031     // Print GUID as a 16-digit hexadecimal number.
0032     Out << format("0x%016" PRIx64, (uint64_t)Val);
0033   }
0034   static StringRef input(StringRef Scalar, void *, memprof::GUIDHex64 &Val) {
0035     // Reject decimal GUIDs.
0036     if (all_of(Scalar, [](char C) { return std::isdigit(C); }))
0037       return "use a hexadecimal GUID or a function instead";
0038 
0039     uint64_t Num;
0040     if (Scalar.starts_with_insensitive("0x")) {
0041       // Accept hexadecimal numbers starting with 0x or 0X.
0042       if (Scalar.getAsInteger(0, Num))
0043         return "invalid hex64 number";
0044       Val = Num;
0045     } else {
0046       // Otherwise, treat the input as a string containing a function name.
0047       Val = memprof::IndexedMemProfRecord::getGUID(Scalar);
0048     }
0049     return StringRef();
0050   }
0051   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
0052 };
0053 
0054 template <> struct MappingTraits<memprof::Frame> {
0055   // Essentially the same as memprof::Frame except that Function is of type
0056   // memprof::GUIDHex64 instead of GlobalValue::GUID.  This class helps in two
0057   // ways.  During serialization, we print Function as a 16-digit hexadecimal
0058   // number.  During deserialization, we accept a function name as an
0059   // alternative to the usual GUID expressed as a hexadecimal number.
0060   class FrameWithHex64 {
0061   public:
0062     FrameWithHex64(IO &) {}
0063     FrameWithHex64(IO &, const memprof::Frame &F)
0064         : Function(F.Function), LineOffset(F.LineOffset), Column(F.Column),
0065           IsInlineFrame(F.IsInlineFrame) {}
0066     memprof::Frame denormalize(IO &) {
0067       return memprof::Frame(Function, LineOffset, Column, IsInlineFrame);
0068     }
0069 
0070     memprof::GUIDHex64 Function = 0;
0071     static_assert(std::is_same_v<decltype(Function.value),
0072                                  decltype(memprof::Frame::Function)>);
0073     decltype(memprof::Frame::LineOffset) LineOffset = 0;
0074     decltype(memprof::Frame::Column) Column = 0;
0075     decltype(memprof::Frame::IsInlineFrame) IsInlineFrame = false;
0076   };
0077 
0078   static void mapping(IO &Io, memprof::Frame &F) {
0079     MappingNormalization<FrameWithHex64, memprof::Frame> Keys(Io, F);
0080 
0081     Io.mapRequired("Function", Keys->Function);
0082     Io.mapRequired("LineOffset", Keys->LineOffset);
0083     Io.mapRequired("Column", Keys->Column);
0084     Io.mapRequired("IsInlineFrame", Keys->IsInlineFrame);
0085 
0086     // Assert that the definition of Frame matches what we expect.  The
0087     // structured bindings below detect changes to the number of fields.
0088     // static_assert checks the type of each field.
0089     const auto &[Function, SymbolName, LineOffset, Column, IsInlineFrame] = F;
0090     static_assert(
0091         std::is_same_v<remove_cvref_t<decltype(Function)>, GlobalValue::GUID>);
0092     static_assert(std::is_same_v<remove_cvref_t<decltype(SymbolName)>,
0093                                  std::unique_ptr<std::string>>);
0094     static_assert(
0095         std::is_same_v<remove_cvref_t<decltype(LineOffset)>, uint32_t>);
0096     static_assert(std::is_same_v<remove_cvref_t<decltype(Column)>, uint32_t>);
0097     static_assert(
0098         std::is_same_v<remove_cvref_t<decltype(IsInlineFrame)>, bool>);
0099 
0100     // MSVC issues unused variable warnings despite the uses in static_assert
0101     // above.
0102     (void)Function;
0103     (void)SymbolName;
0104     (void)LineOffset;
0105     (void)Column;
0106     (void)IsInlineFrame;
0107   }
0108 
0109   // Request the inline notation for brevity:
0110   //   { Function: 123, LineOffset: 11, Column: 10; IsInlineFrame: true }
0111   static const bool flow = true;
0112 };
0113 
0114 template <> struct CustomMappingTraits<memprof::PortableMemInfoBlock> {
0115   static void inputOne(IO &Io, StringRef KeyStr,
0116                        memprof::PortableMemInfoBlock &MIB) {
0117     // PortableMemInfoBlock keeps track of the set of fields that actually have
0118     // values.  We update the set here as we receive a key-value pair from the
0119     // YAML document.
0120     //
0121     // We set MIB.Name via a temporary variable because ScalarTraits<uintptr_t>
0122     // isn't available on macOS.
0123 #define MIBEntryDef(NameTag, Name, Type)                                       \
0124   if (KeyStr == #Name) {                                                       \
0125     uint64_t Value;                                                            \
0126     Io.mapRequired(KeyStr.str().c_str(), Value);                               \
0127     MIB.Name = static_cast<Type>(Value);                                       \
0128     MIB.Schema.set(llvm::to_underlying(memprof::Meta::Name));                  \
0129     return;                                                                    \
0130   }
0131 #include "llvm/ProfileData/MIBEntryDef.inc"
0132 #undef MIBEntryDef
0133     Io.setError("Key is not a valid validation event");
0134   }
0135 
0136   static void output(IO &Io, memprof::PortableMemInfoBlock &MIB) {
0137     auto Schema = MIB.getSchema();
0138 #define MIBEntryDef(NameTag, Name, Type)                                       \
0139   if (Schema.test(llvm::to_underlying(memprof::Meta::Name))) {                 \
0140     uint64_t Value = MIB.Name;                                                 \
0141     Io.mapRequired(#Name, Value);                                              \
0142   }
0143 #include "llvm/ProfileData/MIBEntryDef.inc"
0144 #undef MIBEntryDef
0145   }
0146 };
0147 
0148 template <> struct MappingTraits<memprof::AllocationInfo> {
0149   static void mapping(IO &Io, memprof::AllocationInfo &AI) {
0150     Io.mapRequired("Callstack", AI.CallStack);
0151     Io.mapRequired("MemInfoBlock", AI.Info);
0152   }
0153 };
0154 
0155 // In YAML, we use GUIDMemProfRecordPair instead of MemProfRecord so that we can
0156 // treat the GUID and the fields within MemProfRecord at the same level as if
0157 // the GUID were part of MemProfRecord.
0158 template <> struct MappingTraits<memprof::GUIDMemProfRecordPair> {
0159   static void mapping(IO &Io, memprof::GUIDMemProfRecordPair &Pair) {
0160     Io.mapRequired("GUID", Pair.GUID);
0161     Io.mapRequired("AllocSites", Pair.Record.AllocSites);
0162     Io.mapRequired("CallSites", Pair.Record.CallSites);
0163   }
0164 };
0165 
0166 template <> struct MappingTraits<memprof::AllMemProfData> {
0167   static void mapping(IO &Io, memprof::AllMemProfData &Data) {
0168     Io.mapRequired("HeapProfileRecords", Data.HeapProfileRecords);
0169   }
0170 };
0171 } // namespace yaml
0172 } // namespace llvm
0173 
0174 LLVM_YAML_IS_SEQUENCE_VECTOR(memprof::Frame)
0175 LLVM_YAML_IS_SEQUENCE_VECTOR(std::vector<memprof::Frame>)
0176 LLVM_YAML_IS_SEQUENCE_VECTOR(memprof::AllocationInfo)
0177 LLVM_YAML_IS_SEQUENCE_VECTOR(memprof::GUIDMemProfRecordPair)
0178 
0179 #endif // LLVM_PROFILEDATA_MEMPROFYAML_H_