|
11 | 11 | #include "llvm/Support/BLAKE3.h" |
12 | 12 | #include "llvm/Support/Endian.h" |
13 | 13 | #include "llvm/Support/EndianStream.h" |
14 | | -#include "llvm/Support/Format.h" |
15 | 14 | #include "llvm/Support/HashBuilder.h" |
16 | | -#include "llvm/Support/YAMLTraits.h" |
17 | 15 | #include "llvm/Support/raw_ostream.h" |
18 | 16 |
|
19 | 17 | #include <bitset> |
@@ -492,23 +490,6 @@ struct MemProfRecord { |
492 | 490 | } |
493 | 491 | }; |
494 | 492 |
|
495 | | -// A "typedef" for GUID. See ScalarTraits<memprof::GUIDHex64> for how a GUID is |
496 | | -// serialized and deserialized in YAML. |
497 | | -LLVM_YAML_STRONG_TYPEDEF(uint64_t, GUIDHex64) |
498 | | - |
499 | | -// Helper struct for AllMemProfData. In YAML, we treat the GUID and the fields |
500 | | -// within MemProfRecord at the same level as if the GUID were part of |
501 | | -// MemProfRecord. |
502 | | -struct GUIDMemProfRecordPair { |
503 | | - GUIDHex64 GUID; |
504 | | - MemProfRecord Record; |
505 | | -}; |
506 | | - |
507 | | -// The top-level data structure, only used with YAML for now. |
508 | | -struct AllMemProfData { |
509 | | - std::vector<GUIDMemProfRecordPair> HeapProfileRecords; |
510 | | -}; |
511 | | - |
512 | 493 | // Reads a memprof schema from a buffer. All entries in the buffer are |
513 | 494 | // interpreted as uint64_t. The first entry in the buffer denotes the number of |
514 | 495 | // ids in the schema. Subsequent entries are integers which map to memprof::Meta |
@@ -1169,131 +1150,6 @@ template <typename FrameIdTy> class CallStackRadixTreeBuilder { |
1169 | 1150 | } |
1170 | 1151 | }; |
1171 | 1152 | } // namespace memprof |
1172 | | - |
1173 | | -namespace yaml { |
1174 | | -template <> struct ScalarTraits<memprof::GUIDHex64> { |
1175 | | - static void output(const memprof::GUIDHex64 &Val, void *, raw_ostream &Out) { |
1176 | | - // Print GUID as a 16-digit hexadecimal number. |
1177 | | - Out << format("0x%016" PRIx64, (uint64_t)Val); |
1178 | | - } |
1179 | | - static StringRef input(StringRef Scalar, void *, memprof::GUIDHex64 &Val) { |
1180 | | - // Reject decimal GUIDs. |
1181 | | - if (all_of(Scalar, [](char C) { return std::isdigit(C); })) |
1182 | | - return "use a hexadecimal GUID or a function instead"; |
1183 | | - |
1184 | | - uint64_t Num; |
1185 | | - if (Scalar.starts_with_insensitive("0x")) { |
1186 | | - // Accept hexadecimal numbers starting with 0x or 0X. |
1187 | | - if (Scalar.getAsInteger(0, Num)) |
1188 | | - return "invalid hex64 number"; |
1189 | | - Val = Num; |
1190 | | - } else { |
1191 | | - // Otherwise, treat the input as a string containing a function name. |
1192 | | - Val = memprof::IndexedMemProfRecord::getGUID(Scalar); |
1193 | | - } |
1194 | | - return StringRef(); |
1195 | | - } |
1196 | | - static QuotingType mustQuote(StringRef) { return QuotingType::None; } |
1197 | | -}; |
1198 | | - |
1199 | | -template <> struct MappingTraits<memprof::Frame> { |
1200 | | - static void mapping(IO &Io, memprof::Frame &F) { |
1201 | | - Io.mapRequired("Function", F.Function); |
1202 | | - Io.mapRequired("LineOffset", F.LineOffset); |
1203 | | - Io.mapRequired("Column", F.Column); |
1204 | | - Io.mapRequired("IsInlineFrame", F.IsInlineFrame); |
1205 | | - |
1206 | | - // Assert that the definition of Frame matches what we expect. The |
1207 | | - // structured bindings below detect changes to the number of fields. |
1208 | | - // static_assert checks the type of each field. |
1209 | | - const auto &[Function, SymbolName, LineOffset, Column, IsInlineFrame] = F; |
1210 | | - static_assert( |
1211 | | - std::is_same_v<remove_cvref_t<decltype(Function)>, GlobalValue::GUID>); |
1212 | | - static_assert(std::is_same_v<remove_cvref_t<decltype(SymbolName)>, |
1213 | | - std::unique_ptr<std::string>>); |
1214 | | - static_assert( |
1215 | | - std::is_same_v<remove_cvref_t<decltype(LineOffset)>, uint32_t>); |
1216 | | - static_assert(std::is_same_v<remove_cvref_t<decltype(Column)>, uint32_t>); |
1217 | | - static_assert( |
1218 | | - std::is_same_v<remove_cvref_t<decltype(IsInlineFrame)>, bool>); |
1219 | | - |
1220 | | - // MSVC issues unused variable warnings despite the uses in static_assert |
1221 | | - // above. |
1222 | | - (void)Function; |
1223 | | - (void)SymbolName; |
1224 | | - (void)LineOffset; |
1225 | | - (void)Column; |
1226 | | - (void)IsInlineFrame; |
1227 | | - } |
1228 | | - |
1229 | | - // Request the inline notation for brevity: |
1230 | | - // { Function: 123, LineOffset: 11, Column: 10; IsInlineFrame: true } |
1231 | | - static const bool flow = true; |
1232 | | -}; |
1233 | | - |
1234 | | -template <> struct CustomMappingTraits<memprof::PortableMemInfoBlock> { |
1235 | | - static void inputOne(IO &Io, StringRef KeyStr, |
1236 | | - memprof::PortableMemInfoBlock &MIB) { |
1237 | | - // PortableMemInfoBlock keeps track of the set of fields that actually have |
1238 | | - // values. We update the set here as we receive a key-value pair from the |
1239 | | - // YAML document. |
1240 | | - // |
1241 | | - // We set MIB.Name via a temporary variable because ScalarTraits<uintptr_t> |
1242 | | - // isn't available on macOS. |
1243 | | -#define MIBEntryDef(NameTag, Name, Type) \ |
1244 | | - if (KeyStr == #Name) { \ |
1245 | | - uint64_t Value; \ |
1246 | | - Io.mapRequired(KeyStr.str().c_str(), Value); \ |
1247 | | - MIB.Name = static_cast<Type>(Value); \ |
1248 | | - MIB.Schema.set(llvm::to_underlying(memprof::Meta::Name)); \ |
1249 | | - return; \ |
1250 | | - } |
1251 | | -#include "llvm/ProfileData/MIBEntryDef.inc" |
1252 | | -#undef MIBEntryDef |
1253 | | - Io.setError("Key is not a valid validation event"); |
1254 | | - } |
1255 | | - |
1256 | | - static void output(IO &Io, memprof::PortableMemInfoBlock &MIB) { |
1257 | | - auto Schema = MIB.getSchema(); |
1258 | | -#define MIBEntryDef(NameTag, Name, Type) \ |
1259 | | - if (Schema.test(llvm::to_underlying(memprof::Meta::Name))) { \ |
1260 | | - uint64_t Value = MIB.Name; \ |
1261 | | - Io.mapRequired(#Name, Value); \ |
1262 | | - } |
1263 | | -#include "llvm/ProfileData/MIBEntryDef.inc" |
1264 | | -#undef MIBEntryDef |
1265 | | - } |
1266 | | -}; |
1267 | | - |
1268 | | -template <> struct MappingTraits<memprof::AllocationInfo> { |
1269 | | - static void mapping(IO &Io, memprof::AllocationInfo &AI) { |
1270 | | - Io.mapRequired("Callstack", AI.CallStack); |
1271 | | - Io.mapRequired("MemInfoBlock", AI.Info); |
1272 | | - } |
1273 | | -}; |
1274 | | - |
1275 | | -// In YAML, we use GUIDMemProfRecordPair instead of MemProfRecord so that we can |
1276 | | -// treat the GUID and the fields within MemProfRecord at the same level as if |
1277 | | -// the GUID were part of MemProfRecord. |
1278 | | -template <> struct MappingTraits<memprof::GUIDMemProfRecordPair> { |
1279 | | - static void mapping(IO &Io, memprof::GUIDMemProfRecordPair &Pair) { |
1280 | | - Io.mapRequired("GUID", Pair.GUID); |
1281 | | - Io.mapRequired("AllocSites", Pair.Record.AllocSites); |
1282 | | - Io.mapRequired("CallSites", Pair.Record.CallSites); |
1283 | | - } |
1284 | | -}; |
1285 | | - |
1286 | | -template <> struct MappingTraits<memprof::AllMemProfData> { |
1287 | | - static void mapping(IO &Io, memprof::AllMemProfData &Data) { |
1288 | | - Io.mapRequired("HeapProfileRecords", Data.HeapProfileRecords); |
1289 | | - } |
1290 | | -}; |
1291 | | -} // namespace yaml |
1292 | 1153 | } // namespace llvm |
1293 | 1154 |
|
1294 | | -LLVM_YAML_IS_SEQUENCE_VECTOR(memprof::Frame) |
1295 | | -LLVM_YAML_IS_SEQUENCE_VECTOR(std::vector<memprof::Frame>) |
1296 | | -LLVM_YAML_IS_SEQUENCE_VECTOR(memprof::AllocationInfo) |
1297 | | -LLVM_YAML_IS_SEQUENCE_VECTOR(memprof::GUIDMemProfRecordPair) |
1298 | | - |
1299 | 1155 | #endif // LLVM_PROFILEDATA_MEMPROF_H_ |
0 commit comments