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 16 namespace llvm { 17 namespace yaml { 18 19 template <> 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 29 template <> 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 36 template <> 37 struct 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 50 template <> 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 57 template <> 58 struct 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 91 template <> 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 98 template <> 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 106 template <> 107 struct 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 123 template <> 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 130 struct 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 143 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint64_t) 144 145 namespace llvm { 146 namespace yaml { 147 148 template <> 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 155 template <> 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 165 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::VFuncId) 166 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::ConstVCall) 167 168 namespace llvm { 169 namespace yaml { 170 171 template <> 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 189 LLVM_YAML_IS_STRING_MAP(TypeIdSummary) 190 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml) 191 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string) 192 193 namespace llvm { 194 namespace yaml { 195 196 // FIXME: Add YAML mappings for the rest of the module summary. 197 template <> 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 238 template <> 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