1 //===- bolt/Profile/ProfileYAMLMapping.h ------------------------*- 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 // Implement mapping between binary function profile and YAML representation. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef BOLT_PROFILE_PROFILEYAMLMAPPING_H 14 #define BOLT_PROFILE_PROFILEYAMLMAPPING_H 15 16 #include "bolt/Core/BinaryFunction.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/Support/YAMLTraits.h" 19 #include <vector> 20 21 using llvm::bolt::BinaryFunction; 22 23 namespace llvm { 24 namespace yaml { 25 26 namespace bolt { 27 struct CallSiteInfo { 28 llvm::yaml::Hex32 Offset{0}; 29 uint32_t DestId{0}; 30 uint32_t EntryDiscriminator{0}; /// multiple entry discriminator 31 uint64_t Count{0}; 32 uint64_t Mispreds{0}; 33 34 bool operator==(const CallSiteInfo &Other) const { 35 return Offset == Other.Offset && DestId == Other.DestId && 36 EntryDiscriminator == Other.EntryDiscriminator; 37 } 38 39 bool operator!=(const CallSiteInfo &Other) const { return !(*this == Other); } 40 41 bool operator<(const CallSiteInfo &Other) const { 42 if (Offset < Other.Offset) 43 return true; 44 if (Offset > Other.Offset) 45 return false; 46 47 if (DestId < Other.DestId) 48 return true; 49 if (DestId > Other.DestId) 50 return false; 51 52 if (EntryDiscriminator < Other.EntryDiscriminator) 53 return true; 54 55 return false; 56 } 57 }; 58 } // end namespace bolt 59 60 template <> struct MappingTraits<bolt::CallSiteInfo> { 61 static void mapping(IO &YamlIO, bolt::CallSiteInfo &CSI) { 62 YamlIO.mapRequired("off", CSI.Offset); 63 YamlIO.mapRequired("fid", CSI.DestId); 64 YamlIO.mapOptional("disc", CSI.EntryDiscriminator, (uint32_t)0); 65 YamlIO.mapRequired("cnt", CSI.Count); 66 YamlIO.mapOptional("mis", CSI.Mispreds, (uint64_t)0); 67 } 68 69 static const bool flow = true; 70 }; 71 72 namespace bolt { 73 struct SuccessorInfo { 74 uint32_t Index{0}; 75 uint64_t Count{0}; 76 uint64_t Mispreds{0}; 77 78 bool operator==(const SuccessorInfo &Other) const { 79 return Index == Other.Index; 80 } 81 bool operator!=(const SuccessorInfo &Other) const { 82 return !(*this == Other); 83 } 84 }; 85 } // end namespace bolt 86 87 template <> struct MappingTraits<bolt::SuccessorInfo> { 88 static void mapping(IO &YamlIO, bolt::SuccessorInfo &SI) { 89 YamlIO.mapRequired("bid", SI.Index); 90 YamlIO.mapRequired("cnt", SI.Count); 91 YamlIO.mapOptional("mis", SI.Mispreds, (uint64_t)0); 92 } 93 94 static const bool flow = true; 95 }; 96 97 } // end namespace yaml 98 } // end namespace llvm 99 100 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::bolt::CallSiteInfo) 101 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::bolt::SuccessorInfo) 102 103 namespace llvm { 104 namespace yaml { 105 106 namespace bolt { 107 struct BinaryBasicBlockProfile { 108 uint32_t Index{0}; 109 uint32_t NumInstructions{0}; 110 llvm::yaml::Hex64 Hash{0}; 111 uint64_t ExecCount{0}; 112 uint64_t EventCount{0}; 113 std::vector<CallSiteInfo> CallSites; 114 std::vector<SuccessorInfo> Successors; 115 116 bool operator==(const BinaryBasicBlockProfile &Other) const { 117 return Index == Other.Index; 118 } 119 bool operator!=(const BinaryBasicBlockProfile &Other) const { 120 return !(*this == Other); 121 } 122 }; 123 } // end namespace bolt 124 125 template <> struct MappingTraits<bolt::BinaryBasicBlockProfile> { 126 static void mapping(IO &YamlIO, bolt::BinaryBasicBlockProfile &BBP) { 127 YamlIO.mapRequired("bid", BBP.Index); 128 YamlIO.mapRequired("insns", BBP.NumInstructions); 129 YamlIO.mapOptional("exec", BBP.ExecCount, (uint64_t)0); 130 YamlIO.mapOptional("events", BBP.EventCount, (uint64_t)0); 131 YamlIO.mapOptional("calls", BBP.CallSites, 132 std::vector<bolt::CallSiteInfo>()); 133 YamlIO.mapOptional("succ", BBP.Successors, 134 std::vector<bolt::SuccessorInfo>()); 135 } 136 }; 137 138 } // end namespace yaml 139 } // end namespace llvm 140 141 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::bolt::BinaryBasicBlockProfile) 142 143 namespace llvm { 144 namespace yaml { 145 146 namespace bolt { 147 struct BinaryFunctionProfile { 148 std::string Name; 149 uint32_t NumBasicBlocks{0}; 150 uint32_t Id{0}; 151 llvm::yaml::Hex64 Hash{0}; 152 uint64_t ExecCount{0}; 153 std::vector<BinaryBasicBlockProfile> Blocks; 154 bool Used{false}; 155 }; 156 } // end namespace bolt 157 158 template <> struct MappingTraits<bolt::BinaryFunctionProfile> { 159 static void mapping(IO &YamlIO, bolt::BinaryFunctionProfile &BFP) { 160 YamlIO.mapRequired("name", BFP.Name); 161 YamlIO.mapRequired("fid", BFP.Id); 162 YamlIO.mapRequired("hash", BFP.Hash); 163 YamlIO.mapRequired("exec", BFP.ExecCount); 164 YamlIO.mapRequired("nblocks", BFP.NumBasicBlocks); 165 YamlIO.mapOptional("blocks", BFP.Blocks, 166 std::vector<bolt::BinaryBasicBlockProfile>()); 167 } 168 }; 169 170 LLVM_YAML_STRONG_TYPEDEF(uint16_t, PROFILE_PF) 171 172 template <> struct ScalarBitSetTraits<PROFILE_PF> { 173 static void bitset(IO &io, PROFILE_PF &value) { 174 io.bitSetCase(value, "lbr", BinaryFunction::PF_LBR); 175 io.bitSetCase(value, "sample", BinaryFunction::PF_SAMPLE); 176 io.bitSetCase(value, "memevent", BinaryFunction::PF_MEMEVENT); 177 } 178 }; 179 180 namespace bolt { 181 struct BinaryProfileHeader { 182 uint32_t Version{1}; 183 std::string FileName; // Name of the profiled binary. 184 std::string Id; // BuildID. 185 PROFILE_PF Flags{BinaryFunction::PF_NONE}; 186 // Type of the profile. 187 std::string Origin; // How the profile was obtained. 188 std::string EventNames; // Events used for sample profile. 189 }; 190 } // end namespace bolt 191 192 template <> struct MappingTraits<bolt::BinaryProfileHeader> { 193 static void mapping(IO &YamlIO, bolt::BinaryProfileHeader &Header) { 194 YamlIO.mapRequired("profile-version", Header.Version); 195 YamlIO.mapRequired("binary-name", Header.FileName); 196 YamlIO.mapOptional("binary-build-id", Header.Id); 197 YamlIO.mapRequired("profile-flags", Header.Flags); 198 YamlIO.mapOptional("profile-origin", Header.Origin); 199 YamlIO.mapOptional("profile-events", Header.EventNames); 200 } 201 }; 202 203 } // end namespace yaml 204 } // end namespace llvm 205 206 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::bolt::BinaryFunctionProfile) 207 208 namespace llvm { 209 namespace yaml { 210 211 namespace bolt { 212 struct BinaryProfile { 213 BinaryProfileHeader Header; 214 std::vector<BinaryFunctionProfile> Functions; 215 }; 216 } // namespace bolt 217 218 template <> struct MappingTraits<bolt::BinaryProfile> { 219 static void mapping(IO &YamlIO, bolt::BinaryProfile &BP) { 220 YamlIO.mapRequired("header", BP.Header); 221 YamlIO.mapRequired("functions", BP.Functions); 222 } 223 }; 224 225 } // end namespace yaml 226 } // end namespace llvm 227 228 #endif 229