aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/TargetData.cpp
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2009-08-20 18:26:03 +0000
committerOwen Anderson <resistor@mac.com>2009-08-20 18:26:03 +0000
commitd9b207122eeb740a3878f8389cb38b81d9388734 (patch)
treed003302a05f5a02253fbe2b851c3f5c6270e6a6f /lib/Target/TargetData.cpp
parent47234e6d38407a8cfcb54ca04e45a2e657f240be (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.cpp87
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();