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 std::vector<uint64_t> TypeTests; 132 std::vector<FunctionSummary::VFuncId> TypeTestAssumeVCalls, 133 TypeCheckedLoadVCalls; 134 std::vector<FunctionSummary::ConstVCall> TypeTestAssumeConstVCalls, 135 TypeCheckedLoadConstVCalls; 136 }; 137 138 } // End yaml namespace 139 } // End llvm namespace 140 141 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint64_t) 142 143 namespace llvm { 144 namespace yaml { 145 146 template <> struct MappingTraits<FunctionSummary::VFuncId> { 147 static void mapping(IO &io, FunctionSummary::VFuncId& id) { 148 io.mapOptional("GUID", id.GUID); 149 io.mapOptional("Offset", id.Offset); 150 } 151 }; 152 153 template <> struct MappingTraits<FunctionSummary::ConstVCall> { 154 static void mapping(IO &io, FunctionSummary::ConstVCall& id) { 155 io.mapOptional("VFunc", id.VFunc); 156 io.mapOptional("Args", id.Args); 157 } 158 }; 159 160 } // End yaml namespace 161 } // End llvm namespace 162 163 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::VFuncId) 164 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::ConstVCall) 165 166 namespace llvm { 167 namespace yaml { 168 169 template <> struct MappingTraits<FunctionSummaryYaml> { 170 static void mapping(IO &io, FunctionSummaryYaml& summary) { 171 io.mapOptional("TypeTests", summary.TypeTests); 172 io.mapOptional("TypeTestAssumeVCalls", summary.TypeTestAssumeVCalls); 173 io.mapOptional("TypeCheckedLoadVCalls", summary.TypeCheckedLoadVCalls); 174 io.mapOptional("TypeTestAssumeConstVCalls", 175 summary.TypeTestAssumeConstVCalls); 176 io.mapOptional("TypeCheckedLoadConstVCalls", 177 summary.TypeCheckedLoadConstVCalls); 178 } 179 }; 180 181 } // End yaml namespace 182 } // End llvm namespace 183 184 LLVM_YAML_IS_STRING_MAP(TypeIdSummary) 185 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml) 186 187 namespace llvm { 188 namespace yaml { 189 190 // FIXME: Add YAML mappings for the rest of the module summary. 191 template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> { 192 static void inputOne(IO &io, StringRef Key, GlobalValueSummaryMapTy &V) { 193 std::vector<FunctionSummaryYaml> FSums; 194 io.mapRequired(Key.str().c_str(), FSums); 195 uint64_t KeyInt; 196 if (Key.getAsInteger(0, KeyInt)) { 197 io.setError("key not an integer"); 198 return; 199 } 200 auto &Elem = V[KeyInt]; 201 for (auto &FSum : FSums) { 202 GlobalValueSummary::GVFlags GVFlags(GlobalValue::ExternalLinkage, false, 203 false); 204 Elem.push_back(llvm::make_unique<FunctionSummary>( 205 GVFlags, 0, ArrayRef<ValueInfo>{}, 206 ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests), 207 std::move(FSum.TypeTestAssumeVCalls), 208 std::move(FSum.TypeCheckedLoadVCalls), 209 std::move(FSum.TypeTestAssumeConstVCalls), 210 std::move(FSum.TypeCheckedLoadConstVCalls))); 211 } 212 } 213 static void output(IO &io, GlobalValueSummaryMapTy &V) { 214 for (auto &P : V) { 215 std::vector<FunctionSummaryYaml> FSums; 216 for (auto &Sum : P.second) { 217 if (auto *FSum = dyn_cast<FunctionSummary>(Sum.get())) 218 FSums.push_back(FunctionSummaryYaml{ 219 FSum->type_tests(), FSum->type_test_assume_vcalls(), 220 FSum->type_checked_load_vcalls(), 221 FSum->type_test_assume_const_vcalls(), 222 FSum->type_checked_load_const_vcalls()}); 223 } 224 if (!FSums.empty()) 225 io.mapRequired(llvm::utostr(P.first).c_str(), FSums); 226 } 227 } 228 }; 229 230 template <> struct MappingTraits<ModuleSummaryIndex> { 231 static void mapping(IO &io, ModuleSummaryIndex& index) { 232 io.mapOptional("GlobalValueMap", index.GlobalValueMap); 233 io.mapOptional("TypeIdMap", index.TypeIdMap); 234 } 235 }; 236 237 } // End yaml namespace 238 } // End llvm namespace 239 240 #endif 241