LLVM 23.0.0git
ModuleSummaryIndexYAML.h
Go to the documentation of this file.
1//===-- llvm/ModuleSummaryIndexYAML.h - YAML I/O for summary ----*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_IR_MODULESUMMARYINDEXYAML_H
10#define LLVM_IR_MODULESUMMARYINDEXYAML_H
11
12#include "llvm/ADT/StringRef.h"
15#include <algorithm>
16
17namespace llvm {
18namespace yaml {
19
21 static void enumeration(IO &io, TypeTestResolution::Kind &value) {
22 io.enumCase(value, "Unknown", TypeTestResolution::Unknown);
23 io.enumCase(value, "Unsat", TypeTestResolution::Unsat);
24 io.enumCase(value, "ByteArray", TypeTestResolution::ByteArray);
25 io.enumCase(value, "Inline", TypeTestResolution::Inline);
26 io.enumCase(value, "Single", TypeTestResolution::Single);
27 io.enumCase(value, "AllOnes", TypeTestResolution::AllOnes);
28 }
29};
30
31template <> struct MappingTraits<TypeTestResolution> {
32 static void mapping(IO &io, TypeTestResolution &res) {
33 io.mapOptional("Kind", res.TheKind);
34 io.mapOptional("SizeM1BitWidth", res.SizeM1BitWidth);
35 io.mapOptional("AlignLog2", res.AlignLog2);
36 io.mapOptional("SizeM1", res.SizeM1);
37 io.mapOptional("BitMask", res.BitMask);
38 io.mapOptional("InlineBits", res.InlineBits);
39 }
40};
41
42template <>
55
56template <> struct MappingTraits<WholeProgramDevirtResolution::ByArg> {
58 io.mapOptional("Kind", res.TheKind);
59 io.mapOptional("Info", res.Info);
60 io.mapOptional("Byte", res.Byte);
61 io.mapOptional("Bit", res.Bit);
62 }
63};
64
65template <>
67 std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg>> {
68 static void inputOne(
69 IO &io, StringRef Key,
70 std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg> &V) {
71 std::vector<uint64_t> Args;
72 std::pair<StringRef, StringRef> P = {"", Key};
73 while (!P.second.empty()) {
74 P = P.second.split(',');
75 uint64_t Arg;
76 if (P.first.getAsInteger(0, Arg)) {
77 io.setError("key not an integer");
78 return;
79 }
80 Args.push_back(Arg);
81 }
82 io.mapRequired(Key, V[Args]);
83 }
84 static void output(
85 IO &io,
86 std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg> &V) {
87 for (auto &P : V) {
88 std::string Key;
89 for (uint64_t Arg : P.first) {
90 if (!Key.empty())
91 Key += ',';
92 Key += llvm::utostr(Arg);
93 }
94 io.mapRequired(Key, P.second);
95 }
96 }
97};
98
102 io.enumCase(value, "SingleImpl", WholeProgramDevirtResolution::SingleImpl);
103 io.enumCase(value, "BranchFunnel",
105 }
106};
107
109 static void mapping(IO &io, WholeProgramDevirtResolution &res) {
110 io.mapOptional("Kind", res.TheKind);
111 io.mapOptional("SingleImplName", res.SingleImplName);
112 io.mapOptional("ResByArg", res.ResByArg);
113 }
114};
115
116template <>
117struct CustomMappingTraits<std::map<uint64_t, WholeProgramDevirtResolution>> {
118 static void inputOne(IO &io, StringRef Key,
119 std::map<uint64_t, WholeProgramDevirtResolution> &V) {
120 uint64_t KeyInt;
121 if (Key.getAsInteger(0, KeyInt)) {
122 io.setError("key not an integer");
123 return;
124 }
125 io.mapRequired(Key, V[KeyInt]);
126 }
127 static void output(IO &io, std::map<uint64_t, WholeProgramDevirtResolution> &V) {
128 for (auto &P : V)
129 io.mapRequired(llvm::utostr(P.first), P.second);
130 }
131};
132
133template <> struct MappingTraits<TypeIdSummary> {
134 static void mapping(IO &io, TypeIdSummary& summary) {
135 io.mapOptional("TTRes", summary.TTRes);
136 io.mapOptional("WPDRes", summary.WPDRes);
137 }
138};
139
141 // Commonly used fields
144 unsigned ImportType;
146 // Fields for AliasSummary
147 std::optional<uint64_t> Aliasee;
148 // Fields for FunctionSummary
149 std::vector<uint64_t> Refs = {};
150 std::vector<uint64_t> TypeTests = {};
151 std::vector<FunctionSummary::VFuncId> TypeTestAssumeVCalls = {};
152 std::vector<FunctionSummary::VFuncId> TypeCheckedLoadVCalls = {};
153 std::vector<FunctionSummary::ConstVCall> TypeTestAssumeConstVCalls = {};
154 std::vector<FunctionSummary::ConstVCall> TypeCheckedLoadConstVCalls = {};
155};
156
157} // End yaml namespace
158} // End llvm namespace
159
160namespace llvm {
161namespace yaml {
162
163template <> struct MappingTraits<FunctionSummary::VFuncId> {
164 static void mapping(IO &io, FunctionSummary::VFuncId& id) {
165 io.mapOptional("GUID", id.GUID);
166 io.mapOptional("Offset", id.Offset);
167 }
168};
169
170template <> struct MappingTraits<FunctionSummary::ConstVCall> {
171 static void mapping(IO &io, FunctionSummary::ConstVCall& id) {
172 io.mapOptional("VFunc", id.VFunc);
173 io.mapOptional("Args", id.Args);
174 }
175};
176
177} // End yaml namespace
178} // End llvm namespace
179
180LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::VFuncId)
181LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::ConstVCall)
182
183namespace llvm {
184namespace yaml {
185
187 static void mapping(IO &io, GlobalValueSummaryYaml &summary) {
188 io.mapOptional("Linkage", summary.Linkage);
189 io.mapOptional("Visibility", summary.Visibility);
190 io.mapOptional("NotEligibleToImport", summary.NotEligibleToImport);
191 io.mapOptional("Live", summary.Live);
192 io.mapOptional("Local", summary.IsLocal);
193 io.mapOptional("CanAutoHide", summary.CanAutoHide);
194 io.mapOptional("ImportType", summary.ImportType);
195 io.mapOptional("NoRenameOnPromotion", summary.NoRenameOnPromotion);
196 io.mapOptional("Aliasee", summary.Aliasee);
197 io.mapOptional("Refs", summary.Refs);
198 io.mapOptional("TypeTests", summary.TypeTests);
199 io.mapOptional("TypeTestAssumeVCalls", summary.TypeTestAssumeVCalls);
200 io.mapOptional("TypeCheckedLoadVCalls", summary.TypeCheckedLoadVCalls);
201 io.mapOptional("TypeTestAssumeConstVCalls",
203 io.mapOptional("TypeCheckedLoadConstVCalls",
205 }
206};
207
208} // End yaml namespace
209} // End llvm namespace
210
211LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalValueSummaryYaml)
212
213namespace llvm {
214namespace yaml {
215
216// FIXME: Add YAML mappings for the rest of the module summary.
219 std::vector<GlobalValueSummaryYaml> GVSums;
220 io.mapRequired(Key, GVSums);
221 uint64_t KeyInt;
222 if (Key.getAsInteger(0, KeyInt)) {
223 io.setError("key not an integer");
224 return;
225 }
226 auto &Elem = V.try_emplace(KeyInt, /*IsAnalysis=*/false).first->second;
227 for (auto &GVSum : GVSums) {
229 static_cast<GlobalValue::LinkageTypes>(GVSum.Linkage),
230 static_cast<GlobalValue::VisibilityTypes>(GVSum.Visibility),
231 GVSum.NotEligibleToImport, GVSum.Live, GVSum.IsLocal,
232 GVSum.CanAutoHide,
233 static_cast<GlobalValueSummary::ImportKind>(GVSum.ImportType),
234 GVSum.NoRenameOnPromotion);
235 if (GVSum.Aliasee) {
236 auto ASum = std::make_unique<AliasSummary>(GVFlags);
237 V.try_emplace(*GVSum.Aliasee, /*IsAnalysis=*/false);
238 ValueInfo AliaseeVI(/*IsAnalysis=*/false, &*V.find(*GVSum.Aliasee));
239 // Note: Aliasee cannot be filled until all summaries are loaded.
240 // This is done in fixAliaseeLinks() which is called in
241 // MappingTraits<ModuleSummaryIndex>::mapping().
242 ASum->setAliasee(AliaseeVI, /*Aliasee=*/nullptr);
243 Elem.addSummary(std::move(ASum));
244 continue;
245 }
247 Refs.reserve(GVSum.Refs.size());
248 for (auto &RefGUID : GVSum.Refs) {
249 auto It = V.try_emplace(RefGUID, /*IsAnalysis=*/false).first;
250 Refs.push_back(ValueInfo(/*IsAnalysis=*/false, &*It));
251 }
252 Elem.addSummary(std::make_unique<FunctionSummary>(
253 GVFlags, /*NumInsts=*/0, FunctionSummary::FFlags{}, std::move(Refs),
254 SmallVector<FunctionSummary::EdgeTy, 0>{}, std::move(GVSum.TypeTests),
255 std::move(GVSum.TypeTestAssumeVCalls),
256 std::move(GVSum.TypeCheckedLoadVCalls),
257 std::move(GVSum.TypeTestAssumeConstVCalls),
258 std::move(GVSum.TypeCheckedLoadConstVCalls),
261 }
262 }
263 static void output(IO &io, GlobalValueSummaryMapTy &V) {
264 for (auto &P : V) {
265 std::vector<GlobalValueSummaryYaml> GVSums;
266 for (auto &Sum : P.second.getSummaryList()) {
267 if (auto *FSum = dyn_cast<FunctionSummary>(Sum.get())) {
268 std::vector<uint64_t> Refs;
269 Refs.reserve(FSum->refs().size());
270 for (auto &VI : FSum->refs())
271 Refs.push_back(VI.getGUID());
272 GVSums.push_back(GlobalValueSummaryYaml{
273 FSum->flags().Linkage, FSum->flags().Visibility,
274 static_cast<bool>(FSum->flags().NotEligibleToImport),
275 static_cast<bool>(FSum->flags().Live),
276 static_cast<bool>(FSum->flags().DSOLocal),
277 static_cast<bool>(FSum->flags().CanAutoHide),
278 FSum->flags().ImportType,
279 static_cast<bool>(FSum->flags().NoRenameOnPromotion),
280 /*Aliasee=*/std::nullopt, Refs, FSum->type_tests(),
281 FSum->type_test_assume_vcalls(), FSum->type_checked_load_vcalls(),
282 FSum->type_test_assume_const_vcalls(),
283 FSum->type_checked_load_const_vcalls()});
284 } else if (auto *ASum = dyn_cast<AliasSummary>(Sum.get());
285 ASum && ASum->hasAliasee()) {
286 GVSums.push_back(GlobalValueSummaryYaml{
287 ASum->flags().Linkage, ASum->flags().Visibility,
288 static_cast<bool>(ASum->flags().NotEligibleToImport),
289 static_cast<bool>(ASum->flags().Live),
290 static_cast<bool>(ASum->flags().DSOLocal),
291 static_cast<bool>(ASum->flags().CanAutoHide),
292 ASum->flags().ImportType,
293 static_cast<bool>(ASum->flags().NoRenameOnPromotion),
294 /*Aliasee=*/ASum->getAliaseeGUID()});
295 }
296 }
297 if (!GVSums.empty())
298 io.mapRequired(llvm::utostr(P.first), GVSums);
299 }
300 }
302 for (auto &P : V) {
303 for (auto &Sum : P.second.getSummaryList()) {
304 if (auto *Alias = dyn_cast<AliasSummary>(Sum.get())) {
305 ValueInfo AliaseeVI = Alias->getAliaseeVI();
306 auto AliaseeSL = AliaseeVI.getSummaryList();
307 if (AliaseeSL.empty()) {
309 Alias->setAliasee(EmptyVI, nullptr);
310 } else
311 Alias->setAliasee(AliaseeVI, AliaseeSL[0].get());
312 }
313 }
314 }
315 }
316};
317
320 TypeIdSummary TId;
321 io.mapRequired(Key, TId);
323 }
324 static void output(IO &io, TypeIdSummaryMapTy &V) {
325 for (auto &TidIter : V)
326 io.mapRequired(TidIter.second.first, TidIter.second.second);
327 }
328};
329
331 static void mapping(IO &io, ModuleSummaryIndex& index) {
332 io.mapOptional("GlobalValueMap", index.GlobalValueMap);
333 if (!io.outputting())
335 index.GlobalValueMap);
336
337 if (io.outputting()) {
338 io.mapOptional("TypeIdMap", index.TypeIdMap);
339 } else {
340 TypeIdSummaryMapTy TypeIdMap;
341 io.mapOptional("TypeIdMap", TypeIdMap);
342 for (auto &[TypeGUID, TypeIdSummaryMap] : TypeIdMap) {
343 // Save type id references in index and point TypeIdMap to use the
344 // references owned by index.
345 StringRef KeyRef = index.TypeIdSaver.save(TypeIdSummaryMap.first);
346 index.TypeIdMap.insert(
347 {TypeGUID, {KeyRef, std::move(TypeIdSummaryMap.second)}});
348 }
349 }
350
351 io.mapOptional("WithGlobalValueDeadStripping",
352 index.WithGlobalValueDeadStripping);
353
354 if (io.outputting()) {
355 auto CfiFunctionDefs = index.CfiFunctionDefs.symbols();
356 llvm::sort(CfiFunctionDefs);
357 io.mapOptional("CfiFunctionDefs", CfiFunctionDefs);
358 auto CfiFunctionDecls(index.CfiFunctionDecls.symbols());
359 llvm::sort(CfiFunctionDecls);
360 io.mapOptional("CfiFunctionDecls", CfiFunctionDecls);
361 } else {
362 std::vector<std::string> CfiFunctionDefs;
363 io.mapOptional("CfiFunctionDefs", CfiFunctionDefs);
364 index.CfiFunctionDefs = {CfiFunctionDefs.begin(), CfiFunctionDefs.end()};
365 std::vector<std::string> CfiFunctionDecls;
366 io.mapOptional("CfiFunctionDecls", CfiFunctionDecls);
367 index.CfiFunctionDecls = {CfiFunctionDecls.begin(),
368 CfiFunctionDecls.end()};
369 }
370 }
371};
372
373} // End yaml namespace
374} // End llvm namespace
375
376#endif
static ValueInfo EmptyVI
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
#define P(N)
#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)
Utility for declaring that a std::vector of a particular type should be considered a YAML sequence.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
std::vector< StringRef > symbols() const
Function summary information to aid decisions and implementation of importing.
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
Definition Globals.cpp:78
VisibilityTypes
An enumeration for the kinds of visibility of global values.
Definition GlobalValue.h:67
LinkageTypes
An enumeration for the kinds of linkage for global values.
Definition GlobalValue.h:52
Class to hold module path string table and global value map, and encapsulate methods for operating on...
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
StringRef save(const char *S)
Definition StringSaver.h:53
virtual bool outputting() const =0
void enumCase(T &Val, StringRef Str, const T ConstVal)
Definition YAMLTraits.h:734
void mapOptional(StringRef Key, T &Val)
Definition YAMLTraits.h:799
virtual void setError(const Twine &)=0
void mapRequired(StringRef Key, T &Val)
Definition YAMLTraits.h:789
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
std::multimap< GlobalValue::GUID, std::pair< StringRef, TypeIdSummary > > TypeIdSummaryMapTy
Map of a type GUID to type id string and summary (multimap used in case of GUID conflicts).
std::string utostr(uint64_t X, bool isNeg=false)
std::map< GlobalValue::GUID, GlobalValueSummaryInfo > GlobalValueSummaryMapTy
Map from global value GUID to corresponding summary structures.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
A specification for a virtual function call with all constant integer arguments.
Flags specific to function summaries.
An "identifier" for a virtual function.
Group flags (Linkage, NotEligibleToImport, etc.) as a bitfield.
std::map< uint64_t, WholeProgramDevirtResolution > WPDRes
Mapping from byte offset to whole-program devirt resolution for that (typeid, byte offset) pair.
TypeTestResolution TTRes
Kind
Specifies which kind of type check we should emit for this byte array.
@ Unknown
Unknown (analysis not performed, don't lower)
@ Single
Single element (last example in "Short Inline Bit Vectors")
@ Inline
Inlined bit vector ("Short Inline Bit Vectors")
@ Unsat
Unsatisfiable type (i.e. no global has this type metadata)
@ AllOnes
All-ones bit vector ("Eliminating Bit Vector Checks for All-Ones Bit Vectors")
@ ByteArray
Test a byte array (first example)
unsigned SizeM1BitWidth
Range of size-1 expressed as a bit width.
enum llvm::TypeTestResolution::Kind TheKind
Struct that holds a reference to a particular GUID in a global value summary.
ArrayRef< std::unique_ptr< GlobalValueSummary > > getSummaryList() const
@ UniformRetVal
Uniform return value optimization.
@ VirtualConstProp
Virtual constant propagation.
@ UniqueRetVal
Unique return value optimization.
@ Indir
Just do a regular virtual call.
uint64_t Info
Additional information for the resolution:
enum llvm::WholeProgramDevirtResolution::ByArg::Kind TheKind
enum llvm::WholeProgramDevirtResolution::Kind TheKind
std::map< std::vector< uint64_t >, ByArg > ResByArg
Resolutions for calls with all constant integer arguments (excluding the first argument,...
@ SingleImpl
Single implementation devirtualization.
@ Indir
Just do a regular virtual call.
@ BranchFunnel
When retpoline mitigation is enabled, use a branch funnel that is defined in the merged module.
static void output(IO &io, GlobalValueSummaryMapTy &V)
static void inputOne(IO &io, StringRef Key, GlobalValueSummaryMapTy &V)
static void output(IO &io, TypeIdSummaryMapTy &V)
static void inputOne(IO &io, StringRef Key, TypeIdSummaryMapTy &V)
static void inputOne(IO &io, StringRef Key, std::map< std::vector< uint64_t >, WholeProgramDevirtResolution::ByArg > &V)
static void output(IO &io, std::map< std::vector< uint64_t >, WholeProgramDevirtResolution::ByArg > &V)
static void inputOne(IO &io, StringRef Key, std::map< uint64_t, WholeProgramDevirtResolution > &V)
static void output(IO &io, std::map< uint64_t, WholeProgramDevirtResolution > &V)
This class should be specialized by any type that needs to be converted to/from a YAML mapping in the...
Definition YAMLTraits.h:273
std::vector< FunctionSummary::ConstVCall > TypeTestAssumeConstVCalls
std::vector< FunctionSummary::VFuncId > TypeCheckedLoadVCalls
std::vector< FunctionSummary::ConstVCall > TypeCheckedLoadConstVCalls
std::vector< FunctionSummary::VFuncId > TypeTestAssumeVCalls
static void mapping(IO &io, FunctionSummary::ConstVCall &id)
static void mapping(IO &io, FunctionSummary::VFuncId &id)
static void mapping(IO &io, GlobalValueSummaryYaml &summary)
static void mapping(IO &io, ModuleSummaryIndex &index)
static void mapping(IO &io, TypeIdSummary &summary)
static void mapping(IO &io, TypeTestResolution &res)
static void mapping(IO &io, WholeProgramDevirtResolution &res)
static void mapping(IO &io, WholeProgramDevirtResolution::ByArg &res)
This class should be specialized by any type that needs to be converted to/from a YAML mapping.
Definition YAMLTraits.h:62
static void enumeration(IO &io, TypeTestResolution::Kind &value)
static void enumeration(IO &io, WholeProgramDevirtResolution::ByArg::Kind &value)
static void enumeration(IO &io, WholeProgramDevirtResolution::Kind &value)
This class should be specialized by any integral type that converts to/from a YAML scalar where there...
Definition YAMLTraits.h:107