Switch LayoutInfo to be a DenseMap instead of an std::map. This speeds up

-load-vn -gcse by 2.3%.

llvm-svn: 34160
This commit is contained in:
Chris Lattner 2007-02-10 20:26:17 +00:00
parent 8fa88af5f0
commit d079b34aa0

View File

@ -23,6 +23,7 @@
#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/ManagedStatic.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
#include <algorithm> #include <algorithm>
#include <cstdlib> #include <cstdlib>
@ -208,7 +209,20 @@ TargetData::TargetData(const Module *M) {
/// targets with cached elements should have been destroyed. /// targets with cached elements should have been destroyed.
/// ///
typedef std::pair<const TargetData*,const StructType*> LayoutKey; typedef std::pair<const TargetData*,const StructType*> LayoutKey;
typedef std::map<LayoutKey, StructLayout*> LayoutInfoTy;
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 DenseMapKeyInfo<void*>::getHashValue(Val.first) ^
DenseMapKeyInfo<void*>::getHashValue(Val.second);
}
static bool isPod() { return true; }
};
typedef DenseMap<LayoutKey, StructLayout*, DenseMapLayoutKeyInfo> LayoutInfoTy;
static ManagedStatic<LayoutInfoTy> LayoutInfo; static ManagedStatic<LayoutInfoTy> LayoutInfo;
@ -216,14 +230,15 @@ TargetData::~TargetData() {
if (LayoutInfo.isConstructed()) { if (LayoutInfo.isConstructed()) {
// Remove any layouts for this TD. // Remove any layouts for this TD.
LayoutInfoTy &TheMap = *LayoutInfo; LayoutInfoTy &TheMap = *LayoutInfo;
LayoutInfoTy::iterator for (LayoutInfoTy::iterator I = TheMap.begin(), E = TheMap.end();
I = TheMap.lower_bound(LayoutKey(this, (const StructType*)0)); I != E; ) {
if (I->first.first == this) {
for (LayoutInfoTy::iterator E = TheMap.end(); I->second->~StructLayout();
I != E && I->first.first == this; ) { free(I->second);
I->second->~StructLayout(); TheMap.erase(I++);
free(I->second); } else {
TheMap.erase(I++); ++I;
}
} }
} }
} }
@ -231,18 +246,21 @@ TargetData::~TargetData() {
const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
LayoutInfoTy &TheMap = *LayoutInfo; LayoutInfoTy &TheMap = *LayoutInfo;
LayoutInfoTy::iterator I = TheMap.lower_bound(LayoutKey(this, Ty)); StructLayout *&SL = TheMap[LayoutKey(this, Ty)];
if (I != TheMap.end() && I->first.first == this && I->first.second == Ty) if (SL) return SL;
return I->second;
// Otherwise, create the struct layout. Because it is variable length, we // Otherwise, create the struct layout. Because it is variable length, we
// malloc it, then use placement new. // malloc it, then use placement new.
unsigned NumElts = Ty->getNumElements(); unsigned NumElts = Ty->getNumElements();
StructLayout *L = StructLayout *L =
(StructLayout *)malloc(sizeof(StructLayout)+(NumElts-1)*sizeof(uint64_t)); (StructLayout *)malloc(sizeof(StructLayout)+(NumElts-1)*sizeof(uint64_t));
// Set SL before calling StructLayout's ctor. The ctor could cause other
// entries to be added to TheMap, invalidating our reference.
SL = L;
new (L) StructLayout(Ty, *this); new (L) StructLayout(Ty, *this);
TheMap.insert(I, std::make_pair(LayoutKey(this, Ty), L));
return L; return L;
} }