Reapply r79555 for testing. Daniel's trying to work out some buildbot weirdnesss.
llvm-svn: 79572
This commit is contained in:
parent
1a606ab12a
commit
9ca906e69d
|
@ -91,6 +91,9 @@ private:
|
||||||
*/
|
*/
|
||||||
static const TargetAlignElem InvalidAlignmentElem;
|
static const TargetAlignElem InvalidAlignmentElem;
|
||||||
|
|
||||||
|
/// Opaque pointer for the StructType -> StructLayout map
|
||||||
|
void* LayoutMap;
|
||||||
|
|
||||||
//! Set/initialize target alignments
|
//! Set/initialize target alignments
|
||||||
void setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
|
void setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
|
||||||
unsigned char pref_align, uint32_t bit_width);
|
unsigned char pref_align, uint32_t bit_width);
|
||||||
|
@ -107,6 +110,9 @@ private:
|
||||||
return (&align != &InvalidAlignmentElem);
|
return (&align != &InvalidAlignmentElem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DO NOT IMPLEMENT
|
||||||
|
void operator=(const TargetData&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Default ctor.
|
/// Default ctor.
|
||||||
///
|
///
|
||||||
|
@ -118,22 +124,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a TargetData from a specification string. See init().
|
/// 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.
|
/// Initialize target data from properties stored in the module.
|
||||||
explicit TargetData(const Module *M);
|
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
|
~TargetData(); // Not virtual, do not subclass this class
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include "llvm/Support/ManagedStatic.h"
|
#include "llvm/Support/ManagedStatic.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/System/Mutex.h"
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -132,6 +131,8 @@ const TargetAlignElem TargetData::InvalidAlignmentElem =
|
||||||
// TargetData Class Implementation
|
// TargetData Class Implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
typedef DenseMap<const StructType*, StructLayout*> LayoutInfoTy;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A TargetDescription string consists of a sequence of hyphen-delimited
|
A TargetDescription string consists of a sequence of hyphen-delimited
|
||||||
specifiers for target endianness, pointer size and alignments, and various
|
specifiers for target endianness, pointer size and alignments, and various
|
||||||
|
@ -170,6 +171,7 @@ const TargetAlignElem TargetData::InvalidAlignmentElem =
|
||||||
alignment will be used.
|
alignment will be used.
|
||||||
*/
|
*/
|
||||||
void TargetData::init(const std::string &TargetDescription) {
|
void TargetData::init(const std::string &TargetDescription) {
|
||||||
|
LayoutMap = static_cast<void*>(new LayoutInfoTy());
|
||||||
std::string temp = TargetDescription;
|
std::string temp = TargetDescription;
|
||||||
|
|
||||||
LittleEndian = false;
|
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)
|
TargetData::TargetData(const Module *M)
|
||||||
: ImmutablePass(&ID) {
|
: ImmutablePass(&ID) {
|
||||||
init(M->getDataLayout());
|
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
|
void
|
||||||
TargetData::setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
|
TargetData::setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
|
||||||
unsigned char pref_align, uint32_t bit_width) {
|
unsigned char pref_align, uint32_t bit_width) {
|
||||||
|
@ -317,61 +336,26 @@ unsigned TargetData::getAlignmentInfo(AlignTypeEnum AlignType,
|
||||||
: Alignments[BestMatchIdx].PrefAlign;
|
: 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() {
|
TargetData::~TargetData() {
|
||||||
if (!LayoutInfo.isConstructed())
|
assert(LayoutMap && "LayoutMap not initialized?");
|
||||||
return;
|
LayoutInfoTy &TheMap = *static_cast<LayoutInfoTy*>(LayoutMap);
|
||||||
|
|
||||||
sys::SmartScopedLock<true> Lock(*LayoutLock);
|
|
||||||
// Remove any layouts for this TD.
|
// Remove any layouts for this TD.
|
||||||
LayoutInfoTy &TheMap = *LayoutInfo;
|
|
||||||
for (LayoutInfoTy::iterator I = TheMap.begin(), E = TheMap.end(); I != E; ) {
|
for (LayoutInfoTy::iterator I = TheMap.begin(), E = TheMap.end(); I != E; ) {
|
||||||
if (I->first.first == this) {
|
|
||||||
I->second->~StructLayout();
|
I->second->~StructLayout();
|
||||||
free(I->second);
|
free(I->second);
|
||||||
TheMap.erase(I++);
|
TheMap.erase(I++);
|
||||||
} else {
|
|
||||||
++I;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete static_cast<LayoutInfoTy*>(LayoutMap);
|
||||||
|
LayoutMap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
|
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[Ty];
|
||||||
StructLayout *&SL = TheMap[LayoutKey(this, Ty)];
|
|
||||||
if (SL) return SL;
|
if (SL) return SL;
|
||||||
|
|
||||||
// Otherwise, create the struct layout. Because it is variable length, we
|
// 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
|
/// removed, this method must be called whenever a StructType is removed to
|
||||||
/// avoid a dangling pointer in this cache.
|
/// avoid a dangling pointer in this cache.
|
||||||
void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
|
void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
|
||||||
if (!LayoutInfo.isConstructed()) return; // No cache.
|
assert(LayoutMap && "LayoutMap not initialized?");
|
||||||
|
LayoutInfoTy *LayoutInfo = static_cast<LayoutInfoTy*>(LayoutMap);
|
||||||
sys::SmartScopedLock<true> Lock(*LayoutLock);
|
LayoutInfoTy::iterator I = LayoutInfo->find(Ty);
|
||||||
LayoutInfoTy::iterator I = LayoutInfo->find(LayoutKey(this, Ty));
|
|
||||||
if (I == LayoutInfo->end()) return;
|
if (I == LayoutInfo->end()) return;
|
||||||
|
|
||||||
I->second->~StructLayout();
|
I->second->~StructLayout();
|
||||||
|
|
Loading…
Reference in New Issue