LLVM 23.0.0git
TypePool.h
Go to the documentation of this file.
1//===- TypePool.h -----------------------------------------------*- 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_DWARFLINKER_PARALLEL_TYPEPOOL_H
10#define LLVM_DWARFLINKER_PARALLEL_TYPEPOOL_H
11
12#include "ArrayList.h"
14#include "llvm/ADT/StringMap.h"
15#include "llvm/CodeGen/DIE.h"
17#include <atomic>
18#include <limits>
19
20namespace llvm {
21namespace dwarf_linker {
22namespace parallel {
23
24class TypePool;
25class CompileUnit;
26class TypeEntryBody;
27
29
30/// Keeps cloned data for the type DIE.
32public:
33 /// Returns copy of type DIE which should be emitted into resulting file.
34 DIE &getFinalDie() const {
35 if (Die)
36 return *Die;
37
39 return *DeclarationDie;
40 }
41
42 /// Returns true if type die entry has only declaration die.
43 bool hasOnlyDeclaration() const { return Die == nullptr; }
44
45 /// Creates type DIE for the specified name.
46 static TypeEntryBody *
48 TypeEntryBody *Result = Allocator.Allocate<TypeEntryBody>();
49 new (Result) TypeEntryBody(Allocator);
50 return Result;
51 }
52
53 /// TypeEntryBody keeps partially cloned DIEs corresponding to this type.
54 /// The two kinds of DIE can be kept: declaration and definition.
55 /// If definition DIE was met while parsing input DWARF then this DIE would
56 /// be used as a final DIE for this type. If definition DIE is not met then
57 /// declaration DIE would be used as a final DIE.
58
59 // Keeps definition die.
60 std::atomic<DIE *> Die = {nullptr};
61
62 // Keeps declaration die.
63 std::atomic<DIE *> DeclarationDie = {nullptr};
64
65 // True if the declaration winner's parent is itself a declaration.
67
68 // Priority of the CU that set Die (lower wins, for deterministic output).
69 // Atomic so it can be read outside the lock for a fast pre-check; the
70 // definitive comparison still happens under the spinlock.
71 std::atomic<uint64_t> DiePriority = {std::numeric_limits<uint64_t>::max()};
72
73 // Priority of the CU that set DeclarationDie (lower wins).
74 uint64_t DeclarationDiePriority = std::numeric_limits<uint64_t>::max();
75
76 // Spinlock for deterministic type DIE allocation.
77 std::atomic_flag Lock = {};
78
79 /// Children for current type.
81
82protected:
83 TypeEntryBody() = delete;
88
91};
92
94public:
95 /// \returns Hash value for the specified \p Key.
96 static inline uint64_t getHashValue(const StringRef &Key) {
97 return xxh3_64bits(Key);
98 }
99
100 /// \returns true if both \p LHS and \p RHS are equal.
101 static inline bool isEqual(const StringRef &LHS, const StringRef &RHS) {
102 return LHS == RHS;
103 }
104
105 /// \returns key for the specified \p KeyData.
106 static inline StringRef getKey(const TypeEntry &KeyData) {
107 return KeyData.getKey();
108 }
109
110 /// \returns newly created object of KeyDataTy type.
111 static inline TypeEntry *
116};
117
118/// TypePool keeps type descriptors which contain partially cloned DIE
119/// correspinding to each type. Types are identified by names.
121 : ConcurrentHashTableByPtr<StringRef, TypeEntry,
122 llvm::parallel::PerThreadBumpPtrAllocator,
123 TypeEntryInfo> {
124public:
127 llvm::parallel::PerThreadBumpPtrAllocator,
128 TypeEntryInfo>(Allocator) {
129 Root = TypeEntry::create("", Allocator);
130 Root->getValue().store(TypeEntryBody::create(Allocator));
131 }
132
139
140 /// Create or return existing type entry body for the specified \p Entry.
141 /// Link that entry as child for the specified \p ParentEntry.
142 /// \returns The existing or created type entry body.
144 TypeEntry *ParentEntry) {
145 TypeEntryBody *DIE = Entry->getValue().load();
146 if (DIE)
147 return DIE;
148
149 TypeEntryBody *NewDIE = TypeEntryBody::create(Allocator);
150 if (Entry->getValue().compare_exchange_strong(DIE, NewDIE)) {
151 ParentEntry->getValue().load()->Children.add(Entry);
152 return NewDIE;
153 }
154
155 return DIE;
156 }
157
158 /// Sort children for each kept type entry.
159 void sortTypes() {
160 std::function<void(TypeEntry * Entry)> SortChildrenRec =
161 [&](TypeEntry *Entry) {
162 Entry->getValue().load()->Children.sort(TypesComparator);
163 Entry->getValue().load()->Children.forEach(SortChildrenRec);
164 };
165
166 SortChildrenRec(getRoot());
167 }
168
169 /// Return root for all type entries.
170 TypeEntry *getRoot() const { return Root; }
171
172 /// Return thread local allocator used by pool.
174 return Allocator.getThreadLocalAllocator();
175 }
176
177protected:
178 std::function<bool(const TypeEntry *LHS, const TypeEntry *RHS)>
179 TypesComparator = [](const TypeEntry *LHS, const TypeEntry *RHS) -> bool {
180 return LHS->getKey() < RHS->getKey();
181 };
182
183 // Root of all type entries.
184 TypeEntry *Root = nullptr;
185
186private:
188};
189
190} // end of namespace parallel
191} // end of namespace dwarf_linker
192} // end of namespace llvm
193
194#endif // LLVM_DWARFLINKER_PARALLEL_TYPEPOOL_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
This file defines the BumpPtrAllocator interface.
Basic Register Allocator
Value * RHS
Value * LHS
ConcurrentHashTableByPtr(llvm::parallel::PerThreadBumpPtrAllocator &Allocator, uint64_t EstimatedSize=100000, size_t ThreadsNum=parallel::strategy.compute_thread_count(), size_t InitialNumberOfBuckets=128)
A structured debug information entry.
Definition DIE.h:828
const ValueTy & getValue() const
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
static StringMapEntry * create(StringRef key, AllocatorTy &allocator, InitTy &&...initVals)
StringRef getKey() const
StringRef first() const
Represent a constant reference to a string, i.e.
Definition StringRef.h:55
This class is a simple list of T structures.
Definition ArrayList.h:23
Stores all information related to a compile unit, be it in its original instance of the object file o...
Keeps cloned data for the type DIE.
Definition TypePool.h:31
ArrayList< TypeEntry *, 5 > Children
Children for current type.
Definition TypePool.h:80
DIE & getFinalDie() const
Returns copy of type DIE which should be emitted into resulting file.
Definition TypePool.h:34
TypeEntryBody(TypeEntryBody &&RHS)=delete
bool hasOnlyDeclaration() const
Returns true if type die entry has only declaration die.
Definition TypePool.h:43
TypeEntryBody(const TypeEntryBody &RHS)=delete
TypeEntryBody(llvm::parallel::PerThreadBumpPtrAllocator &Allocator)
Definition TypePool.h:89
TypeEntryBody & operator=(const TypeEntryBody &RHS)=delete
std::atomic< DIE * > Die
TypeEntryBody keeps partially cloned DIEs corresponding to this type.
Definition TypePool.h:60
std::atomic< uint64_t > DiePriority
Definition TypePool.h:71
static TypeEntryBody * create(llvm::parallel::PerThreadBumpPtrAllocator &Allocator)
Creates type DIE for the specified name.
Definition TypePool.h:47
TypeEntryBody & operator=(const TypeEntryBody &&RHS)=delete
static bool isEqual(const StringRef &LHS, const StringRef &RHS)
Definition TypePool.h:101
static TypeEntry * create(const StringRef &Key, llvm::parallel::PerThreadBumpPtrAllocator &Allocator)
Definition TypePool.h:112
static uint64_t getHashValue(const StringRef &Key)
Definition TypePool.h:96
static StringRef getKey(const TypeEntry &KeyData)
Definition TypePool.h:106
TypePool keeps type descriptors which contain partially cloned DIE correspinding to each type.
Definition TypePool.h:123
BumpPtrAllocator & getThreadLocalAllocator()
Return thread local allocator used by pool.
Definition TypePool.h:173
TypeEntryBody * getOrCreateTypeEntryBody(TypeEntry *Entry, TypeEntry *ParentEntry)
Create or return existing type entry body for the specified Entry.
Definition TypePool.h:143
TypeEntry * insert(StringRef Name)
Definition TypePool.h:133
TypeEntry * getRoot() const
Return root for all type entries.
Definition TypePool.h:170
std::function< bool(const TypeEntry *LHS, const TypeEntry *RHS)> TypesComparator
Definition TypePool.h:179
void sortTypes()
Sort children for each kept type entry.
Definition TypePool.h:159
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
Definition TypePool.h:28
PerThreadAllocator< BumpPtrAllocator > PerThreadBumpPtrAllocator
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI uint64_t xxh3_64bits(ArrayRef< uint8_t > data)
Definition xxhash.cpp:553
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383