From 2ea20154cef8ecfb8803bcfe5223e1c199d61858 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Thu, 20 Aug 2009 23:51:44 +0000 Subject: [PATCH] Re-revert r79555. Apparently it's not just buildbot weirdness. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79578 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetData.h | 21 +++++--- lib/Target/TargetData.cpp | 87 +++++++++++++++++++------------- 2 files changed, 65 insertions(+), 43 deletions(-) diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index b0ea291249a..23775be70f9 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/Target/TargetData.h @@ -91,9 +91,6 @@ private: */ static const TargetAlignElem InvalidAlignmentElem; - /// Opaque pointer for the StructType -> StructLayout map - void* LayoutMap; - //! Set/initialize target alignments void setAlignment(AlignTypeEnum align_type, unsigned char abi_align, unsigned char pref_align, uint32_t bit_width); @@ -110,9 +107,6 @@ private: return (&align != &InvalidAlignmentElem); } - // DO NOT IMPLEMENT - void operator=(const TargetData&); - public: /// Default ctor. /// @@ -124,11 +118,22 @@ public: } /// Constructs a TargetData from a specification string. See init(). - explicit TargetData(const std::string &TargetDescription); + explicit TargetData(const std::string &TargetDescription) + : ImmutablePass(&ID) { + init(TargetDescription); + } /// Initialize target data from properties stored in the module. explicit TargetData(const Module *M); - TargetData(const TargetData &TD); + + TargetData(const TargetData &TD) : + ImmutablePass(&ID), + LittleEndian(TD.isLittleEndian()), + PointerMemSize(TD.PointerMemSize), + PointerABIAlign(TD.PointerABIAlign), + PointerPrefAlign(TD.PointerPrefAlign), + Alignments(TD.Alignments) + { } ~TargetData(); // Not virtual, do not subclass this class diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index 43f0ac8a94d..baef9c8fa74 100644 --- a/lib/Target/TargetData.cpp +++ b/lib/Target/TargetData.cpp @@ -24,6 +24,7 @@ #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 @@ -131,8 +132,6 @@ const TargetAlignElem TargetData::InvalidAlignmentElem = // TargetData Class Implementation //===----------------------------------------------------------------------===// -typedef DenseMap LayoutInfoTy; - /*! A TargetDescription string consists of a sequence of hyphen-delimited specifiers for target endianness, pointer size and alignments, and various @@ -171,7 +170,6 @@ typedef DenseMap LayoutInfoTy; alignment will be used. */ void TargetData::init(const std::string &TargetDescription) { - LayoutMap = static_cast(new LayoutInfoTy()); std::string temp = TargetDescription; LittleEndian = false; @@ -236,28 +234,11 @@ 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(TD.LayoutMap); - LayoutMap = static_cast(new LayoutInfoTy(*Other)); -} - - void TargetData::setAlignment(AlignTypeEnum align_type, unsigned char abi_align, unsigned char pref_align, uint32_t bit_width) { @@ -336,26 +317,61 @@ unsigned TargetData::getAlignmentInfo(AlignTypeEnum AlignType, : Alignments[BestMatchIdx].PrefAlign; } -TargetData::~TargetData() { - assert(LayoutMap && "LayoutMap not initialized?"); - LayoutInfoTy &TheMap = *static_cast(LayoutMap); +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 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::getHashValue(Val.first) ^ + DenseMapInfo::getHashValue(Val.second); + } + static bool isEqual(const LayoutKey &LHS, const LayoutKey &RHS) { + return LHS == RHS; + } + + static bool isPod() { return true; } +}; + +typedef DenseMap LayoutInfoTy; + +} + +static ManagedStatic LayoutInfo; +static ManagedStatic > LayoutLock; +TargetData::~TargetData() { + if (!LayoutInfo.isConstructed()) + return; + + sys::SmartScopedLock Lock(*LayoutLock); // Remove any layouts for this TD. + LayoutInfoTy &TheMap = *LayoutInfo; for (LayoutInfoTy::iterator I = TheMap.begin(), E = TheMap.end(); I != E; ) { - I->second->~StructLayout(); - free(I->second); - TheMap.erase(I++); + if (I->first.first == this) { + I->second->~StructLayout(); + free(I->second); + TheMap.erase(I++); + } else { + ++I; + } } - - delete static_cast(LayoutMap); - LayoutMap = 0; } const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { - assert(LayoutMap && "LayoutMap not initialized?"); - LayoutInfoTy &TheMap = *static_cast(LayoutMap); + LayoutInfoTy &TheMap = *LayoutInfo; - StructLayout *&SL = TheMap[Ty]; + sys::SmartScopedLock Lock(*LayoutLock); + StructLayout *&SL = TheMap[LayoutKey(this, Ty)]; if (SL) return SL; // Otherwise, create the struct layout. Because it is variable length, we @@ -377,9 +393,10 @@ 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 { - assert(LayoutMap && "LayoutMap not initialized?"); - LayoutInfoTy *LayoutInfo = static_cast(LayoutMap); - LayoutInfoTy::iterator I = LayoutInfo->find(Ty); + if (!LayoutInfo.isConstructed()) return; // No cache. + + sys::SmartScopedLock Lock(*LayoutLock); + LayoutInfoTy::iterator I = LayoutInfo->find(LayoutKey(this, Ty)); if (I == LayoutInfo->end()) return; I->second->~StructLayout(); -- 2.34.1