LLVM 22.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.str().c_str(), 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.c_str(), 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.str().c_str(), 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).c_str(), 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;
145 // Fields for AliasSummary
146 std::optional<uint64_t> Aliasee;
147 // Fields for FunctionSummary
148 std::vector<uint64_t> Refs = {};
149 std::vector<uint64_t> TypeTests = {};
150 std::vector<FunctionSummary::VFuncId> TypeTestAssumeVCalls = {};
151 std::vector<FunctionSummary::VFuncId> TypeCheckedLoadVCalls = {};
152 std::vector<FunctionSummary::ConstVCall> TypeTestAssumeConstVCalls = {};
153 std::vector<FunctionSummary::ConstVCall> TypeCheckedLoadConstVCalls = {};
154};
155
156} // End yaml namespace
157} // End llvm namespace
158
159namespace llvm {
160namespace yaml {
161
162template <> struct MappingTraits<FunctionSummary::VFuncId> {
163 static void mapping(IO &io, FunctionSummary::VFuncId& id) {
164 io.mapOptional("GUID", id.GUID);
165 io.mapOptional("Offset", id.Offset);
166 }
167};
168
169template <> struct MappingTraits<FunctionSummary::ConstVCall> {
170 static void mapping(IO &io, FunctionSummary::ConstVCall& id) {
171 io.mapOptional("VFunc", id.VFunc);
172 io.mapOptional("Args", id.Args);
173 }
174};
175
176} // End yaml namespace
177} // End llvm namespace
178
179LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::VFuncId)
180LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::ConstVCall)
181
182namespace llvm {
183namespace yaml {
184
186 static void mapping(IO &io, GlobalValueSummaryYaml &summary) {
187 io.mapOptional("Linkage", summary.Linkage);
188 io.mapOptional("Visibility", summary.Visibility);
189 io.mapOptional("NotEligibleToImport", summary.NotEligibleToImport);
190 io.mapOptional("Live", summary.Live);
191 io.mapOptional("Local", summary.IsLocal);
192 io.mapOptional("CanAutoHide", summary.CanAutoHide);
193 io.mapOptional("ImportType", summary.ImportType);
194 io.mapOptional("Aliasee", summary.Aliasee);
195 io.mapOptional("Refs", summary.Refs);
196 io.mapOptional("TypeTests", summary.TypeTests);
197 io.mapOptional("TypeTestAssumeVCalls", summary.TypeTestAssumeVCalls);
198 io.mapOptional("TypeCheckedLoadVCalls", summary.TypeCheckedLoadVCalls);
199 io.mapOptional("TypeTestAssumeConstVCalls",
201 io.mapOptional("TypeCheckedLoadConstVCalls",
203 }
204};
205
206} // End yaml namespace
207} // End llvm namespace
208
209LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalValueSummaryYaml)
210
211namespace llvm {
212namespace yaml {
213
214// FIXME: Add YAML mappings for the rest of the module summary.
217 std::vector<GlobalValueSummaryYaml> GVSums;
218 io.mapRequired(Key.str().c_str(), GVSums);
219 uint64_t KeyInt;
220 if (Key.getAsInteger(0, KeyInt)) {
221 io.setError("key not an integer");
222 return;
223 }
224 auto &Elem = V.try_emplace(KeyInt, /*IsAnalysis=*/false).first->second;
225 for (auto &GVSum : GVSums) {
227 static_cast<GlobalValue::LinkageTypes>(GVSum.Linkage),
228 static_cast<GlobalValue::VisibilityTypes>(GVSum.Visibility),
229 GVSum.NotEligibleToImport, GVSum.Live, GVSum.IsLocal,
230 GVSum.CanAutoHide,
231 static_cast<GlobalValueSummary::ImportKind>(GVSum.ImportType));
232 if (GVSum.Aliasee) {
233 auto ASum = std::make_unique<AliasSummary>(GVFlags);
234 V.try_emplace(*GVSum.Aliasee, /*IsAnalysis=*/false);
235 ValueInfo AliaseeVI(/*IsAnalysis=*/false, &*V.find(*GVSum.Aliasee));
236 // Note: Aliasee cannot be filled until all summaries are loaded.
237 // This is done in fixAliaseeLinks() which is called in
238 // MappingTraits<ModuleSummaryIndex>::mapping().
239 ASum->setAliasee(AliaseeVI, /*Aliasee=*/nullptr);
240 Elem.SummaryList.push_back(std::move(ASum));
241 continue;
242 }
244 Refs.reserve(GVSum.Refs.size());
245 for (auto &RefGUID : GVSum.Refs) {
246 auto It = V.try_emplace(RefGUID, /*IsAnalysis=*/false).first;
247 Refs.push_back(ValueInfo(/*IsAnalysis=*/false, &*It));
248 }
249 Elem.SummaryList.push_back(std::make_unique<FunctionSummary>(
250 GVFlags, /*NumInsts=*/0, FunctionSummary::FFlags{}, std::move(Refs),
251 SmallVector<FunctionSummary::EdgeTy, 0>{}, std::move(GVSum.TypeTests),
252 std::move(GVSum.TypeTestAssumeVCalls),
253 std::move(GVSum.TypeCheckedLoadVCalls),
254 std::move(GVSum.TypeTestAssumeConstVCalls),
255 std::move(GVSum.TypeCheckedLoadConstVCalls),
258 }
259 }
260 static void output(IO &io, GlobalValueSummaryMapTy &V) {
261 for (auto &P : V) {
262 std::vector<GlobalValueSummaryYaml> GVSums;
263 for (auto &Sum : P.second.SummaryList) {
264 if (auto *FSum = dyn_cast<FunctionSummary>(Sum.get())) {
265 std::vector<uint64_t> Refs;
266 Refs.reserve(FSum->refs().size());
267 for (auto &VI : FSum->refs())
268 Refs.push_back(VI.getGUID());
269 GVSums.push_back(GlobalValueSummaryYaml{
270 FSum->flags().Linkage, FSum->flags().Visibility,
271 static_cast<bool>(FSum->flags().NotEligibleToImport),
272 static_cast<bool>(FSum->flags().Live),
273 static_cast<bool>(FSum->flags().DSOLocal),
274 static_cast<bool>(FSum->flags().CanAutoHide),
275 FSum->flags().ImportType, /*Aliasee=*/std::nullopt, Refs,
276 FSum->type_tests(), FSum->type_test_assume_vcalls(),
277 FSum->type_checked_load_vcalls(),
278 FSum->type_test_assume_const_vcalls(),
279 FSum->type_checked_load_const_vcalls()});
280 } else if (auto *ASum = dyn_cast<AliasSummary>(Sum.get());
281 ASum && ASum->hasAliasee()) {
282 GVSums.push_back(GlobalValueSummaryYaml{
283 ASum->flags().Linkage, ASum->flags().Visibility,
284 static_cast<bool>(ASum->flags().NotEligibleToImport),
285 static_cast<bool>(ASum->flags().Live),
286 static_cast<bool>(ASum->flags().DSOLocal),
287 static_cast<bool>(ASum->flags().CanAutoHide),
288 ASum->flags().ImportType,
289 /*Aliasee=*/ASum->getAliaseeGUID()});
290 }
291 }
292 if (!GVSums.empty())
293 io.mapRequired(llvm::utostr(P.first).c_str(), GVSums);
294 }
295 }
297 for (auto &P : V) {
298 for (auto &Sum : P.second.SummaryList) {
299 if (auto *Alias = dyn_cast<AliasSummary>(Sum.get())) {
300 ValueInfo AliaseeVI = Alias->getAliaseeVI();
301 auto AliaseeSL = AliaseeVI.getSummaryList();
302 if (AliaseeSL.empty()) {
304 Alias->setAliasee(EmptyVI, nullptr);
305 } else
306 Alias->setAliasee(AliaseeVI, AliaseeSL[0].get());
307 }
308 }
309 }
310 }
311};
312
315 TypeIdSummary TId;
316 io.mapRequired(Key.str().c_str(), TId);
318 }
319 static void output(IO &io, TypeIdSummaryMapTy &V) {
320 for (auto &TidIter : V)
321 io.mapRequired(TidIter.second.first.str().c_str(), TidIter.second.second);
322 }
323};
324
326 static void mapping(IO &io, ModuleSummaryIndex& index) {
327 io.mapOptional("GlobalValueMap", index.GlobalValueMap);
328 if (!io.outputting())
330 index.GlobalValueMap);
331
332 if (io.outputting()) {
333 io.mapOptional("TypeIdMap", index.TypeIdMap);
334 } else {
335 TypeIdSummaryMapTy TypeIdMap;
336 io.mapOptional("TypeIdMap", TypeIdMap);
337 for (auto &[TypeGUID, TypeIdSummaryMap] : TypeIdMap) {
338 // Save type id references in index and point TypeIdMap to use the
339 // references owned by index.
340 StringRef KeyRef = index.TypeIdSaver.save(TypeIdSummaryMap.first);
341 index.TypeIdMap.insert(
342 {TypeGUID, {KeyRef, std::move(TypeIdSummaryMap.second)}});
343 }
344 }
345
346 io.mapOptional("WithGlobalValueDeadStripping",
347 index.WithGlobalValueDeadStripping);
348
349 if (io.outputting()) {
350 auto CfiFunctionDefs = index.CfiFunctionDefs.symbols();
351 llvm::sort(CfiFunctionDefs);
352 io.mapOptional("CfiFunctionDefs", CfiFunctionDefs);
353 auto CfiFunctionDecls(index.CfiFunctionDecls.symbols());
354 llvm::sort(CfiFunctionDecls);
355 io.mapOptional("CfiFunctionDecls", CfiFunctionDecls);
356 } else {
357 std::vector<std::string> CfiFunctionDefs;
358 io.mapOptional("CfiFunctionDefs", CfiFunctionDefs);
359 index.CfiFunctionDefs = {CfiFunctionDefs.begin(), CfiFunctionDefs.end()};
360 std::vector<std::string> CfiFunctionDecls;
361 io.mapOptional("CfiFunctionDecls", CfiFunctionDecls);
362 index.CfiFunctionDecls = {CfiFunctionDecls.begin(),
363 CfiFunctionDecls.end()};
364 }
365 }
366};
367
368} // End yaml namespace
369} // End llvm namespace
370
371#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:41
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:77
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
void mapOptional(const char *Key, T &Val)
Definition YAMLTraits.h:810
virtual bool outputting() const =0
void mapRequired(const char *Key, T &Val)
Definition YAMLTraits.h:800
virtual void setError(const Twine &)=0
void enumCase(T &Val, const char *Str, const T ConstVal)
Definition YAMLTraits.h:745
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
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:1652
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:851
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