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