From 9085750d3126618ab1b3a4104c34bc504f8b09f4 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Fri, 21 Aug 2009 19:59:12 +0000 Subject: [PATCH] Try again at privatizing the layout info map, with a rewritten patch. This preserves the existing behavior much more closely than my previous attempt. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79663 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetData.h | 6 ++- lib/Target/TargetData.cpp | 64 +++++++++----------------------- 2 files changed, 22 insertions(+), 48 deletions(-) diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index 23775be70f9..f8ea64b4ea6 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/Target/TargetData.h @@ -91,6 +91,9 @@ private: */ static const TargetAlignElem InvalidAlignmentElem; + // Opaque pointer for the StructType -> StructLayout map. + mutable void* LayoutMap; + //! Set/initialize target alignments void setAlignment(AlignTypeEnum align_type, unsigned char abi_align, unsigned char pref_align, uint32_t bit_width); @@ -132,7 +135,8 @@ public: PointerMemSize(TD.PointerMemSize), PointerABIAlign(TD.PointerABIAlign), PointerPrefAlign(TD.PointerPrefAlign), - Alignments(TD.Alignments) + Alignments(TD.Alignments), + LayoutMap(0) { } ~TargetData(); // Not virtual, do not subclass this class diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index baef9c8fa74..5bcd6583635 100644 --- a/lib/Target/TargetData.cpp +++ b/lib/Target/TargetData.cpp @@ -172,6 +172,7 @@ const TargetAlignElem TargetData::InvalidAlignmentElem = void TargetData::init(const std::string &TargetDescription) { std::string temp = TargetDescription; + LayoutMap = 0; LittleEndian = false; PointerMemSize = 8; PointerABIAlign = 8; @@ -317,61 +318,30 @@ 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 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; +typedef DenseMapLayoutInfoTy; TargetData::~TargetData() { - if (!LayoutInfo.isConstructed()) + if (!LayoutMap) return; - sys::SmartScopedLock Lock(*LayoutLock); // Remove any layouts for this TD. - LayoutInfoTy &TheMap = *LayoutInfo; + LayoutInfoTy &TheMap = *static_cast(LayoutMap); 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(LayoutMap); } const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { - LayoutInfoTy &TheMap = *LayoutInfo; + if (!LayoutMap) + LayoutMap = static_cast(new LayoutInfoTy()); + + LayoutInfoTy &TheMap = *static_cast(LayoutMap); - sys::SmartScopedLock 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 +363,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 { - if (!LayoutInfo.isConstructed()) return; // No cache. + if (!LayoutMap) return; // No cache. - sys::SmartScopedLock Lock(*LayoutLock); - LayoutInfoTy::iterator I = LayoutInfo->find(LayoutKey(this, Ty)); + LayoutInfoTy* LayoutInfo = static_cast(LayoutMap); + LayoutInfoTy::iterator I = LayoutInfo->find(Ty); if (I == LayoutInfo->end()) return; I->second->~StructLayout(); -- 2.34.1