blob: 45f8cd7cd512955159a945b13bfcd8081839d24c [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- llvm/ModuleSummaryIndex.h - Module Summary Index ---------*- 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/// @file
11/// ModuleSummaryIndex.h This file contains the declarations the classes that
12/// hold the module index and summary for function importing.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_IR_MODULESUMMARYINDEX_H
17#define LLVM_IR_MODULESUMMARYINDEX_H
18
19#include "llvm/ADT/ArrayRef.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/SmallString.h"
23#include "llvm/ADT/StringExtras.h"
24#include "llvm/ADT/StringMap.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/IR/GlobalValue.h"
27#include "llvm/IR/Module.h"
28#include "llvm/Support/MathExtras.h"
29#include "llvm/Support/ScaledNumber.h"
30#include <algorithm>
31#include <array>
32#include <cassert>
33#include <cstddef>
34#include <cstdint>
35#include <map>
36#include <memory>
37#include <set>
38#include <string>
39#include <utility>
40#include <vector>
41
42namespace llvm {
43
44namespace yaml {
45
46template <typename T> struct MappingTraits;
47
48} // end namespace yaml
49
50/// \brief Class to accumulate and hold information about a callee.
51struct CalleeInfo {
52 enum class HotnessType : uint8_t {
53 Unknown = 0,
54 Cold = 1,
55 None = 2,
56 Hot = 3,
57 Critical = 4
58 };
59
60 // The size of the bit-field might need to be adjusted if more values are
61 // added to HotnessType enum.
62 uint32_t Hotness : 3;
63
64 /// The value stored in RelBlockFreq has to be interpreted as the digits of
65 /// a scaled number with a scale of \p -ScaleShift.
66 uint32_t RelBlockFreq : 29;
67 static constexpr int32_t ScaleShift = 8;
68 static constexpr uint64_t MaxRelBlockFreq = (1 << 29) - 1;
69
70 CalleeInfo()
71 : Hotness(static_cast<uint32_t>(HotnessType::Unknown)), RelBlockFreq(0) {}
72 explicit CalleeInfo(HotnessType Hotness, uint64_t RelBF)
73 : Hotness(static_cast<uint32_t>(Hotness)), RelBlockFreq(RelBF) {}
74
75 void updateHotness(const HotnessType OtherHotness) {
76 Hotness = std::max(Hotness, static_cast<uint32_t>(OtherHotness));
77 }
78
79 HotnessType getHotness() const { return HotnessType(Hotness); }
80
81 /// Update \p RelBlockFreq from \p BlockFreq and \p EntryFreq
82 ///
83 /// BlockFreq is divided by EntryFreq and added to RelBlockFreq. To represent
84 /// fractional values, the result is represented as a fixed point number with
85 /// scale of -ScaleShift.
86 void updateRelBlockFreq(uint64_t BlockFreq, uint64_t EntryFreq) {
87 if (EntryFreq == 0)
88 return;
89 using Scaled64 = ScaledNumber<uint64_t>;
90 Scaled64 Temp(BlockFreq, ScaleShift);
91 Temp /= Scaled64::get(EntryFreq);
92
93 uint64_t Sum =
94 SaturatingAdd<uint64_t>(Temp.toInt<uint64_t>(), RelBlockFreq);
95 Sum = std::min(Sum, uint64_t(MaxRelBlockFreq));
96 RelBlockFreq = static_cast<uint32_t>(Sum);
97 }
98};
99
100class GlobalValueSummary;
101
102using GlobalValueSummaryList = std::vector<std::unique_ptr<GlobalValueSummary>>;
103
104struct GlobalValueSummaryInfo {
105 union NameOrGV {
106 NameOrGV(bool IsAnalysis) {
107 if (IsAnalysis)
108 GV = nullptr;
109 else
110 Name = "";
111 }
112
113 /// The GlobalValue corresponding to this summary. This is only used in
114 /// per-module summaries, when module analysis is being run.
115 const GlobalValue *GV;
116
117 /// Summary string representation. This StringRef points to BC module
118 /// string table and is valid until module data is stored in memory.
119 /// This is guaranteed to happen until runThinLTOBackend function is
120 /// called, so it is safe to use this field during thin link. This field
121 /// is only valid if summary index was loaded from BC file.
122 StringRef Name;
123 } U;
124
125 GlobalValueSummaryInfo(bool IsAnalysis) : U(IsAnalysis) {}
126
127 /// List of global value summary structures for a particular value held
128 /// in the GlobalValueMap. Requires a vector in the case of multiple
129 /// COMDAT values of the same name.
130 GlobalValueSummaryList SummaryList;
131};
132
133/// Map from global value GUID to corresponding summary structures. Use a
134/// std::map rather than a DenseMap so that pointers to the map's value_type
135/// (which are used by ValueInfo) are not invalidated by insertion. Also it will
136/// likely incur less overhead, as the value type is not very small and the size
137/// of the map is unknown, resulting in inefficiencies due to repeated
138/// insertions and resizing.
139using GlobalValueSummaryMapTy =
140 std::map<GlobalValue::GUID, GlobalValueSummaryInfo>;
141
142/// Struct that holds a reference to a particular GUID in a global value
143/// summary.
144struct ValueInfo {
145 PointerIntPair<const GlobalValueSummaryMapTy::value_type *, 1, bool>
146 RefAndFlag;
147
148 ValueInfo() = default;
149 ValueInfo(bool IsAnalysis, const GlobalValueSummaryMapTy::value_type *R) {
150 RefAndFlag.setPointer(R);
151 RefAndFlag.setInt(IsAnalysis);
152 }
153
154 operator bool() const { return getRef(); }
155
156 GlobalValue::GUID getGUID() const { return getRef()->first; }
157 const GlobalValue *getValue() const {
158 assert(isFromAnalysis());
159 return getRef()->second.U.GV;
160 }
161
162 ArrayRef<std::unique_ptr<GlobalValueSummary>> getSummaryList() const {
163 return getRef()->second.SummaryList;
164 }
165
166 StringRef name() const {
167 return isFromAnalysis() ? getRef()->second.U.GV->getName()
168 : getRef()->second.U.Name;
169 }
170
171 bool isFromAnalysis() const { return RefAndFlag.getInt(); }
172
173 const GlobalValueSummaryMapTy::value_type *getRef() const {
174 return RefAndFlag.getPointer();
175 }
176
177 bool isDSOLocal() const;
178};
179
180inline bool operator==(const ValueInfo &A, const ValueInfo &B) {
181 assert(A.getRef() && B.getRef() &&
182 "Need ValueInfo with non-null Ref to compare GUIDs");
183 return A.getRef() == B.getRef();
184}
185
186inline bool operator!=(const ValueInfo &A, const ValueInfo &B) {
187 assert(A.getRef() && B.getRef() &&
188 "Need ValueInfo with non-null Ref to compare GUIDs");
189 return A.getGUID() != B.getGUID();
190}
191
192inline bool operator<(const ValueInfo &A, const ValueInfo &B) {
193 assert(A.getRef() && B.getRef() &&
194 "Need ValueInfo with non-null Ref to compare GUIDs");
195 return A.getGUID() < B.getGUID();
196}
197
198template <> struct DenseMapInfo<ValueInfo> {
199 static inline ValueInfo getEmptyKey() {
200 return ValueInfo(false, (GlobalValueSummaryMapTy::value_type *)-8);
201 }
202
203 static inline ValueInfo getTombstoneKey() {
204 return ValueInfo(false, (GlobalValueSummaryMapTy::value_type *)-16);
205 }
206
207 static inline bool isSpecialKey(ValueInfo V) {
208 return V == getTombstoneKey() || V == getEmptyKey();
209 }
210
211 static bool isEqual(ValueInfo L, ValueInfo R) {
212 // We are not supposed to mix ValueInfo(s) with different analysis flag
213 // in a same container.
214 assert(isSpecialKey(L) || isSpecialKey(R) ||
215 (L.isFromAnalysis() == R.isFromAnalysis()));
216 return L.getRef() == R.getRef();
217 }
218 static unsigned getHashValue(ValueInfo I) { return (uintptr_t)I.getRef(); }
219};
220
221/// \brief Function and variable summary information to aid decisions and
222/// implementation of importing.
223class GlobalValueSummary {
224public:
225 /// \brief Sububclass discriminator (for dyn_cast<> et al.)
226 enum SummaryKind : unsigned { AliasKind, FunctionKind, GlobalVarKind };
227
228 /// Group flags (Linkage, NotEligibleToImport, etc.) as a bitfield.
229 struct GVFlags {
230 /// \brief The linkage type of the associated global value.
231 ///
232 /// One use is to flag values that have local linkage types and need to
233 /// have module identifier appended before placing into the combined
234 /// index, to disambiguate from other values with the same name.
235 /// In the future this will be used to update and optimize linkage
236 /// types based on global summary-based analysis.
237 unsigned Linkage : 4;
238
239 /// Indicate if the global value cannot be imported (e.g. it cannot
240 /// be renamed or references something that can't be renamed).
241 unsigned NotEligibleToImport : 1;
242
243 /// In per-module summary, indicate that the global value must be considered
244 /// a live root for index-based liveness analysis. Used for special LLVM
245 /// values such as llvm.global_ctors that the linker does not know about.
246 ///
247 /// In combined summary, indicate that the global value is live.
248 unsigned Live : 1;
249
250 /// Indicates that the linker resolved the symbol to a definition from
251 /// within the same linkage unit.
252 unsigned DSOLocal : 1;
253
254 /// Convenience Constructors
255 explicit GVFlags(GlobalValue::LinkageTypes Linkage,
256 bool NotEligibleToImport, bool Live, bool IsLocal)
257 : Linkage(Linkage), NotEligibleToImport(NotEligibleToImport),
258 Live(Live), DSOLocal(IsLocal) {}
259 };
260
261private:
262 /// Kind of summary for use in dyn_cast<> et al.
263 SummaryKind Kind;
264
265 GVFlags Flags;
266
267 /// This is the hash of the name of the symbol in the original file. It is
268 /// identical to the GUID for global symbols, but differs for local since the
269 /// GUID includes the module level id in the hash.
270 GlobalValue::GUID OriginalName = 0;
271
272 /// \brief Path of module IR containing value's definition, used to locate
273 /// module during importing.
274 ///
275 /// This is only used during parsing of the combined index, or when
276 /// parsing the per-module index for creation of the combined summary index,
277 /// not during writing of the per-module index which doesn't contain a
278 /// module path string table.
279 StringRef ModulePath;
280
281 /// List of values referenced by this global value's definition
282 /// (either by the initializer of a global variable, or referenced
283 /// from within a function). This does not include functions called, which
284 /// are listed in the derived FunctionSummary object.
285 std::vector<ValueInfo> RefEdgeList;
286
287protected:
288 GlobalValueSummary(SummaryKind K, GVFlags Flags, std::vector<ValueInfo> Refs)
289 : Kind(K), Flags(Flags), RefEdgeList(std::move(Refs)) {
290 assert((K != AliasKind || Refs.empty()) &&
291 "Expect no references for AliasSummary");
292 }
293
294public:
295 virtual ~GlobalValueSummary() = default;
296
297 /// Returns the hash of the original name, it is identical to the GUID for
298 /// externally visible symbols, but not for local ones.
299 GlobalValue::GUID getOriginalName() { return OriginalName; }
300
301 /// Initialize the original name hash in this summary.
302 void setOriginalName(GlobalValue::GUID Name) { OriginalName = Name; }
303
304 /// Which kind of summary subclass this is.
305 SummaryKind getSummaryKind() const { return Kind; }
306
307 /// Set the path to the module containing this function, for use in
308 /// the combined index.
309 void setModulePath(StringRef ModPath) { ModulePath = ModPath; }
310
311 /// Get the path to the module containing this function.
312 StringRef modulePath() const { return ModulePath; }
313
314 /// Get the flags for this GlobalValue (see \p struct GVFlags).
315 GVFlags flags() { return Flags; }
316
317 /// Return linkage type recorded for this global value.
318 GlobalValue::LinkageTypes linkage() const {
319 return static_cast<GlobalValue::LinkageTypes>(Flags.Linkage);
320 }
321
322 /// Sets the linkage to the value determined by global summary-based
323 /// optimization. Will be applied in the ThinLTO backends.
324 void setLinkage(GlobalValue::LinkageTypes Linkage) {
325 Flags.Linkage = Linkage;
326 }
327
328 /// Return true if this global value can't be imported.
329 bool notEligibleToImport() const { return Flags.NotEligibleToImport; }
330
331 bool isLive() const { return Flags.Live; }
332
333 void setLive(bool Live) { Flags.Live = Live; }
334
335 void setDSOLocal(bool Local) { Flags.DSOLocal = Local; }
336
337 bool isDSOLocal() const { return Flags.DSOLocal; }
338
339 /// Flag that this global value cannot be imported.
340 void setNotEligibleToImport() { Flags.NotEligibleToImport = true; }
341
342 /// Return the list of values referenced by this global value definition.
343 ArrayRef<ValueInfo> refs() const { return RefEdgeList; }
344
345 /// If this is an alias summary, returns the summary of the aliased object (a
346 /// global variable or function), otherwise returns itself.
347 GlobalValueSummary *getBaseObject();
348 const GlobalValueSummary *getBaseObject() const;
349
350 friend class ModuleSummaryIndex;
351};
352
353/// \brief Alias summary information.
354class AliasSummary : public GlobalValueSummary {
355 GlobalValueSummary *AliaseeSummary;
356 // AliaseeGUID is only set and accessed when we are building a combined index
357 // via the BitcodeReader.
358 GlobalValue::GUID AliaseeGUID;
359
360public:
361 AliasSummary(GVFlags Flags)
362 : GlobalValueSummary(AliasKind, Flags, ArrayRef<ValueInfo>{}),
363 AliaseeSummary(nullptr), AliaseeGUID(0) {}
364
365 /// Check if this is an alias summary.
366 static bool classof(const GlobalValueSummary *GVS) {
367 return GVS->getSummaryKind() == AliasKind;
368 }
369
370 void setAliasee(GlobalValueSummary *Aliasee) { AliaseeSummary = Aliasee; }
371 void setAliaseeGUID(GlobalValue::GUID GUID) { AliaseeGUID = GUID; }
372
373 const GlobalValueSummary &getAliasee() const {
374 assert(AliaseeSummary && "Unexpected missing aliasee summary");
375 return *AliaseeSummary;
376 }
377
378 GlobalValueSummary &getAliasee() {
379 return const_cast<GlobalValueSummary &>(
380 static_cast<const AliasSummary *>(this)->getAliasee());
381 }
382 const GlobalValue::GUID &getAliaseeGUID() const {
383 assert(AliaseeGUID && "Unexpected missing aliasee GUID");
384 return AliaseeGUID;
385 }
386};
387
388const inline GlobalValueSummary *GlobalValueSummary::getBaseObject() const {
389 if (auto *AS = dyn_cast<AliasSummary>(this))
390 return &AS->getAliasee();
391 return this;
392}
393
394inline GlobalValueSummary *GlobalValueSummary::getBaseObject() {
395 if (auto *AS = dyn_cast<AliasSummary>(this))
396 return &AS->getAliasee();
397 return this;
398}
399
400/// \brief Function summary information to aid decisions and implementation of
401/// importing.
402class FunctionSummary : public GlobalValueSummary {
403public:
404 /// <CalleeValueInfo, CalleeInfo> call edge pair.
405 using EdgeTy = std::pair<ValueInfo, CalleeInfo>;
406
407 /// An "identifier" for a virtual function. This contains the type identifier
408 /// represented as a GUID and the offset from the address point to the virtual
409 /// function pointer, where "address point" is as defined in the Itanium ABI:
410 /// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general
411 struct VFuncId {
412 GlobalValue::GUID GUID;
413 uint64_t Offset;
414 };
415
416 /// A specification for a virtual function call with all constant integer
417 /// arguments. This is used to perform virtual constant propagation on the
418 /// summary.
419 struct ConstVCall {
420 VFuncId VFunc;
421 std::vector<uint64_t> Args;
422 };
423
424 /// Function attribute flags. Used to track if a function accesses memory,
425 /// recurses or aliases.
426 struct FFlags {
427 unsigned ReadNone : 1;
428 unsigned ReadOnly : 1;
429 unsigned NoRecurse : 1;
430 unsigned ReturnDoesNotAlias : 1;
431 };
432
433 /// Create an empty FunctionSummary (with specified call edges).
434 /// Used to represent external nodes and the dummy root node.
435 static FunctionSummary
436 makeDummyFunctionSummary(std::vector<FunctionSummary::EdgeTy> Edges) {
437 return FunctionSummary(
438 FunctionSummary::GVFlags(
439 GlobalValue::LinkageTypes::AvailableExternallyLinkage,
440 /*NotEligibleToImport=*/true, /*Live=*/true, /*IsLocal=*/false),
441 0, FunctionSummary::FFlags{}, std::vector<ValueInfo>(),
442 std::move(Edges), std::vector<GlobalValue::GUID>(),
443 std::vector<FunctionSummary::VFuncId>(),
444 std::vector<FunctionSummary::VFuncId>(),
445 std::vector<FunctionSummary::ConstVCall>(),
446 std::vector<FunctionSummary::ConstVCall>());
447 }
448
449 /// A dummy node to reference external functions that aren't in the index
450 static FunctionSummary ExternalNode;
451
452private:
453 /// Number of instructions (ignoring debug instructions, e.g.) computed
454 /// during the initial compile step when the summary index is first built.
455 unsigned InstCount;
456
457 /// Function attribute flags. Used to track if a function accesses memory,
458 /// recurses or aliases.
459 FFlags FunFlags;
460
461 /// List of <CalleeValueInfo, CalleeInfo> call edge pairs from this function.
462 std::vector<EdgeTy> CallGraphEdgeList;
463
464 /// All type identifier related information. Because these fields are
465 /// relatively uncommon we only allocate space for them if necessary.
466 struct TypeIdInfo {
467 /// List of type identifiers used by this function in llvm.type.test
468 /// intrinsics other than by an llvm.assume intrinsic, represented as GUIDs.
469 std::vector<GlobalValue::GUID> TypeTests;
470
471 /// List of virtual calls made by this function using (respectively)
472 /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics that do
473 /// not have all constant integer arguments.
474 std::vector<VFuncId> TypeTestAssumeVCalls, TypeCheckedLoadVCalls;
475
476 /// List of virtual calls made by this function using (respectively)
477 /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics with
478 /// all constant integer arguments.
479 std::vector<ConstVCall> TypeTestAssumeConstVCalls,
480 TypeCheckedLoadConstVCalls;
481 };
482
483 std::unique_ptr<TypeIdInfo> TIdInfo;
484
485public:
486 FunctionSummary(GVFlags Flags, unsigned NumInsts, FFlags FunFlags,
487 std::vector<ValueInfo> Refs, std::vector<EdgeTy> CGEdges,
488 std::vector<GlobalValue::GUID> TypeTests,
489 std::vector<VFuncId> TypeTestAssumeVCalls,
490 std::vector<VFuncId> TypeCheckedLoadVCalls,
491 std::vector<ConstVCall> TypeTestAssumeConstVCalls,
492 std::vector<ConstVCall> TypeCheckedLoadConstVCalls)
493 : GlobalValueSummary(FunctionKind, Flags, std::move(Refs)),
494 InstCount(NumInsts), FunFlags(FunFlags),
495 CallGraphEdgeList(std::move(CGEdges)) {
496 if (!TypeTests.empty() || !TypeTestAssumeVCalls.empty() ||
497 !TypeCheckedLoadVCalls.empty() || !TypeTestAssumeConstVCalls.empty() ||
498 !TypeCheckedLoadConstVCalls.empty())
499 TIdInfo = llvm::make_unique<TypeIdInfo>(TypeIdInfo{
500 std::move(TypeTests), std::move(TypeTestAssumeVCalls),
501 std::move(TypeCheckedLoadVCalls),
502 std::move(TypeTestAssumeConstVCalls),
503 std::move(TypeCheckedLoadConstVCalls)});
504 }
505
506 /// Check if this is a function summary.
507 static bool classof(const GlobalValueSummary *GVS) {
508 return GVS->getSummaryKind() == FunctionKind;
509 }
510
511 /// Get function attribute flags.
512 FFlags &fflags() { return FunFlags; }
513
514 /// Get the instruction count recorded for this function.
515 unsigned instCount() const { return InstCount; }
516
517 /// Return the list of <CalleeValueInfo, CalleeInfo> pairs.
518 ArrayRef<EdgeTy> calls() const { return CallGraphEdgeList; }
519
520 /// Returns the list of type identifiers used by this function in
521 /// llvm.type.test intrinsics other than by an llvm.assume intrinsic,
522 /// represented as GUIDs.
523 ArrayRef<GlobalValue::GUID> type_tests() const {
524 if (TIdInfo)
525 return TIdInfo->TypeTests;
526 return {};
527 }
528
529 /// Returns the list of virtual calls made by this function using
530 /// llvm.assume(llvm.type.test) intrinsics that do not have all constant
531 /// integer arguments.
532 ArrayRef<VFuncId> type_test_assume_vcalls() const {
533 if (TIdInfo)
534 return TIdInfo->TypeTestAssumeVCalls;
535 return {};
536 }
537
538 /// Returns the list of virtual calls made by this function using
539 /// llvm.type.checked.load intrinsics that do not have all constant integer
540 /// arguments.
541 ArrayRef<VFuncId> type_checked_load_vcalls() const {
542 if (TIdInfo)
543 return TIdInfo->TypeCheckedLoadVCalls;
544 return {};
545 }
546
547 /// Returns the list of virtual calls made by this function using
548 /// llvm.assume(llvm.type.test) intrinsics with all constant integer
549 /// arguments.
550 ArrayRef<ConstVCall> type_test_assume_const_vcalls() const {
551 if (TIdInfo)
552 return TIdInfo->TypeTestAssumeConstVCalls;
553 return {};
554 }
555
556 /// Returns the list of virtual calls made by this function using
557 /// llvm.type.checked.load intrinsics with all constant integer arguments.
558 ArrayRef<ConstVCall> type_checked_load_const_vcalls() const {
559 if (TIdInfo)
560 return TIdInfo->TypeCheckedLoadConstVCalls;
561 return {};
562 }
563
564 /// Add a type test to the summary. This is used by WholeProgramDevirt if we
565 /// were unable to devirtualize a checked call.
566 void addTypeTest(GlobalValue::GUID Guid) {
567 if (!TIdInfo)
568 TIdInfo = llvm::make_unique<TypeIdInfo>();
569 TIdInfo->TypeTests.push_back(Guid);
570 }
571
572 friend struct GraphTraits<ValueInfo>;
573};
574
575template <> struct DenseMapInfo<FunctionSummary::VFuncId> {
576 static FunctionSummary::VFuncId getEmptyKey() { return {0, uint64_t(-1)}; }
577
578 static FunctionSummary::VFuncId getTombstoneKey() {
579 return {0, uint64_t(-2)};
580 }
581
582 static bool isEqual(FunctionSummary::VFuncId L, FunctionSummary::VFuncId R) {
583 return L.GUID == R.GUID && L.Offset == R.Offset;
584 }
585
586 static unsigned getHashValue(FunctionSummary::VFuncId I) { return I.GUID; }
587};
588
589template <> struct DenseMapInfo<FunctionSummary::ConstVCall> {
590 static FunctionSummary::ConstVCall getEmptyKey() {
591 return {{0, uint64_t(-1)}, {}};
592 }
593
594 static FunctionSummary::ConstVCall getTombstoneKey() {
595 return {{0, uint64_t(-2)}, {}};
596 }
597
598 static bool isEqual(FunctionSummary::ConstVCall L,
599 FunctionSummary::ConstVCall R) {
600 return DenseMapInfo<FunctionSummary::VFuncId>::isEqual(L.VFunc, R.VFunc) &&
601 L.Args == R.Args;
602 }
603
604 static unsigned getHashValue(FunctionSummary::ConstVCall I) {
605 return I.VFunc.GUID;
606 }
607};
608
609/// \brief Global variable summary information to aid decisions and
610/// implementation of importing.
611///
612/// Currently this doesn't add anything to the base \p GlobalValueSummary,
613/// but is a placeholder as additional info may be added to the summary
614/// for variables.
615class GlobalVarSummary : public GlobalValueSummary {
616
617public:
618 GlobalVarSummary(GVFlags Flags, std::vector<ValueInfo> Refs)
619 : GlobalValueSummary(GlobalVarKind, Flags, std::move(Refs)) {}
620
621 /// Check if this is a global variable summary.
622 static bool classof(const GlobalValueSummary *GVS) {
623 return GVS->getSummaryKind() == GlobalVarKind;
624 }
625};
626
627struct TypeTestResolution {
628 /// Specifies which kind of type check we should emit for this byte array.
629 /// See http://clang.llvm.org/docs/ControlFlowIntegrityDesign.html for full
630 /// details on each kind of check; the enumerators are described with
631 /// reference to that document.
632 enum Kind {
633 Unsat, ///< Unsatisfiable type (i.e. no global has this type metadata)
634 ByteArray, ///< Test a byte array (first example)
635 Inline, ///< Inlined bit vector ("Short Inline Bit Vectors")
636 Single, ///< Single element (last example in "Short Inline Bit Vectors")
637 AllOnes, ///< All-ones bit vector ("Eliminating Bit Vector Checks for
638 /// All-Ones Bit Vectors")
639 } TheKind = Unsat;
640
641 /// Range of size-1 expressed as a bit width. For example, if the size is in
642 /// range [1,256], this number will be 8. This helps generate the most compact
643 /// instruction sequences.
644 unsigned SizeM1BitWidth = 0;
645
646 // The following fields are only used if the target does not support the use
647 // of absolute symbols to store constants. Their meanings are the same as the
648 // corresponding fields in LowerTypeTestsModule::TypeIdLowering in
649 // LowerTypeTests.cpp.
650
651 uint64_t AlignLog2 = 0;
652 uint64_t SizeM1 = 0;
653 uint8_t BitMask = 0;
654 uint64_t InlineBits = 0;
655};
656
657struct WholeProgramDevirtResolution {
658 enum Kind {
659 Indir, ///< Just do a regular virtual call
660 SingleImpl, ///< Single implementation devirtualization
661 BranchFunnel, ///< When retpoline mitigation is enabled, use a branch funnel
662 ///< that is defined in the merged module. Otherwise same as
663 ///< Indir.
664 } TheKind = Indir;
665
666 std::string SingleImplName;
667
668 struct ByArg {
669 enum Kind {
670 Indir, ///< Just do a regular virtual call
671 UniformRetVal, ///< Uniform return value optimization
672 UniqueRetVal, ///< Unique return value optimization
673 VirtualConstProp, ///< Virtual constant propagation
674 } TheKind = Indir;
675
676 /// Additional information for the resolution:
677 /// - UniformRetVal: the uniform return value.
678 /// - UniqueRetVal: the return value associated with the unique vtable (0 or
679 /// 1).
680 uint64_t Info = 0;
681
682 // The following fields are only used if the target does not support the use
683 // of absolute symbols to store constants.
684
685 uint32_t Byte = 0;
686 uint32_t Bit = 0;
687 };
688
689 /// Resolutions for calls with all constant integer arguments (excluding the
690 /// first argument, "this"), where the key is the argument vector.
691 std::map<std::vector<uint64_t>, ByArg> ResByArg;
692};
693
694struct TypeIdSummary {
695 TypeTestResolution TTRes;
696
697 /// Mapping from byte offset to whole-program devirt resolution for that
698 /// (typeid, byte offset) pair.
699 std::map<uint64_t, WholeProgramDevirtResolution> WPDRes;
700};
701
702/// 160 bits SHA1
703using ModuleHash = std::array<uint32_t, 5>;
704
705/// Type used for iterating through the global value summary map.
706using const_gvsummary_iterator = GlobalValueSummaryMapTy::const_iterator;
707using gvsummary_iterator = GlobalValueSummaryMapTy::iterator;
708
709/// String table to hold/own module path strings, which additionally holds the
710/// module ID assigned to each module during the plugin step, as well as a hash
711/// of the module. The StringMap makes a copy of and owns inserted strings.
712using ModulePathStringTableTy = StringMap<std::pair<uint64_t, ModuleHash>>;
713
714/// Map of global value GUID to its summary, used to identify values defined in
715/// a particular module, and provide efficient access to their summary.
716using GVSummaryMapTy = DenseMap<GlobalValue::GUID, GlobalValueSummary *>;
717
718/// Class to hold module path string table and global value map,
719/// and encapsulate methods for operating on them.
720class ModuleSummaryIndex {
721private:
722 /// Map from value name to list of summary instances for values of that
723 /// name (may be duplicates in the COMDAT case, e.g.).
724 GlobalValueSummaryMapTy GlobalValueMap;
725
726 /// Holds strings for combined index, mapping to the corresponding module ID.
727 ModulePathStringTableTy ModulePathStringTable;
728
729 /// Mapping from type identifiers to summary information for that type
730 /// identifier.
731 std::map<std::string, TypeIdSummary> TypeIdMap;
732
733 /// Mapping from original ID to GUID. If original ID can map to multiple
734 /// GUIDs, it will be mapped to 0.
735 std::map<GlobalValue::GUID, GlobalValue::GUID> OidGuidMap;
736
737 /// Indicates that summary-based GlobalValue GC has run, and values with
738 /// GVFlags::Live==false are really dead. Otherwise, all values must be
739 /// considered live.
740 bool WithGlobalValueDeadStripping = false;
741
742 /// Indicates that distributed backend should skip compilation of the
743 /// module. Flag is suppose to be set by distributed ThinLTO indexing
744 /// when it detected that the module is not needed during the final
745 /// linking. As result distributed backend should just output a minimal
746 /// valid object file.
747 bool SkipModuleByDistributedBackend = false;
748
749 /// If true then we're performing analysis of IR module, filling summary
750 /// accordingly. The value of 'false' means we're reading summary from
751 /// BC or YAML source. Affects the type of value stored in NameOrGV union
752 bool IsAnalysis;
753
754 std::set<std::string> CfiFunctionDefs;
755 std::set<std::string> CfiFunctionDecls;
756
757 // YAML I/O support.
758 friend yaml::MappingTraits<ModuleSummaryIndex>;
759
760 GlobalValueSummaryMapTy::value_type *
761 getOrInsertValuePtr(GlobalValue::GUID GUID) {
762 return &*GlobalValueMap.emplace(GUID, GlobalValueSummaryInfo(IsAnalysis)).first;
763 }
764
765public:
766 // See IsAnalysis variable comment.
767 ModuleSummaryIndex(bool IsPerformingAnalysis)
768 : IsAnalysis(IsPerformingAnalysis) {}
769
770 bool isPerformingAnalysis() const { return IsAnalysis; }
771
772 gvsummary_iterator begin() { return GlobalValueMap.begin(); }
773 const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); }
774 gvsummary_iterator end() { return GlobalValueMap.end(); }
775 const_gvsummary_iterator end() const { return GlobalValueMap.end(); }
776 size_t size() const { return GlobalValueMap.size(); }
777
778 /// Convenience function for doing a DFS on a ValueInfo. Marks the function in
779 /// the FunctionHasParent map.
780 static void discoverNodes(ValueInfo V,
781 std::map<ValueInfo, bool> &FunctionHasParent) {
782 if (!V.getSummaryList().size())
783 return; // skip external functions that don't have summaries
784
785 // Mark discovered if we haven't yet
786 auto S = FunctionHasParent.emplace(V, false);
787
788 // Stop if we've already discovered this node
789 if (!S.second)
790 return;
791
792 FunctionSummary *F =
793 dyn_cast<FunctionSummary>(V.getSummaryList().front().get());
794 assert(F != nullptr && "Expected FunctionSummary node");
795
796 for (auto &C : F->calls()) {
797 // Insert node if necessary
798 auto S = FunctionHasParent.emplace(C.first, true);
799
800 // Skip nodes that we're sure have parents
801 if (!S.second && S.first->second)
802 continue;
803
804 if (S.second)
805 discoverNodes(C.first, FunctionHasParent);
806 else
807 S.first->second = true;
808 }
809 }
810
811 // Calculate the callgraph root
812 FunctionSummary calculateCallGraphRoot() {
813 // Functions that have a parent will be marked in FunctionHasParent pair.
814 // Once we've marked all functions, the functions in the map that are false
815 // have no parent (so they're the roots)
816 std::map<ValueInfo, bool> FunctionHasParent;
817
818 for (auto &S : *this) {
819 // Skip external functions
820 if (!S.second.SummaryList.size() ||
821 !isa<FunctionSummary>(S.second.SummaryList.front().get()))
822 continue;
823 discoverNodes(ValueInfo(IsAnalysis, &S), FunctionHasParent);
824 }
825
826 std::vector<FunctionSummary::EdgeTy> Edges;
827 // create edges to all roots in the Index
828 for (auto &P : FunctionHasParent) {
829 if (P.second)
830 continue; // skip over non-root nodes
831 Edges.push_back(std::make_pair(P.first, CalleeInfo{}));
832 }
833 if (Edges.empty()) {
834 // Failed to find root - return an empty node
835 return FunctionSummary::makeDummyFunctionSummary({});
836 }
837 auto CallGraphRoot = FunctionSummary::makeDummyFunctionSummary(Edges);
838 return CallGraphRoot;
839 }
840
841 bool withGlobalValueDeadStripping() const {
842 return WithGlobalValueDeadStripping;
843 }
844 void setWithGlobalValueDeadStripping() {
845 WithGlobalValueDeadStripping = true;
846 }
847
848 bool skipModuleByDistributedBackend() const {
849 return SkipModuleByDistributedBackend;
850 }
851 void setSkipModuleByDistributedBackend() {
852 SkipModuleByDistributedBackend = true;
853 }
854
855 bool isGlobalValueLive(const GlobalValueSummary *GVS) const {
856 return !WithGlobalValueDeadStripping || GVS->isLive();
857 }
858 bool isGUIDLive(GlobalValue::GUID GUID) const;
859
860 /// Return a ValueInfo for GUID if it exists, otherwise return ValueInfo().
861 ValueInfo getValueInfo(GlobalValue::GUID GUID) const {
862 auto I = GlobalValueMap.find(GUID);
863 return ValueInfo(IsAnalysis, I == GlobalValueMap.end() ? nullptr : &*I);
864 }
865
866 /// Return a ValueInfo for \p GUID.
867 ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID) {
868 return ValueInfo(IsAnalysis, getOrInsertValuePtr(GUID));
869 }
870
871 /// Return a ValueInfo for \p GUID setting value \p Name.
872 ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID, StringRef Name) {
873 assert(!IsAnalysis);
874 auto VP = getOrInsertValuePtr(GUID);
875 VP->second.U.Name = Name;
876 return ValueInfo(IsAnalysis, VP);
877 }
878
879 /// Return a ValueInfo for \p GV and mark it as belonging to GV.
880 ValueInfo getOrInsertValueInfo(const GlobalValue *GV) {
881 assert(IsAnalysis);
882 auto VP = getOrInsertValuePtr(GV->getGUID());
883 VP->second.U.GV = GV;
884 return ValueInfo(IsAnalysis, VP);
885 }
886
887 /// Return the GUID for \p OriginalId in the OidGuidMap.
888 GlobalValue::GUID getGUIDFromOriginalID(GlobalValue::GUID OriginalID) const {
889 const auto I = OidGuidMap.find(OriginalID);
890 return I == OidGuidMap.end() ? 0 : I->second;
891 }
892
893 std::set<std::string> &cfiFunctionDefs() { return CfiFunctionDefs; }
894 const std::set<std::string> &cfiFunctionDefs() const { return CfiFunctionDefs; }
895
896 std::set<std::string> &cfiFunctionDecls() { return CfiFunctionDecls; }
897 const std::set<std::string> &cfiFunctionDecls() const { return CfiFunctionDecls; }
898
899 /// Add a global value summary for a value of the given name.
900 void addGlobalValueSummary(StringRef ValueName,
901 std::unique_ptr<GlobalValueSummary> Summary) {
902 addGlobalValueSummary(getOrInsertValueInfo(GlobalValue::getGUID(ValueName)),
903 std::move(Summary));
904 }
905
906 /// Add a global value summary for the given ValueInfo.
907 void addGlobalValueSummary(ValueInfo VI,
908 std::unique_ptr<GlobalValueSummary> Summary) {
909 addOriginalName(VI.getGUID(), Summary->getOriginalName());
910 // Here we have a notionally const VI, but the value it points to is owned
911 // by the non-const *this.
912 const_cast<GlobalValueSummaryMapTy::value_type *>(VI.getRef())
913 ->second.SummaryList.push_back(std::move(Summary));
914 }
915
916 /// Add an original name for the value of the given GUID.
917 void addOriginalName(GlobalValue::GUID ValueGUID,
918 GlobalValue::GUID OrigGUID) {
919 if (OrigGUID == 0 || ValueGUID == OrigGUID)
920 return;
921 if (OidGuidMap.count(OrigGUID) && OidGuidMap[OrigGUID] != ValueGUID)
922 OidGuidMap[OrigGUID] = 0;
923 else
924 OidGuidMap[OrigGUID] = ValueGUID;
925 }
926
927 /// Find the summary for global \p GUID in module \p ModuleId, or nullptr if
928 /// not found.
929 GlobalValueSummary *findSummaryInModule(GlobalValue::GUID ValueGUID,
930 StringRef ModuleId) const {
931 auto CalleeInfo = getValueInfo(ValueGUID);
932 if (!CalleeInfo) {
933 return nullptr; // This function does not have a summary
934 }
935 auto Summary =
936 llvm::find_if(CalleeInfo.getSummaryList(),
937 [&](const std::unique_ptr<GlobalValueSummary> &Summary) {
938 return Summary->modulePath() == ModuleId;
939 });
940 if (Summary == CalleeInfo.getSummaryList().end())
941 return nullptr;
942 return Summary->get();
943 }
944
945 /// Returns the first GlobalValueSummary for \p GV, asserting that there
946 /// is only one if \p PerModuleIndex.
947 GlobalValueSummary *getGlobalValueSummary(const GlobalValue &GV,
948 bool PerModuleIndex = true) const {
949 assert(GV.hasName() && "Can't get GlobalValueSummary for GV with no name");
950 return getGlobalValueSummary(GlobalValue::getGUID(GV.getName()),
951 PerModuleIndex);
952 }
953
954 /// Returns the first GlobalValueSummary for \p ValueGUID, asserting that
955 /// there
956 /// is only one if \p PerModuleIndex.
957 GlobalValueSummary *getGlobalValueSummary(GlobalValue::GUID ValueGUID,
958 bool PerModuleIndex = true) const;
959
960 /// Table of modules, containing module hash and id.
961 const StringMap<std::pair<uint64_t, ModuleHash>> &modulePaths() const {
962 return ModulePathStringTable;
963 }
964
965 /// Table of modules, containing hash and id.
966 StringMap<std::pair<uint64_t, ModuleHash>> &modulePaths() {
967 return ModulePathStringTable;
968 }
969
970 /// Get the module ID recorded for the given module path.
971 uint64_t getModuleId(const StringRef ModPath) const {
972 return ModulePathStringTable.lookup(ModPath).first;
973 }
974
975 /// Get the module SHA1 hash recorded for the given module path.
976 const ModuleHash &getModuleHash(const StringRef ModPath) const {
977 auto It = ModulePathStringTable.find(ModPath);
978 assert(It != ModulePathStringTable.end() && "Module not registered");
979 return It->second.second;
980 }
981
982 /// Convenience method for creating a promoted global name
983 /// for the given value name of a local, and its original module's ID.
984 static std::string getGlobalNameForLocal(StringRef Name, ModuleHash ModHash) {
985 SmallString<256> NewName(Name);
986 NewName += ".llvm.";
987 NewName += utostr((uint64_t(ModHash[0]) << 32) |
988 ModHash[1]); // Take the first 64 bits
989 return NewName.str();
990 }
991
992 /// Helper to obtain the unpromoted name for a global value (or the original
993 /// name if not promoted).
994 static StringRef getOriginalNameBeforePromote(StringRef Name) {
995 std::pair<StringRef, StringRef> Pair = Name.split(".llvm.");
996 return Pair.first;
997 }
998
999 typedef ModulePathStringTableTy::value_type ModuleInfo;
1000
1001 /// Add a new module with the given \p Hash, mapped to the given \p
1002 /// ModID, and return a reference to the module.
1003 ModuleInfo *addModule(StringRef ModPath, uint64_t ModId,
1004 ModuleHash Hash = ModuleHash{{0}}) {
1005 return &*ModulePathStringTable.insert({ModPath, {ModId, Hash}}).first;
1006 }
1007
1008 /// Check if the given Module has any functions available for exporting
1009 /// in the index. We consider any module present in the ModulePathStringTable
1010 /// to have exported functions.
1011 bool hasExportedFunctions(const Module &M) const {
1012 return ModulePathStringTable.count(M.getModuleIdentifier());
1013 }
1014
1015 const std::map<std::string, TypeIdSummary> &typeIds() const {
1016 return TypeIdMap;
1017 }
1018
1019 /// This accessor should only be used when exporting because it can mutate the
1020 /// map.
1021 TypeIdSummary &getOrInsertTypeIdSummary(StringRef TypeId) {
1022 return TypeIdMap[TypeId];
1023 }
1024
1025 /// This returns either a pointer to the type id summary (if present in the
1026 /// summary map) or null (if not present). This may be used when importing.
1027 const TypeIdSummary *getTypeIdSummary(StringRef TypeId) const {
1028 auto I = TypeIdMap.find(TypeId);
1029 if (I == TypeIdMap.end())
1030 return nullptr;
1031 return &I->second;
1032 }
1033
1034 /// Collect for the given module the list of function it defines
1035 /// (GUID -> Summary).
1036 void collectDefinedFunctionsForModule(StringRef ModulePath,
1037 GVSummaryMapTy &GVSummaryMap) const;
1038
1039 /// Collect for each module the list of Summaries it defines (GUID ->
1040 /// Summary).
1041 void collectDefinedGVSummariesPerModule(
1042 StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) const;
1043
1044 /// Export summary to dot file for GraphViz.
1045 void exportToDot(raw_ostream& OS) const;
1046
1047 /// Print out strongly connected components for debugging.
1048 void dumpSCCs(raw_ostream &OS);
1049};
1050
1051/// GraphTraits definition to build SCC for the index
1052template <> struct GraphTraits<ValueInfo> {
1053 typedef ValueInfo NodeRef;
1054
1055 static NodeRef valueInfoFromEdge(FunctionSummary::EdgeTy &P) {
1056 return P.first;
1057 }
1058 using ChildIteratorType =
1059 mapped_iterator<std::vector<FunctionSummary::EdgeTy>::iterator,
1060 decltype(&valueInfoFromEdge)>;
1061
1062 static NodeRef getEntryNode(ValueInfo V) { return V; }
1063
1064 static ChildIteratorType child_begin(NodeRef N) {
1065 if (!N.getSummaryList().size()) // handle external function
1066 return ChildIteratorType(
1067 FunctionSummary::ExternalNode.CallGraphEdgeList.begin(),
1068 &valueInfoFromEdge);
1069 FunctionSummary *F =
1070 cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject());
1071 return ChildIteratorType(F->CallGraphEdgeList.begin(), &valueInfoFromEdge);
1072 }
1073
1074 static ChildIteratorType child_end(NodeRef N) {
1075 if (!N.getSummaryList().size()) // handle external function
1076 return ChildIteratorType(
1077 FunctionSummary::ExternalNode.CallGraphEdgeList.end(),
1078 &valueInfoFromEdge);
1079 FunctionSummary *F =
1080 cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject());
1081 return ChildIteratorType(F->CallGraphEdgeList.end(), &valueInfoFromEdge);
1082 }
1083};
1084
1085template <>
1086struct GraphTraits<ModuleSummaryIndex *> : public GraphTraits<ValueInfo> {
1087 static NodeRef getEntryNode(ModuleSummaryIndex *I) {
1088 std::unique_ptr<GlobalValueSummary> Root =
1089 make_unique<FunctionSummary>(I->calculateCallGraphRoot());
1090 GlobalValueSummaryInfo G(I->isPerformingAnalysis());
1091 G.SummaryList.push_back(std::move(Root));
1092 static auto P =
1093 GlobalValueSummaryMapTy::value_type(GlobalValue::GUID(0), std::move(G));
1094 return ValueInfo(I->isPerformingAnalysis(), &P);
1095 }
1096};
1097
1098} // end namespace llvm
1099
1100#endif // LLVM_IR_MODULESUMMARYINDEX_H