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 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 40 template <> 41 struct 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 54 template <> 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 63 template <> 64 struct 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 97 template <> 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 104 template <> 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 112 template <> 113 struct 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 129 template <> 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 136 struct FunctionSummaryYaml { 137 unsigned Linkage; 138 bool NotEligibleToImport, Live, IsLocal; 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 149 namespace llvm { 150 namespace yaml { 151 152 template <> 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 159 template <> 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 169 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::VFuncId) 170 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::ConstVCall) 171 172 namespace llvm { 173 namespace yaml { 174 175 template <> 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("Local", summary.IsLocal); 181 io.mapOptional("TypeTests", summary.TypeTests); 182 io.mapOptional("TypeTestAssumeVCalls", summary.TypeTestAssumeVCalls); 183 io.mapOptional("TypeCheckedLoadVCalls", summary.TypeCheckedLoadVCalls); 184 io.mapOptional("TypeTestAssumeConstVCalls", 185 summary.TypeTestAssumeConstVCalls); 186 io.mapOptional("TypeCheckedLoadConstVCalls", 187 summary.TypeCheckedLoadConstVCalls); 188 } 189 }; 190 191 } // End yaml namespace 192 } // End llvm namespace 193 194 LLVM_YAML_IS_STRING_MAP(TypeIdSummary) 195 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml) 196 197 namespace llvm { 198 namespace yaml { 199 200 // FIXME: Add YAML mappings for the rest of the module summary. 201 template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> { 202 static void inputOne(IO &io, StringRef Key, GlobalValueSummaryMapTy &V) { 203 std::vector<FunctionSummaryYaml> FSums; 204 io.mapRequired(Key.str().c_str(), FSums); 205 uint64_t KeyInt; 206 if (Key.getAsInteger(0, KeyInt)) { 207 io.setError("key not an integer"); 208 return; 209 } 210 auto &Elem = V[KeyInt]; 211 for (auto &FSum : FSums) { 212 Elem.SummaryList.push_back(llvm::make_unique<FunctionSummary>( 213 GlobalValueSummary::GVFlags( 214 static_cast<GlobalValue::LinkageTypes>(FSum.Linkage), 215 FSum.NotEligibleToImport, FSum.Live, FSum.IsLocal), 216 0, FunctionSummary::FFlags{}, ArrayRef<ValueInfo>{}, 217 ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests), 218 std::move(FSum.TypeTestAssumeVCalls), 219 std::move(FSum.TypeCheckedLoadVCalls), 220 std::move(FSum.TypeTestAssumeConstVCalls), 221 std::move(FSum.TypeCheckedLoadConstVCalls))); 222 } 223 } 224 static void output(IO &io, GlobalValueSummaryMapTy &V) { 225 for (auto &P : V) { 226 std::vector<FunctionSummaryYaml> FSums; 227 for (auto &Sum : P.second.SummaryList) { 228 if (auto *FSum = dyn_cast<FunctionSummary>(Sum.get())) 229 FSums.push_back(FunctionSummaryYaml{ 230 FSum->flags().Linkage, 231 static_cast<bool>(FSum->flags().NotEligibleToImport), 232 static_cast<bool>(FSum->flags().Live), 233 static_cast<bool>(FSum->flags().DSOLocal), FSum->type_tests(), 234 FSum->type_test_assume_vcalls(), FSum->type_checked_load_vcalls(), 235 FSum->type_test_assume_const_vcalls(), 236 FSum->type_checked_load_const_vcalls()}); 237 } 238 if (!FSums.empty()) 239 io.mapRequired(llvm::utostr(P.first).c_str(), FSums); 240 } 241 } 242 }; 243 244 template <> struct MappingTraits<ModuleSummaryIndex> { 245 static void mapping(IO &io, ModuleSummaryIndex& index) { 246 io.mapOptional("GlobalValueMap", index.GlobalValueMap); 247 io.mapOptional("TypeIdMap", index.TypeIdMap); 248 io.mapOptional("WithGlobalValueDeadStripping", 249 index.WithGlobalValueDeadStripping); 250 251 if (io.outputting()) { 252 std::vector<std::string> CfiFunctionDefs(index.CfiFunctionDefs.begin(), 253 index.CfiFunctionDefs.end()); 254 io.mapOptional("CfiFunctionDefs", CfiFunctionDefs); 255 std::vector<std::string> CfiFunctionDecls(index.CfiFunctionDecls.begin(), 256 index.CfiFunctionDecls.end()); 257 io.mapOptional("CfiFunctionDecls", CfiFunctionDecls); 258 } else { 259 std::vector<std::string> CfiFunctionDefs; 260 io.mapOptional("CfiFunctionDefs", CfiFunctionDefs); 261 index.CfiFunctionDefs = {CfiFunctionDefs.begin(), CfiFunctionDefs.end()}; 262 std::vector<std::string> CfiFunctionDecls; 263 io.mapOptional("CfiFunctionDecls", CfiFunctionDecls); 264 index.CfiFunctionDecls = {CfiFunctionDecls.begin(), 265 CfiFunctionDecls.end()}; 266 } 267 } 268 }; 269 270 } // End yaml namespace 271 } // End llvm namespace 272 273 #endif 274