1 //===-- llvm/ModuleSummaryIndexYAML.h - YAML I/O for summary ----*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_IR_MODULESUMMARYINDEXYAML_H
10 #define LLVM_IR_MODULESUMMARYINDEXYAML_H
12 #include "llvm/IR/ModuleSummaryIndex.h"
13 #include "llvm/Support/YAMLTraits.h"
18 template <> struct ScalarEnumerationTraits
<TypeTestResolution::Kind
> {
19 static void enumeration(IO
&io
, TypeTestResolution::Kind
&value
) {
20 io
.enumCase(value
, "Unsat", TypeTestResolution::Unsat
);
21 io
.enumCase(value
, "ByteArray", TypeTestResolution::ByteArray
);
22 io
.enumCase(value
, "Inline", TypeTestResolution::Inline
);
23 io
.enumCase(value
, "Single", TypeTestResolution::Single
);
24 io
.enumCase(value
, "AllOnes", TypeTestResolution::AllOnes
);
28 template <> struct MappingTraits
<TypeTestResolution
> {
29 static void mapping(IO
&io
, TypeTestResolution
&res
) {
30 io
.mapOptional("Kind", res
.TheKind
);
31 io
.mapOptional("SizeM1BitWidth", res
.SizeM1BitWidth
);
32 io
.mapOptional("AlignLog2", res
.AlignLog2
);
33 io
.mapOptional("SizeM1", res
.SizeM1
);
34 io
.mapOptional("BitMask", res
.BitMask
);
35 io
.mapOptional("InlineBits", res
.InlineBits
);
40 struct ScalarEnumerationTraits
<WholeProgramDevirtResolution::ByArg::Kind
> {
41 static void enumeration(IO
&io
,
42 WholeProgramDevirtResolution::ByArg::Kind
&value
) {
43 io
.enumCase(value
, "Indir", WholeProgramDevirtResolution::ByArg::Indir
);
44 io
.enumCase(value
, "UniformRetVal",
45 WholeProgramDevirtResolution::ByArg::UniformRetVal
);
46 io
.enumCase(value
, "UniqueRetVal",
47 WholeProgramDevirtResolution::ByArg::UniqueRetVal
);
48 io
.enumCase(value
, "VirtualConstProp",
49 WholeProgramDevirtResolution::ByArg::VirtualConstProp
);
53 template <> struct MappingTraits
<WholeProgramDevirtResolution::ByArg
> {
54 static void mapping(IO
&io
, WholeProgramDevirtResolution::ByArg
&res
) {
55 io
.mapOptional("Kind", res
.TheKind
);
56 io
.mapOptional("Info", res
.Info
);
57 io
.mapOptional("Byte", res
.Byte
);
58 io
.mapOptional("Bit", res
.Bit
);
63 struct CustomMappingTraits
<
64 std::map
<std::vector
<uint64_t>, WholeProgramDevirtResolution::ByArg
>> {
66 IO
&io
, StringRef Key
,
67 std::map
<std::vector
<uint64_t>, WholeProgramDevirtResolution::ByArg
> &V
) {
68 std::vector
<uint64_t> Args
;
69 std::pair
<StringRef
, StringRef
> P
= {"", Key
};
70 while (!P
.second
.empty()) {
71 P
= P
.second
.split(',');
73 if (P
.first
.getAsInteger(0, Arg
)) {
74 io
.setError("key not an integer");
79 io
.mapRequired(Key
.str().c_str(), V
[Args
]);
83 std::map
<std::vector
<uint64_t>, WholeProgramDevirtResolution::ByArg
> &V
) {
86 for (uint64_t Arg
: P
.first
) {
89 Key
+= llvm::utostr(Arg
);
91 io
.mapRequired(Key
.c_str(), P
.second
);
96 template <> struct ScalarEnumerationTraits
<WholeProgramDevirtResolution::Kind
> {
97 static void enumeration(IO
&io
, WholeProgramDevirtResolution::Kind
&value
) {
98 io
.enumCase(value
, "Indir", WholeProgramDevirtResolution::Indir
);
99 io
.enumCase(value
, "SingleImpl", WholeProgramDevirtResolution::SingleImpl
);
100 io
.enumCase(value
, "BranchFunnel",
101 WholeProgramDevirtResolution::BranchFunnel
);
105 template <> struct MappingTraits
<WholeProgramDevirtResolution
> {
106 static void mapping(IO
&io
, WholeProgramDevirtResolution
&res
) {
107 io
.mapOptional("Kind", res
.TheKind
);
108 io
.mapOptional("SingleImplName", res
.SingleImplName
);
109 io
.mapOptional("ResByArg", res
.ResByArg
);
114 struct CustomMappingTraits
<std::map
<uint64_t, WholeProgramDevirtResolution
>> {
115 static void inputOne(IO
&io
, StringRef Key
,
116 std::map
<uint64_t, WholeProgramDevirtResolution
> &V
) {
118 if (Key
.getAsInteger(0, KeyInt
)) {
119 io
.setError("key not an integer");
122 io
.mapRequired(Key
.str().c_str(), V
[KeyInt
]);
124 static void output(IO
&io
, std::map
<uint64_t, WholeProgramDevirtResolution
> &V
) {
126 io
.mapRequired(llvm::utostr(P
.first
).c_str(), P
.second
);
130 template <> struct MappingTraits
<TypeIdSummary
> {
131 static void mapping(IO
&io
, TypeIdSummary
& summary
) {
132 io
.mapOptional("TTRes", summary
.TTRes
);
133 io
.mapOptional("WPDRes", summary
.WPDRes
);
137 struct FunctionSummaryYaml
{
139 bool NotEligibleToImport
, Live
, IsLocal
;
140 std::vector
<uint64_t> Refs
;
141 std::vector
<uint64_t> TypeTests
;
142 std::vector
<FunctionSummary::VFuncId
> TypeTestAssumeVCalls
,
143 TypeCheckedLoadVCalls
;
144 std::vector
<FunctionSummary::ConstVCall
> TypeTestAssumeConstVCalls
,
145 TypeCheckedLoadConstVCalls
;
148 } // End yaml namespace
149 } // End llvm namespace
154 template <> struct MappingTraits
<FunctionSummary::VFuncId
> {
155 static void mapping(IO
&io
, FunctionSummary::VFuncId
& id
) {
156 io
.mapOptional("GUID", id
.GUID
);
157 io
.mapOptional("Offset", id
.Offset
);
161 template <> struct MappingTraits
<FunctionSummary::ConstVCall
> {
162 static void mapping(IO
&io
, FunctionSummary::ConstVCall
& id
) {
163 io
.mapOptional("VFunc", id
.VFunc
);
164 io
.mapOptional("Args", id
.Args
);
168 } // End yaml namespace
169 } // End llvm namespace
171 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::VFuncId
)
172 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::ConstVCall
)
177 template <> struct MappingTraits
<FunctionSummaryYaml
> {
178 static void mapping(IO
&io
, FunctionSummaryYaml
& summary
) {
179 io
.mapOptional("Linkage", summary
.Linkage
);
180 io
.mapOptional("NotEligibleToImport", summary
.NotEligibleToImport
);
181 io
.mapOptional("Live", summary
.Live
);
182 io
.mapOptional("Local", summary
.IsLocal
);
183 io
.mapOptional("Refs", summary
.Refs
);
184 io
.mapOptional("TypeTests", summary
.TypeTests
);
185 io
.mapOptional("TypeTestAssumeVCalls", summary
.TypeTestAssumeVCalls
);
186 io
.mapOptional("TypeCheckedLoadVCalls", summary
.TypeCheckedLoadVCalls
);
187 io
.mapOptional("TypeTestAssumeConstVCalls",
188 summary
.TypeTestAssumeConstVCalls
);
189 io
.mapOptional("TypeCheckedLoadConstVCalls",
190 summary
.TypeCheckedLoadConstVCalls
);
194 } // End yaml namespace
195 } // End llvm namespace
197 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml
)
202 // FIXME: Add YAML mappings for the rest of the module summary.
203 template <> struct CustomMappingTraits
<GlobalValueSummaryMapTy
> {
204 static void inputOne(IO
&io
, StringRef Key
, GlobalValueSummaryMapTy
&V
) {
205 std::vector
<FunctionSummaryYaml
> FSums
;
206 io
.mapRequired(Key
.str().c_str(), FSums
);
208 if (Key
.getAsInteger(0, KeyInt
)) {
209 io
.setError("key not an integer");
212 if (!V
.count(KeyInt
))
213 V
.emplace(KeyInt
, /*IsAnalysis=*/false);
214 auto &Elem
= V
.find(KeyInt
)->second
;
215 for (auto &FSum
: FSums
) {
216 std::vector
<ValueInfo
> Refs
;
217 for (auto &RefGUID
: FSum
.Refs
) {
218 if (!V
.count(RefGUID
))
219 V
.emplace(RefGUID
, /*IsAnalysis=*/false);
220 Refs
.push_back(ValueInfo(/*IsAnalysis=*/false, &*V
.find(RefGUID
)));
222 Elem
.SummaryList
.push_back(llvm::make_unique
<FunctionSummary
>(
223 GlobalValueSummary::GVFlags(
224 static_cast<GlobalValue::LinkageTypes
>(FSum
.Linkage
),
225 FSum
.NotEligibleToImport
, FSum
.Live
, FSum
.IsLocal
),
226 /*NumInsts=*/0, FunctionSummary::FFlags
{}, /*EntryCount=*/0, Refs
,
227 ArrayRef
<FunctionSummary::EdgeTy
>{}, std::move(FSum
.TypeTests
),
228 std::move(FSum
.TypeTestAssumeVCalls
),
229 std::move(FSum
.TypeCheckedLoadVCalls
),
230 std::move(FSum
.TypeTestAssumeConstVCalls
),
231 std::move(FSum
.TypeCheckedLoadConstVCalls
)));
234 static void output(IO
&io
, GlobalValueSummaryMapTy
&V
) {
236 std::vector
<FunctionSummaryYaml
> FSums
;
237 for (auto &Sum
: P
.second
.SummaryList
) {
238 if (auto *FSum
= dyn_cast
<FunctionSummary
>(Sum
.get())) {
239 std::vector
<uint64_t> Refs
;
240 for (auto &VI
: FSum
->refs())
241 Refs
.push_back(VI
.getGUID());
242 FSums
.push_back(FunctionSummaryYaml
{
243 FSum
->flags().Linkage
,
244 static_cast<bool>(FSum
->flags().NotEligibleToImport
),
245 static_cast<bool>(FSum
->flags().Live
),
246 static_cast<bool>(FSum
->flags().DSOLocal
), Refs
,
247 FSum
->type_tests(), FSum
->type_test_assume_vcalls(),
248 FSum
->type_checked_load_vcalls(),
249 FSum
->type_test_assume_const_vcalls(),
250 FSum
->type_checked_load_const_vcalls()});
254 io
.mapRequired(llvm::utostr(P
.first
).c_str(), FSums
);
259 template <> struct CustomMappingTraits
<TypeIdSummaryMapTy
> {
260 static void inputOne(IO
&io
, StringRef Key
, TypeIdSummaryMapTy
&V
) {
262 io
.mapRequired(Key
.str().c_str(), TId
);
263 V
.insert({GlobalValue::getGUID(Key
), {Key
, TId
}});
265 static void output(IO
&io
, TypeIdSummaryMapTy
&V
) {
266 for (auto TidIter
= V
.begin(); TidIter
!= V
.end(); TidIter
++)
267 io
.mapRequired(TidIter
->second
.first
.c_str(), TidIter
->second
.second
);
271 template <> struct MappingTraits
<ModuleSummaryIndex
> {
272 static void mapping(IO
&io
, ModuleSummaryIndex
& index
) {
273 io
.mapOptional("GlobalValueMap", index
.GlobalValueMap
);
274 io
.mapOptional("TypeIdMap", index
.TypeIdMap
);
275 io
.mapOptional("WithGlobalValueDeadStripping",
276 index
.WithGlobalValueDeadStripping
);
278 if (io
.outputting()) {
279 std::vector
<std::string
> CfiFunctionDefs(index
.CfiFunctionDefs
.begin(),
280 index
.CfiFunctionDefs
.end());
281 io
.mapOptional("CfiFunctionDefs", CfiFunctionDefs
);
282 std::vector
<std::string
> CfiFunctionDecls(index
.CfiFunctionDecls
.begin(),
283 index
.CfiFunctionDecls
.end());
284 io
.mapOptional("CfiFunctionDecls", CfiFunctionDecls
);
286 std::vector
<std::string
> CfiFunctionDefs
;
287 io
.mapOptional("CfiFunctionDefs", CfiFunctionDefs
);
288 index
.CfiFunctionDefs
= {CfiFunctionDefs
.begin(), CfiFunctionDefs
.end()};
289 std::vector
<std::string
> CfiFunctionDecls
;
290 io
.mapOptional("CfiFunctionDecls", CfiFunctionDecls
);
291 index
.CfiFunctionDecls
= {CfiFunctionDecls
.begin(),
292 CfiFunctionDecls
.end()};
297 } // End yaml namespace
298 } // End llvm namespace