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