diff options
author | Owen Anderson <resistor@mac.com> | 2009-08-20 18:26:03 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2009-08-20 18:26:03 +0000 |
commit | d9b207122eeb740a3878f8389cb38b81d9388734 (patch) | |
tree | d003302a05f5a02253fbe2b851c3f5c6270e6a6f /lib/Target/TargetData.cpp | |
parent | 47234e6d38407a8cfcb54ca04e45a2e657f240be (diff) |
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
Diffstat (limited to 'lib/Target/TargetData.cpp')
-rw-r--r-- | lib/Target/TargetData.cpp | 87 |
1 files changed, 35 insertions, 52 deletions
diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index baef9c8fa7..43f0ac8a94 100644 --- a/lib/Target/TargetData.cpp +++ b/lib/Target/TargetData.cpp @@ -24,7 +24,6 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/System/Mutex.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringExtras.h" #include <algorithm> @@ -132,6 +131,8 @@ const TargetAlignElem TargetData::InvalidAlignmentElem = // TargetData Class Implementation //===----------------------------------------------------------------------===// +typedef DenseMap<const StructType*, StructLayout*> LayoutInfoTy; + /*! A TargetDescription string consists of a sequence of hyphen-delimited specifiers for target endianness, pointer size and alignments, and various @@ -170,6 +171,7 @@ const TargetAlignElem TargetData::InvalidAlignmentElem = alignment will be used. */ void TargetData::init(const std::string &TargetDescription) { + LayoutMap = static_cast<void*>(new LayoutInfoTy()); std::string temp = TargetDescription; LittleEndian = false; @@ -234,11 +236,28 @@ void TargetData::init(const std::string &TargetDescription) { } } +TargetData::TargetData(const std::string &TargetDescription) + : ImmutablePass(&ID) { + init(TargetDescription); +} + TargetData::TargetData(const Module *M) : ImmutablePass(&ID) { init(M->getDataLayout()); } +TargetData::TargetData(const TargetData &TD) : + ImmutablePass(&ID), + LittleEndian(TD.isLittleEndian()), + PointerMemSize(TD.PointerMemSize), + PointerABIAlign(TD.PointerABIAlign), + PointerPrefAlign(TD.PointerPrefAlign), + Alignments(TD.Alignments) { + LayoutInfoTy *Other = static_cast<LayoutInfoTy*>(TD.LayoutMap); + LayoutMap = static_cast<void*>(new LayoutInfoTy(*Other)); +} + + void TargetData::setAlignment(AlignTypeEnum align_type, unsigned char abi_align, unsigned char pref_align, uint32_t bit_width) { @@ -317,61 +336,26 @@ unsigned TargetData::getAlignmentInfo(AlignTypeEnum AlignType, : Alignments[BestMatchIdx].PrefAlign; } -namespace { - -/// LayoutInfo - The lazy cache of structure layout information maintained by -/// TargetData. Note that the struct types must have been free'd before -/// llvm_shutdown is called (and thus this is deallocated) because all the -/// targets with cached elements should have been destroyed. -/// -typedef std::pair<const TargetData*,const StructType*> LayoutKey; - -struct DenseMapLayoutKeyInfo { - static inline LayoutKey getEmptyKey() { return LayoutKey(0, 0); } - static inline LayoutKey getTombstoneKey() { - return LayoutKey((TargetData*)(intptr_t)-1, 0); - } - static unsigned getHashValue(const LayoutKey &Val) { - return DenseMapInfo<void*>::getHashValue(Val.first) ^ - DenseMapInfo<void*>::getHashValue(Val.second); - } - static bool isEqual(const LayoutKey &LHS, const LayoutKey &RHS) { - return LHS == RHS; - } - - static bool isPod() { return true; } -}; - -typedef DenseMap<LayoutKey, StructLayout*, DenseMapLayoutKeyInfo> LayoutInfoTy; - -} - -static ManagedStatic<LayoutInfoTy> LayoutInfo; -static ManagedStatic<sys::SmartMutex<true> > LayoutLock; - TargetData::~TargetData() { - if (!LayoutInfo.isConstructed()) - return; - - sys::SmartScopedLock<true> Lock(*LayoutLock); + assert(LayoutMap && "LayoutMap not initialized?"); + LayoutInfoTy &TheMap = *static_cast<LayoutInfoTy*>(LayoutMap); + // Remove any layouts for this TD. - LayoutInfoTy &TheMap = *LayoutInfo; for (LayoutInfoTy::iterator I = TheMap.begin(), E = TheMap.end(); I != E; ) { - if (I->first.first == this) { - I->second->~StructLayout(); - free(I->second); - TheMap.erase(I++); - } else { - ++I; - } + I->second->~StructLayout(); + free(I->second); + TheMap.erase(I++); } + + delete static_cast<LayoutInfoTy*>(LayoutMap); + LayoutMap = 0; } const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { - LayoutInfoTy &TheMap = *LayoutInfo; + assert(LayoutMap && "LayoutMap not initialized?"); + LayoutInfoTy &TheMap = *static_cast<LayoutInfoTy*>(LayoutMap); - sys::SmartScopedLock<true> Lock(*LayoutLock); - StructLayout *&SL = TheMap[LayoutKey(this, Ty)]; + StructLayout *&SL = TheMap[Ty]; if (SL) return SL; // Otherwise, create the struct layout. Because it is variable length, we @@ -393,10 +377,9 @@ const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { /// removed, this method must be called whenever a StructType is removed to /// avoid a dangling pointer in this cache. void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const { - if (!LayoutInfo.isConstructed()) return; // No cache. - - sys::SmartScopedLock<true> Lock(*LayoutLock); - LayoutInfoTy::iterator I = LayoutInfo->find(LayoutKey(this, Ty)); + assert(LayoutMap && "LayoutMap not initialized?"); + LayoutInfoTy *LayoutInfo = static_cast<LayoutInfoTy*>(LayoutMap); + LayoutInfoTy::iterator I = LayoutInfo->find(Ty); if (I == LayoutInfo->end()) return; I->second->~StructLayout(); |