llvm.org GIT mirror llvm / d9b2071
Make the StructType->StructLayout table private to TargetData, allowing us to avoid locking on it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79555 91177308-0d34-0410-b5e6-96231b3b80d8 Owen Anderson 10 years ago
2 changed file(s) with 45 addition(s) and 67 deletion(s). Raw diff Collapse all Expand all
9090 */
9191 static const TargetAlignElem InvalidAlignmentElem;
9292
93 /// Opaque pointer for the StructType -> StructLayout map
94 void* LayoutMap;
95
9396 //! Set/initialize target alignments
9497 void setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
9598 unsigned char pref_align, uint32_t bit_width);
106109 return (&align != &InvalidAlignmentElem);
107110 }
108111
112 // DO NOT IMPLEMENT
113 void operator=(const TargetData&);
114
109115 public:
110116 /// Default ctor.
111117 ///
117123 }
118124
119125 /// Constructs a TargetData from a specification string. See init().
120 explicit TargetData(const std::string &TargetDescription)
121 : ImmutablePass(&ID) {
122 init(TargetDescription);
123 }
126 explicit TargetData(const std::string &TargetDescription);
124127
125128 /// Initialize target data from properties stored in the module.
126129 explicit TargetData(const Module *M);
127
128 TargetData(const TargetData &TD) :
129 ImmutablePass(&ID),
130 LittleEndian(TD.isLittleEndian()),
131 PointerMemSize(TD.PointerMemSize),
132 PointerABIAlign(TD.PointerABIAlign),
133 PointerPrefAlign(TD.PointerPrefAlign),
134 Alignments(TD.Alignments)
135 { }
130 TargetData(const TargetData &TD);
136131
137132 ~TargetData(); // Not virtual, do not subclass this class
138133
2323 #include "llvm/Support/MathExtras.h"
2424 #include "llvm/Support/ManagedStatic.h"
2525 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/System/Mutex.h"
2726 #include "llvm/ADT/DenseMap.h"
2827 #include "llvm/ADT/StringExtras.h"
2928 #include
131130 // TargetData Class Implementation
132131 //===----------------------------------------------------------------------===//
133132
133 typedef DenseMap LayoutInfoTy;
134
134135 /*!
135136 A TargetDescription string consists of a sequence of hyphen-delimited
136137 specifiers for target endianness, pointer size and alignments, and various
169170 alignment will be used.
170171 */
171172 void TargetData::init(const std::string &TargetDescription) {
173 LayoutMap = static_cast(new LayoutInfoTy());
172174 std::string temp = TargetDescription;
173175
174176 LittleEndian = false;
233235 }
234236 }
235237
238 TargetData::TargetData(const std::string &TargetDescription)
239 : ImmutablePass(&ID) {
240 init(TargetDescription);
241 }
242
236243 TargetData::TargetData(const Module *M)
237244 : ImmutablePass(&ID) {
238245 init(M->getDataLayout());
239246 }
247
248 TargetData::TargetData(const TargetData &TD) :
249 ImmutablePass(&ID),
250 LittleEndian(TD.isLittleEndian()),
251 PointerMemSize(TD.PointerMemSize),
252 PointerABIAlign(TD.PointerABIAlign),
253 PointerPrefAlign(TD.PointerPrefAlign),
254 Alignments(TD.Alignments) {
255 LayoutInfoTy *Other = static_cast(TD.LayoutMap);
256 LayoutMap = static_cast(new LayoutInfoTy(*Other));
257 }
258
240259
241260 void
242261 TargetData::setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
316335 : Alignments[BestMatchIdx].PrefAlign;
317336 }
318337
319 namespace {
320
321 /// LayoutInfo - The lazy cache of structure layout information maintained by
322 /// TargetData. Note that the struct types must have been free'd before
323 /// llvm_shutdown is called (and thus this is deallocated) because all the
324 /// targets with cached elements should have been destroyed.
325 ///
326 typedef std::pair LayoutKey;
327
328 struct DenseMapLayoutKeyInfo {
329 static inline LayoutKey getEmptyKey() { return LayoutKey(0, 0); }
330 static inline LayoutKey getTombstoneKey() {
331 return LayoutKey((TargetData*)(intptr_t)-1, 0);
332 }
333 static unsigned getHashValue(const LayoutKey &Val) {
334 return DenseMapInfo::getHashValue(Val.first) ^
335 DenseMapInfo::getHashValue(Val.second);
336 }
337 static bool isEqual(const LayoutKey &LHS, const LayoutKey &RHS) {
338 return LHS == RHS;
339 }
340
341 static bool isPod() { return true; }
342 };
343
344 typedef DenseMap LayoutInfoTy;
345
346 }
347
348 static ManagedStatic LayoutInfo;
349 static ManagedStatic > LayoutLock;
350
351338 TargetData::~TargetData() {
352 if (!LayoutInfo.isConstructed())
353 return;
354
355 sys::SmartScopedLock Lock(*LayoutLock);
339 assert(LayoutMap && "LayoutMap not initialized?");
340 LayoutInfoTy &TheMap = *static_cast(LayoutMap);
341
356342 // Remove any layouts for this TD.
357 LayoutInfoTy &TheMap = *LayoutInfo;
358343 for (LayoutInfoTy::iterator I = TheMap.begin(), E = TheMap.end(); I != E; ) {
359 if (I->first.first == this) {
360 I->second->~StructLayout();
361 free(I->second);
362 TheMap.erase(I++);
363 } else {
364 ++I;
365 }
366 }
344 I->second->~StructLayout();
345 free(I->second);
346 TheMap.erase(I++);
347 }
348
349 delete static_cast(LayoutMap);
350 LayoutMap = 0;
367351 }
368352
369353 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
370 LayoutInfoTy &TheMap = *LayoutInfo;
371
372 sys::SmartScopedLock Lock(*LayoutLock);
373 StructLayout *&SL = TheMap[LayoutKey(this, Ty)];
354 assert(LayoutMap && "LayoutMap not initialized?");
355 LayoutInfoTy &TheMap = *static_cast(LayoutMap);
356
357 StructLayout *&SL = TheMap[Ty];
374358 if (SL) return SL;
375359
376360 // Otherwise, create the struct layout. Because it is variable length, we
392376 /// removed, this method must be called whenever a StructType is removed to
393377 /// avoid a dangling pointer in this cache.
394378 void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
395 if (!LayoutInfo.isConstructed()) return; // No cache.
396
397 sys::SmartScopedLock Lock(*LayoutLock);
398 LayoutInfoTy::iterator I = LayoutInfo->find(LayoutKey(this, Ty));
379 assert(LayoutMap && "LayoutMap not initialized?");
380 LayoutInfoTy *LayoutInfo = static_cast(LayoutMap);
381 LayoutInfoTy::iterator I = LayoutInfo->find(Ty);
399382 if (I == LayoutInfo->end()) return;
400383
401384 I->second->~StructLayout();