[llvm-commits] [llvm] r79568 - in /llvm/trunk: include/llvm/Target/TargetData.h lib/Target/TargetData.cpp
Bill Wendling
isanbard at gmail.com
Thu Aug 20 15:04:43 PDT 2009
Author: void
Date: Thu Aug 20 17:04:42 2009
New Revision: 79568
URL: http://llvm.org/viewvc/llvm-project?rev=79568&view=rev
Log:
--- Reverse-merging r79555 into '.':
U include/llvm/Target/TargetData.h
U lib/Target/TargetData.cpp
Temporarily revert 79555. It was causing hangs and test failures.
Modified:
llvm/trunk/include/llvm/Target/TargetData.h
llvm/trunk/lib/Target/TargetData.cpp
Modified: llvm/trunk/include/llvm/Target/TargetData.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetData.h?rev=79568&r1=79567&r2=79568&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetData.h (original)
+++ llvm/trunk/include/llvm/Target/TargetData.h Thu Aug 20 17:04:42 2009
@@ -91,9 +91,6 @@
*/
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 @@
return (&align != &InvalidAlignmentElem);
}
- // DO NOT IMPLEMENT
- void operator=(const TargetData&);
-
public:
/// Default ctor.
///
@@ -124,11 +118,22 @@
}
/// 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
Modified: llvm/trunk/lib/Target/TargetData.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetData.cpp?rev=79568&r1=79567&r2=79568&view=diff
==============================================================================
--- llvm/trunk/lib/Target/TargetData.cpp (original)
+++ llvm/trunk/lib/Target/TargetData.cpp Thu Aug 20 17:04:42 2009
@@ -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 <algorithm>
@@ -131,8 +132,6 @@
// 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
@@ -171,7 +170,6 @@
alignment will be used.
*/
void TargetData::init(const std::string &TargetDescription) {
- LayoutMap = static_cast<void*>(new LayoutInfoTy());
std::string temp = TargetDescription;
LittleEndian = false;
@@ -236,28 +234,11 @@
}
}
-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) {
@@ -336,26 +317,61 @@
: Alignments[BestMatchIdx].PrefAlign;
}
-TargetData::~TargetData() {
- assert(LayoutMap && "LayoutMap not initialized?");
- LayoutInfoTy &TheMap = *static_cast<LayoutInfoTy*>(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<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);
// 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<LayoutInfoTy*>(LayoutMap);
- LayoutMap = 0;
}
const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
- assert(LayoutMap && "LayoutMap not initialized?");
- LayoutInfoTy &TheMap = *static_cast<LayoutInfoTy*>(LayoutMap);
+ LayoutInfoTy &TheMap = *LayoutInfo;
- StructLayout *&SL = TheMap[Ty];
+ sys::SmartScopedLock<true> 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 @@
/// 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<LayoutInfoTy*>(LayoutMap);
- LayoutInfoTy::iterator I = LayoutInfo->find(Ty);
+ if (!LayoutInfo.isConstructed()) return; // No cache.
+
+ sys::SmartScopedLock<true> Lock(*LayoutLock);
+ LayoutInfoTy::iterator I = LayoutInfo->find(LayoutKey(this, Ty));
if (I == LayoutInfo->end()) return;
I->second->~StructLayout();
More information about the llvm-commits
mailing list