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