| //===- bolt/Profile/ProfileYAMLMapping.h ------------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Implement mapping between binary function profile and YAML representation. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef BOLT_PROFILE_PROFILEYAMLMAPPING_H |
| #define BOLT_PROFILE_PROFILEYAMLMAPPING_H |
| |
| #include "bolt/Core/BinaryFunction.h" |
| #include "llvm/ADT/StringRef.h" |
| #include "llvm/Support/YAMLTraits.h" |
| #include <vector> |
| |
| using llvm::bolt::BinaryFunction; |
| |
| namespace llvm { |
| namespace yaml { |
| |
| namespace bolt { |
| struct CallSiteInfo { |
| llvm::yaml::Hex32 Offset{0}; |
| uint32_t DestId{0}; |
| uint32_t EntryDiscriminator{0}; /// multiple entry discriminator |
| uint64_t Count{0}; |
| uint64_t Mispreds{0}; |
| |
| bool operator==(const CallSiteInfo &Other) const { |
| return Offset == Other.Offset && DestId == Other.DestId && |
| EntryDiscriminator == Other.EntryDiscriminator; |
| } |
| |
| bool operator!=(const CallSiteInfo &Other) const { return !(*this == Other); } |
| |
| bool operator<(const CallSiteInfo &Other) const { |
| if (Offset < Other.Offset) |
| return true; |
| if (Offset > Other.Offset) |
| return false; |
| |
| if (DestId < Other.DestId) |
| return true; |
| if (DestId > Other.DestId) |
| return false; |
| |
| if (EntryDiscriminator < Other.EntryDiscriminator) |
| return true; |
| |
| return false; |
| } |
| }; |
| } // end namespace bolt |
| |
| template <> struct MappingTraits<bolt::CallSiteInfo> { |
| static void mapping(IO &YamlIO, bolt::CallSiteInfo &CSI) { |
| YamlIO.mapRequired("off", CSI.Offset); |
| YamlIO.mapRequired("fid", CSI.DestId); |
| YamlIO.mapOptional("disc", CSI.EntryDiscriminator, (uint32_t)0); |
| YamlIO.mapRequired("cnt", CSI.Count); |
| YamlIO.mapOptional("mis", CSI.Mispreds, (uint64_t)0); |
| } |
| |
| static const bool flow = true; |
| }; |
| |
| namespace bolt { |
| struct SuccessorInfo { |
| uint32_t Index{0}; |
| uint64_t Count{0}; |
| uint64_t Mispreds{0}; |
| |
| bool operator==(const SuccessorInfo &Other) const { |
| return Index == Other.Index; |
| } |
| bool operator!=(const SuccessorInfo &Other) const { |
| return !(*this == Other); |
| } |
| }; |
| } // end namespace bolt |
| |
| template <> struct MappingTraits<bolt::SuccessorInfo> { |
| static void mapping(IO &YamlIO, bolt::SuccessorInfo &SI) { |
| YamlIO.mapRequired("bid", SI.Index); |
| YamlIO.mapRequired("cnt", SI.Count); |
| YamlIO.mapOptional("mis", SI.Mispreds, (uint64_t)0); |
| } |
| |
| static const bool flow = true; |
| }; |
| |
| } // end namespace yaml |
| } // end namespace llvm |
| |
| LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::bolt::CallSiteInfo) |
| LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::bolt::SuccessorInfo) |
| |
| namespace llvm { |
| namespace yaml { |
| |
| namespace bolt { |
| struct BinaryBasicBlockProfile { |
| uint32_t Index{0}; |
| uint32_t NumInstructions{0}; |
| llvm::yaml::Hex64 Hash{0}; |
| uint64_t ExecCount{0}; |
| uint64_t EventCount{0}; |
| std::vector<CallSiteInfo> CallSites; |
| std::vector<SuccessorInfo> Successors; |
| |
| bool operator==(const BinaryBasicBlockProfile &Other) const { |
| return Index == Other.Index; |
| } |
| bool operator!=(const BinaryBasicBlockProfile &Other) const { |
| return !(*this == Other); |
| } |
| }; |
| } // end namespace bolt |
| |
| template <> struct MappingTraits<bolt::BinaryBasicBlockProfile> { |
| static void mapping(IO &YamlIO, bolt::BinaryBasicBlockProfile &BBP) { |
| YamlIO.mapRequired("bid", BBP.Index); |
| YamlIO.mapRequired("insns", BBP.NumInstructions); |
| YamlIO.mapOptional("exec", BBP.ExecCount, (uint64_t)0); |
| YamlIO.mapOptional("events", BBP.EventCount, (uint64_t)0); |
| YamlIO.mapOptional("calls", BBP.CallSites, |
| std::vector<bolt::CallSiteInfo>()); |
| YamlIO.mapOptional("succ", BBP.Successors, |
| std::vector<bolt::SuccessorInfo>()); |
| } |
| }; |
| |
| } // end namespace yaml |
| } // end namespace llvm |
| |
| LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::bolt::BinaryBasicBlockProfile) |
| |
| namespace llvm { |
| namespace yaml { |
| |
| namespace bolt { |
| struct BinaryFunctionProfile { |
| std::string Name; |
| uint32_t NumBasicBlocks{0}; |
| uint32_t Id{0}; |
| llvm::yaml::Hex64 Hash{0}; |
| uint64_t ExecCount{0}; |
| std::vector<BinaryBasicBlockProfile> Blocks; |
| bool Used{false}; |
| }; |
| } // end namespace bolt |
| |
| template <> struct MappingTraits<bolt::BinaryFunctionProfile> { |
| static void mapping(IO &YamlIO, bolt::BinaryFunctionProfile &BFP) { |
| YamlIO.mapRequired("name", BFP.Name); |
| YamlIO.mapRequired("fid", BFP.Id); |
| YamlIO.mapRequired("hash", BFP.Hash); |
| YamlIO.mapRequired("exec", BFP.ExecCount); |
| YamlIO.mapRequired("nblocks", BFP.NumBasicBlocks); |
| YamlIO.mapOptional("blocks", BFP.Blocks, |
| std::vector<bolt::BinaryBasicBlockProfile>()); |
| } |
| }; |
| |
| LLVM_YAML_STRONG_TYPEDEF(uint16_t, PROFILE_PF) |
| |
| template <> struct ScalarBitSetTraits<PROFILE_PF> { |
| static void bitset(IO &io, PROFILE_PF &value) { |
| io.bitSetCase(value, "lbr", BinaryFunction::PF_LBR); |
| io.bitSetCase(value, "sample", BinaryFunction::PF_SAMPLE); |
| io.bitSetCase(value, "memevent", BinaryFunction::PF_MEMEVENT); |
| } |
| }; |
| |
| namespace bolt { |
| struct BinaryProfileHeader { |
| uint32_t Version{1}; |
| std::string FileName; // Name of the profiled binary. |
| std::string Id; // BuildID. |
| PROFILE_PF Flags{BinaryFunction::PF_NONE}; |
| // Type of the profile. |
| std::string Origin; // How the profile was obtained. |
| std::string EventNames; // Events used for sample profile. |
| }; |
| } // end namespace bolt |
| |
| template <> struct MappingTraits<bolt::BinaryProfileHeader> { |
| static void mapping(IO &YamlIO, bolt::BinaryProfileHeader &Header) { |
| YamlIO.mapRequired("profile-version", Header.Version); |
| YamlIO.mapRequired("binary-name", Header.FileName); |
| YamlIO.mapOptional("binary-build-id", Header.Id); |
| YamlIO.mapRequired("profile-flags", Header.Flags); |
| YamlIO.mapOptional("profile-origin", Header.Origin); |
| YamlIO.mapOptional("profile-events", Header.EventNames); |
| } |
| }; |
| |
| } // end namespace yaml |
| } // end namespace llvm |
| |
| LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::bolt::BinaryFunctionProfile) |
| |
| namespace llvm { |
| namespace yaml { |
| |
| namespace bolt { |
| struct BinaryProfile { |
| BinaryProfileHeader Header; |
| std::vector<BinaryFunctionProfile> Functions; |
| }; |
| } // namespace bolt |
| |
| template <> struct MappingTraits<bolt::BinaryProfile> { |
| static void mapping(IO &YamlIO, bolt::BinaryProfile &BP) { |
| YamlIO.mapRequired("header", BP.Header); |
| YamlIO.mapRequired("functions", BP.Functions); |
| } |
| }; |
| |
| } // end namespace yaml |
| } // end namespace llvm |
| |
| #endif |