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
, CanAutoHide
;
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("CanAutoHide", summary
.CanAutoHide
);
184 io
.mapOptional("Refs", summary
.Refs
);
185 io
.mapOptional("TypeTests", summary
.TypeTests
);
186 io
.mapOptional("TypeTestAssumeVCalls", summary
.TypeTestAssumeVCalls
);
187 io
.mapOptional("TypeCheckedLoadVCalls", summary
.TypeCheckedLoadVCalls
);
188 io
.mapOptional("TypeTestAssumeConstVCalls",
189 summary
.TypeTestAssumeConstVCalls
);
190 io
.mapOptional("TypeCheckedLoadConstVCalls",
191 summary
.TypeCheckedLoadConstVCalls
);
195 } // End yaml namespace
196 } // End llvm namespace
198 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml
)
203 // FIXME: Add YAML mappings for the rest of the module summary.
204 template <> struct CustomMappingTraits
<GlobalValueSummaryMapTy
> {
205 static void inputOne(IO
&io
, StringRef Key
, GlobalValueSummaryMapTy
&V
) {
206 std::vector
<FunctionSummaryYaml
> FSums
;
207 io
.mapRequired(Key
.str().c_str(), FSums
);
209 if (Key
.getAsInteger(0, KeyInt
)) {
210 io
.setError("key not an integer");
213 if (!V
.count(KeyInt
))
214 V
.emplace(KeyInt
, /*IsAnalysis=*/false);
215 auto &Elem
= V
.find(KeyInt
)->second
;
216 for (auto &FSum
: FSums
) {
217 std::vector
<ValueInfo
> Refs
;
218 for (auto &RefGUID
: FSum
.Refs
) {
219 if (!V
.count(RefGUID
))
220 V
.emplace(RefGUID
, /*IsAnalysis=*/false);
221 Refs
.push_back(ValueInfo(/*IsAnalysis=*/false, &*V
.find(RefGUID
)));
223 Elem
.SummaryList
.push_back(std::make_unique
<FunctionSummary
>(
224 GlobalValueSummary::GVFlags(
225 static_cast<GlobalValue::LinkageTypes
>(FSum
.Linkage
),
226 FSum
.NotEligibleToImport
, FSum
.Live
, FSum
.IsLocal
, FSum
.CanAutoHide
),
227 /*NumInsts=*/0, FunctionSummary::FFlags
{}, /*EntryCount=*/0, Refs
,
228 ArrayRef
<FunctionSummary::EdgeTy
>{}, std::move(FSum
.TypeTests
),
229 std::move(FSum
.TypeTestAssumeVCalls
),
230 std::move(FSum
.TypeCheckedLoadVCalls
),
231 std::move(FSum
.TypeTestAssumeConstVCalls
),
232 std::move(FSum
.TypeCheckedLoadConstVCalls
)));
235 static void output(IO
&io
, GlobalValueSummaryMapTy
&V
) {
237 std::vector
<FunctionSummaryYaml
> FSums
;
238 for (auto &Sum
: P
.second
.SummaryList
) {
239 if (auto *FSum
= dyn_cast
<FunctionSummary
>(Sum
.get())) {
240 std::vector
<uint64_t> Refs
;
241 for (auto &VI
: FSum
->refs())
242 Refs
.push_back(VI
.getGUID());
243 FSums
.push_back(FunctionSummaryYaml
{
244 FSum
->flags().Linkage
,
245 static_cast<bool>(FSum
->flags().NotEligibleToImport
),
246 static_cast<bool>(FSum
->flags().Live
),
247 static_cast<bool>(FSum
->flags().DSOLocal
),
248 static_cast<bool>(FSum
->flags().CanAutoHide
), Refs
,
249 FSum
->type_tests(), FSum
->type_test_assume_vcalls(),
250 FSum
->type_checked_load_vcalls(),
251 FSum
->type_test_assume_const_vcalls(),
252 FSum
->type_checked_load_const_vcalls()});
256 io
.mapRequired(llvm::utostr(P
.first
).c_str(), FSums
);
261 template <> struct CustomMappingTraits
<TypeIdSummaryMapTy
> {
262 static void inputOne(IO
&io
, StringRef Key
, TypeIdSummaryMapTy
&V
) {
264 io
.mapRequired(Key
.str().c_str(), TId
);
265 V
.insert({GlobalValue::getGUID(Key
), {Key
, TId
}});
267 static void output(IO
&io
, TypeIdSummaryMapTy
&V
) {
268 for (auto TidIter
= V
.begin(); TidIter
!= V
.end(); TidIter
++)
269 io
.mapRequired(TidIter
->second
.first
.c_str(), TidIter
->second
.second
);
273 template <> struct MappingTraits
<ModuleSummaryIndex
> {
274 static void mapping(IO
&io
, ModuleSummaryIndex
& index
) {
275 io
.mapOptional("GlobalValueMap", index
.GlobalValueMap
);
276 io
.mapOptional("TypeIdMap", index
.TypeIdMap
);
277 io
.mapOptional("WithGlobalValueDeadStripping",
278 index
.WithGlobalValueDeadStripping
);
280 if (io
.outputting()) {
281 std::vector
<std::string
> CfiFunctionDefs(index
.CfiFunctionDefs
.begin(),
282 index
.CfiFunctionDefs
.end());
283 io
.mapOptional("CfiFunctionDefs", CfiFunctionDefs
);
284 std::vector
<std::string
> CfiFunctionDecls(index
.CfiFunctionDecls
.begin(),
285 index
.CfiFunctionDecls
.end());
286 io
.mapOptional("CfiFunctionDecls", CfiFunctionDecls
);
288 std::vector
<std::string
> CfiFunctionDefs
;
289 io
.mapOptional("CfiFunctionDefs", CfiFunctionDefs
);
290 index
.CfiFunctionDefs
= {CfiFunctionDefs
.begin(), CfiFunctionDefs
.end()};
291 std::vector
<std::string
> CfiFunctionDecls
;
292 io
.mapOptional("CfiFunctionDecls", CfiFunctionDecls
);
293 index
.CfiFunctionDecls
= {CfiFunctionDecls
.begin(),
294 CfiFunctionDecls
.end()};
299 } // End yaml namespace
300 } // End llvm namespace