ModuleSummaryIndexYAML.h revision 360784
1//===-- llvm/ModuleSummaryIndexYAML.h - YAML I/O for summary ----*- 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#ifndef LLVM_IR_MODULESUMMARYINDEXYAML_H 10#define LLVM_IR_MODULESUMMARYINDEXYAML_H 11 12#include "llvm/IR/ModuleSummaryIndex.h" 13#include "llvm/Support/YAMLTraits.h" 14 15namespace llvm { 16namespace yaml { 17 18template <> struct ScalarEnumerationTraits<TypeTestResolution::Kind> { 19 static void enumeration(IO &io, TypeTestResolution::Kind &value) { 20 io.enumCase(value, "Unsat", TypeTestResolution::Unsat); 21 io.enumCase(value, "ByteArray", TypeTestResolution::ByteArray); 22 io.enumCase(value, "Inline", TypeTestResolution::Inline); 23 io.enumCase(value, "Single", TypeTestResolution::Single); 24 io.enumCase(value, "AllOnes", TypeTestResolution::AllOnes); 25 } 26}; 27 28template <> struct MappingTraits<TypeTestResolution> { 29 static void mapping(IO &io, TypeTestResolution &res) { 30 io.mapOptional("Kind", res.TheKind); 31 io.mapOptional("SizeM1BitWidth", res.SizeM1BitWidth); 32 io.mapOptional("AlignLog2", res.AlignLog2); 33 io.mapOptional("SizeM1", res.SizeM1); 34 io.mapOptional("BitMask", res.BitMask); 35 io.mapOptional("InlineBits", res.InlineBits); 36 } 37}; 38 39template <> 40struct ScalarEnumerationTraits<WholeProgramDevirtResolution::ByArg::Kind> { 41 static void enumeration(IO &io, 42 WholeProgramDevirtResolution::ByArg::Kind &value) { 43 io.enumCase(value, "Indir", WholeProgramDevirtResolution::ByArg::Indir); 44 io.enumCase(value, "UniformRetVal", 45 WholeProgramDevirtResolution::ByArg::UniformRetVal); 46 io.enumCase(value, "UniqueRetVal", 47 WholeProgramDevirtResolution::ByArg::UniqueRetVal); 48 io.enumCase(value, "VirtualConstProp", 49 WholeProgramDevirtResolution::ByArg::VirtualConstProp); 50 } 51}; 52 53template <> struct MappingTraits<WholeProgramDevirtResolution::ByArg> { 54 static void mapping(IO &io, WholeProgramDevirtResolution::ByArg &res) { 55 io.mapOptional("Kind", res.TheKind); 56 io.mapOptional("Info", res.Info); 57 io.mapOptional("Byte", res.Byte); 58 io.mapOptional("Bit", res.Bit); 59 } 60}; 61 62template <> 63struct CustomMappingTraits< 64 std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg>> { 65 static void inputOne( 66 IO &io, StringRef Key, 67 std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg> &V) { 68 std::vector<uint64_t> Args; 69 std::pair<StringRef, StringRef> P = {"", Key}; 70 while (!P.second.empty()) { 71 P = P.second.split(','); 72 uint64_t Arg; 73 if (P.first.getAsInteger(0, Arg)) { 74 io.setError("key not an integer"); 75 return; 76 } 77 Args.push_back(Arg); 78 } 79 io.mapRequired(Key.str().c_str(), V[Args]); 80 } 81 static void output( 82 IO &io, 83 std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg> &V) { 84 for (auto &P : V) { 85 std::string Key; 86 for (uint64_t Arg : P.first) { 87 if (!Key.empty()) 88 Key += ','; 89 Key += llvm::utostr(Arg); 90 } 91 io.mapRequired(Key.c_str(), P.second); 92 } 93 } 94}; 95 96template <> struct ScalarEnumerationTraits<WholeProgramDevirtResolution::Kind> { 97 static void enumeration(IO &io, WholeProgramDevirtResolution::Kind &value) { 98 io.enumCase(value, "Indir", WholeProgramDevirtResolution::Indir); 99 io.enumCase(value, "SingleImpl", WholeProgramDevirtResolution::SingleImpl); 100 io.enumCase(value, "BranchFunnel", 101 WholeProgramDevirtResolution::BranchFunnel); 102 } 103}; 104 105template <> struct MappingTraits<WholeProgramDevirtResolution> { 106 static void mapping(IO &io, WholeProgramDevirtResolution &res) { 107 io.mapOptional("Kind", res.TheKind); 108 io.mapOptional("SingleImplName", res.SingleImplName); 109 io.mapOptional("ResByArg", res.ResByArg); 110 } 111}; 112 113template <> 114struct CustomMappingTraits<std::map<uint64_t, WholeProgramDevirtResolution>> { 115 static void inputOne(IO &io, StringRef Key, 116 std::map<uint64_t, WholeProgramDevirtResolution> &V) { 117 uint64_t KeyInt; 118 if (Key.getAsInteger(0, KeyInt)) { 119 io.setError("key not an integer"); 120 return; 121 } 122 io.mapRequired(Key.str().c_str(), V[KeyInt]); 123 } 124 static void output(IO &io, std::map<uint64_t, WholeProgramDevirtResolution> &V) { 125 for (auto &P : V) 126 io.mapRequired(llvm::utostr(P.first).c_str(), P.second); 127 } 128}; 129 130template <> struct MappingTraits<TypeIdSummary> { 131 static void mapping(IO &io, TypeIdSummary& summary) { 132 io.mapOptional("TTRes", summary.TTRes); 133 io.mapOptional("WPDRes", summary.WPDRes); 134 } 135}; 136 137struct FunctionSummaryYaml { 138 unsigned Linkage; 139 bool NotEligibleToImport, Live, IsLocal, CanAutoHide; 140 std::vector<uint64_t> Refs; 141 std::vector<uint64_t> TypeTests; 142 std::vector<FunctionSummary::VFuncId> TypeTestAssumeVCalls, 143 TypeCheckedLoadVCalls; 144 std::vector<FunctionSummary::ConstVCall> TypeTestAssumeConstVCalls, 145 TypeCheckedLoadConstVCalls; 146}; 147 148} // End yaml namespace 149} // End llvm namespace 150 151namespace llvm { 152namespace yaml { 153 154template <> struct MappingTraits<FunctionSummary::VFuncId> { 155 static void mapping(IO &io, FunctionSummary::VFuncId& id) { 156 io.mapOptional("GUID", id.GUID); 157 io.mapOptional("Offset", id.Offset); 158 } 159}; 160 161template <> struct MappingTraits<FunctionSummary::ConstVCall> { 162 static void mapping(IO &io, FunctionSummary::ConstVCall& id) { 163 io.mapOptional("VFunc", id.VFunc); 164 io.mapOptional("Args", id.Args); 165 } 166}; 167 168} // End yaml namespace 169} // End llvm namespace 170 171LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::VFuncId) 172LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::ConstVCall) 173 174namespace llvm { 175namespace yaml { 176 177template <> struct MappingTraits<FunctionSummaryYaml> { 178 static void mapping(IO &io, FunctionSummaryYaml& summary) { 179 io.mapOptional("Linkage", summary.Linkage); 180 io.mapOptional("NotEligibleToImport", summary.NotEligibleToImport); 181 io.mapOptional("Live", summary.Live); 182 io.mapOptional("Local", summary.IsLocal); 183 io.mapOptional("CanAutoHide", summary.CanAutoHide); 184 io.mapOptional("Refs", summary.Refs); 185 io.mapOptional("TypeTests", summary.TypeTests); 186 io.mapOptional("TypeTestAssumeVCalls", summary.TypeTestAssumeVCalls); 187 io.mapOptional("TypeCheckedLoadVCalls", summary.TypeCheckedLoadVCalls); 188 io.mapOptional("TypeTestAssumeConstVCalls", 189 summary.TypeTestAssumeConstVCalls); 190 io.mapOptional("TypeCheckedLoadConstVCalls", 191 summary.TypeCheckedLoadConstVCalls); 192 } 193}; 194 195} // End yaml namespace 196} // End llvm namespace 197 198LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml) 199 200namespace llvm { 201namespace yaml { 202 203// FIXME: Add YAML mappings for the rest of the module summary. 204template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> { 205 static void inputOne(IO &io, StringRef Key, GlobalValueSummaryMapTy &V) { 206 std::vector<FunctionSummaryYaml> FSums; 207 io.mapRequired(Key.str().c_str(), FSums); 208 uint64_t KeyInt; 209 if (Key.getAsInteger(0, KeyInt)) { 210 io.setError("key not an integer"); 211 return; 212 } 213 if (!V.count(KeyInt)) 214 V.emplace(KeyInt, /*IsAnalysis=*/false); 215 auto &Elem = V.find(KeyInt)->second; 216 for (auto &FSum : FSums) { 217 std::vector<ValueInfo> Refs; 218 for (auto &RefGUID : FSum.Refs) { 219 if (!V.count(RefGUID)) 220 V.emplace(RefGUID, /*IsAnalysis=*/false); 221 Refs.push_back(ValueInfo(/*IsAnalysis=*/false, &*V.find(RefGUID))); 222 } 223 Elem.SummaryList.push_back(std::make_unique<FunctionSummary>( 224 GlobalValueSummary::GVFlags( 225 static_cast<GlobalValue::LinkageTypes>(FSum.Linkage), 226 FSum.NotEligibleToImport, FSum.Live, FSum.IsLocal, FSum.CanAutoHide), 227 /*NumInsts=*/0, FunctionSummary::FFlags{}, /*EntryCount=*/0, Refs, 228 ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests), 229 std::move(FSum.TypeTestAssumeVCalls), 230 std::move(FSum.TypeCheckedLoadVCalls), 231 std::move(FSum.TypeTestAssumeConstVCalls), 232 std::move(FSum.TypeCheckedLoadConstVCalls))); 233 } 234 } 235 static void output(IO &io, GlobalValueSummaryMapTy &V) { 236 for (auto &P : V) { 237 std::vector<FunctionSummaryYaml> FSums; 238 for (auto &Sum : P.second.SummaryList) { 239 if (auto *FSum = dyn_cast<FunctionSummary>(Sum.get())) { 240 std::vector<uint64_t> Refs; 241 for (auto &VI : FSum->refs()) 242 Refs.push_back(VI.getGUID()); 243 FSums.push_back(FunctionSummaryYaml{ 244 FSum->flags().Linkage, 245 static_cast<bool>(FSum->flags().NotEligibleToImport), 246 static_cast<bool>(FSum->flags().Live), 247 static_cast<bool>(FSum->flags().DSOLocal), 248 static_cast<bool>(FSum->flags().CanAutoHide), Refs, 249 FSum->type_tests(), FSum->type_test_assume_vcalls(), 250 FSum->type_checked_load_vcalls(), 251 FSum->type_test_assume_const_vcalls(), 252 FSum->type_checked_load_const_vcalls()}); 253 } 254 } 255 if (!FSums.empty()) 256 io.mapRequired(llvm::utostr(P.first).c_str(), FSums); 257 } 258 } 259}; 260 261template <> struct CustomMappingTraits<TypeIdSummaryMapTy> { 262 static void inputOne(IO &io, StringRef Key, TypeIdSummaryMapTy &V) { 263 TypeIdSummary TId; 264 io.mapRequired(Key.str().c_str(), TId); 265 V.insert({GlobalValue::getGUID(Key), {Key, TId}}); 266 } 267 static void output(IO &io, TypeIdSummaryMapTy &V) { 268 for (auto TidIter = V.begin(); TidIter != V.end(); TidIter++) 269 io.mapRequired(TidIter->second.first.c_str(), TidIter->second.second); 270 } 271}; 272 273template <> struct MappingTraits<ModuleSummaryIndex> { 274 static void mapping(IO &io, ModuleSummaryIndex& index) { 275 io.mapOptional("GlobalValueMap", index.GlobalValueMap); 276 io.mapOptional("TypeIdMap", index.TypeIdMap); 277 io.mapOptional("WithGlobalValueDeadStripping", 278 index.WithGlobalValueDeadStripping); 279 280 if (io.outputting()) { 281 std::vector<std::string> CfiFunctionDefs(index.CfiFunctionDefs.begin(), 282 index.CfiFunctionDefs.end()); 283 io.mapOptional("CfiFunctionDefs", CfiFunctionDefs); 284 std::vector<std::string> CfiFunctionDecls(index.CfiFunctionDecls.begin(), 285 index.CfiFunctionDecls.end()); 286 io.mapOptional("CfiFunctionDecls", CfiFunctionDecls); 287 } else { 288 std::vector<std::string> CfiFunctionDefs; 289 io.mapOptional("CfiFunctionDefs", CfiFunctionDefs); 290 index.CfiFunctionDefs = {CfiFunctionDefs.begin(), CfiFunctionDefs.end()}; 291 std::vector<std::string> CfiFunctionDecls; 292 io.mapOptional("CfiFunctionDecls", CfiFunctionDecls); 293 index.CfiFunctionDecls = {CfiFunctionDecls.begin(), 294 CfiFunctionDecls.end()}; 295 } 296 } 297}; 298 299} // End yaml namespace 300} // End llvm namespace 301 302#endif 303