[llvm-commits] CVS: llvm/lib/Target/TargetData.cpp
Chris Lattner
sabre at nondot.org
Sat Feb 10 12:16:00 PST 2007
Changes in directory llvm/lib/Target:
TargetData.cpp updated: 1.89 -> 1.90
---
Log message:
eliminate the std::vector from StructLayout, allocating the elements immediately
after the StructLayout object in memory. This marginally improves locality,
speeding up -load-vn -gcse by ~0.8%.
---
Diffs of the changes: (+57 -43)
TargetData.cpp | 100 ++++++++++++++++++++++++++++++++-------------------------
1 files changed, 57 insertions(+), 43 deletions(-)
Index: llvm/lib/Target/TargetData.cpp
diff -u llvm/lib/Target/TargetData.cpp:1.89 llvm/lib/Target/TargetData.cpp:1.90
--- llvm/lib/Target/TargetData.cpp:1.89 Sat Feb 10 13:59:22 2007
+++ llvm/lib/Target/TargetData.cpp Sat Feb 10 14:15:41 2007
@@ -48,11 +48,11 @@
StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
StructAlignment = 0;
StructSize = 0;
+ NumElements = ST->getNumElements();
// Loop over each of the elements, placing them in memory...
- for (StructType::element_iterator TI = ST->element_begin(),
- TE = ST->element_end(); TI != TE; ++TI) {
- const Type *Ty = *TI;
+ for (unsigned i = 0, e = NumElements; i != e; ++i) {
+ const Type *Ty = ST->getElementType(i);
unsigned char A;
unsigned TyAlign;
uint64_t TySize;
@@ -66,7 +66,7 @@
// Keep track of maximum alignment constraint
StructAlignment = std::max(TyAlign, StructAlignment);
- MemberOffsets.push_back(StructSize);
+ MemberOffsets[i] = StructSize;
StructSize += TySize; // Consume space for this data item
}
@@ -83,15 +83,15 @@
/// getElementContainingOffset - Given a valid offset into the structure,
/// return the structure index that contains it.
unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
- std::vector<uint64_t>::const_iterator SI =
- std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(), Offset);
- assert(SI != MemberOffsets.begin() && "Offset not in structure type!");
+ const uint64_t *SI =
+ std::upper_bound(&MemberOffsets[0], &MemberOffsets[NumElements], Offset);
+ assert(SI != &MemberOffsets[0] && "Offset not in structure type!");
--SI;
assert(*SI <= Offset && "upper_bound didn't work");
- assert((SI == MemberOffsets.begin() || *(SI-1) < Offset) &&
- (SI+1 == MemberOffsets.end() || *(SI+1) > Offset) &&
+ assert((SI == &MemberOffsets[0] || *(SI-1) < Offset) &&
+ (SI+1 == &MemberOffsets[NumElements] || *(SI+1) > Offset) &&
"Upper bound didn't work!");
- return SI-MemberOffsets.begin();
+ return SI-&MemberOffsets[0];
}
//===----------------------------------------------------------------------===//
@@ -203,25 +203,66 @@
}
/// LayoutInfo - The lazy cache of structure layout information maintained by
-/// TargetData.
+/// 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;
-static ManagedStatic<std::map<LayoutKey, StructLayout> > LayoutInfo;
+static ManagedStatic<std::map<LayoutKey, StructLayout*> > LayoutInfo;
TargetData::~TargetData() {
if (LayoutInfo.isConstructed()) {
// Remove any layouts for this TD.
- std::map<LayoutKey, StructLayout> &TheMap = *LayoutInfo;
- std::map<LayoutKey, StructLayout>::iterator
+ std::map<LayoutKey, StructLayout*> &TheMap = *LayoutInfo;
+ std::map<LayoutKey, StructLayout*>::iterator
I = TheMap.lower_bound(LayoutKey(this, (const StructType*)0));
- for (std::map<LayoutKey, StructLayout>::iterator E = TheMap.end();
- I != E && I->first.first == this; )
+ for (std::map<LayoutKey, StructLayout*>::iterator E = TheMap.end();
+ I != E && I->first.first == this; ) {
+ I->second->~StructLayout();
+ free(I->second);
TheMap.erase(I++);
+ }
+ }
+}
+
+const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
+ std::map<LayoutKey, StructLayout*> &TheMap = *LayoutInfo;
+
+ std::map<LayoutKey, StructLayout*>::iterator
+ I = TheMap.lower_bound(LayoutKey(this, Ty));
+ if (I != TheMap.end() && I->first.first == this && I->first.second == Ty)
+ return I->second;
+
+ // Otherwise, create the struct layout. Because it is variable length, we
+ // malloc it, then use placement new.
+ unsigned NumElts = Ty->getNumElements();
+ StructLayout *L =
+ (StructLayout *)malloc(sizeof(StructLayout)+(NumElts-1)*sizeof(uint64_t));
+ new (L) StructLayout(Ty, *this);
+
+ TheMap.insert(I, std::make_pair(LayoutKey(this, Ty), L));
+ return L;
+}
+
+/// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
+/// objects. If a TargetData object is alive when types are being refined and
+/// 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.
+
+ std::map<LayoutKey, StructLayout*>::iterator I =
+ LayoutInfo->find(LayoutKey(this, Ty));
+ if (I != LayoutInfo->end()) {
+ I->second->~StructLayout();
+ free(I->second);
+ LayoutInfo->erase(I);
}
}
+
std::string TargetData::getStringRepresentation() const {
std::stringstream repr;
@@ -250,33 +291,6 @@
return repr.str();
}
-const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
- std::map<LayoutKey, StructLayout> &TheMap = *LayoutInfo;
-
- std::map<LayoutKey, StructLayout>::iterator
- I = TheMap.lower_bound(LayoutKey(this, Ty));
- if (I != TheMap.end() && I->first.first == this && I->first.second == Ty)
- return &I->second;
- else {
- return &TheMap.insert(I, std::make_pair(LayoutKey(this, Ty),
- StructLayout(Ty, *this)))->second;
- }
-}
-
-/// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
-/// objects. If a TargetData object is alive when types are being refined and
-/// 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.
-
- std::map<LayoutKey, StructLayout>::iterator I =
- LayoutInfo->find(std::make_pair(this, Ty));
- if (I != LayoutInfo->end())
- LayoutInfo->erase(I);
-}
-
-
static inline void getTypeInfoABI(const Type *Ty, const TargetData *TD,
uint64_t &Size, unsigned char &Alignment) {
More information about the llvm-commits
mailing list