summaryrefslogtreecommitdiff
path: root/lib/VMCore/Type.cpp
diff options
context:
space:
mode:
authorJay Foad <jay.foad@gmail.com>2012-02-21 09:25:52 +0000
committerJay Foad <jay.foad@gmail.com>2012-02-21 09:25:52 +0000
commit6b842e35dcd7faf2b05b2ef9b1892c29050f3607 (patch)
tree7d8ba2732297420de7b37a26b0725d6034607d5a /lib/VMCore/Type.cpp
parentdac3d36584766a7c00972603598dcdff2f5314d5 (diff)
downloadllvm-6b842e35dcd7faf2b05b2ef9b1892c29050f3607.tar.gz
llvm-6b842e35dcd7faf2b05b2ef9b1892c29050f3607.tar.bz2
llvm-6b842e35dcd7faf2b05b2ef9b1892c29050f3607.tar.xz
PR1210: make uniquing of struct and function types more efficient by
using a DenseMap and Talin's new GeneralHash, avoiding the need for a temporary std::vector on every lookup. Patch by Meador Inge! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151049 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/Type.cpp')
-rw-r--r--lib/VMCore/Type.cpp56
1 files changed, 25 insertions, 31 deletions
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index 5cdddb36ee..0bc4f74af2 100644
--- a/lib/VMCore/Type.cpp
+++ b/lib/VMCore/Type.cpp
@@ -390,24 +390,20 @@ FunctionType::FunctionType(Type *Result, ArrayRef<Type*> Params,
// FunctionType::get - The factory function for the FunctionType class.
FunctionType *FunctionType::get(Type *ReturnType,
ArrayRef<Type*> Params, bool isVarArg) {
- // TODO: This is brutally slow.
- unsigned ParamsSize = Params.size();
- std::vector<Type*> Key;
- Key.reserve(ParamsSize + 2);
- Key.push_back(const_cast<Type*>(ReturnType));
- for (unsigned i = 0, e = ParamsSize; i != e; ++i)
- Key.push_back(const_cast<Type*>(Params[i]));
- if (isVarArg)
- Key.push_back(0);
-
LLVMContextImpl *pImpl = ReturnType->getContext().pImpl;
- FunctionType *&FT = pImpl->FunctionTypes[Key];
-
- if (FT == 0) {
+ FunctionTypeKeyInfo::KeyTy Key(ReturnType, Params, isVarArg);
+ LLVMContextImpl::FunctionTypeMap::iterator I =
+ pImpl->FunctionTypes.find_as(Key);
+ FunctionType *FT;
+
+ if (I == pImpl->FunctionTypes.end()) {
FT = (FunctionType*) pImpl->TypeAllocator.
- Allocate(sizeof(FunctionType) + sizeof(Type*) * (ParamsSize + 1),
+ Allocate(sizeof(FunctionType) + sizeof(Type*) * (Params.size() + 1),
AlignOf<FunctionType>::Alignment);
new (FT) FunctionType(ReturnType, Params, isVarArg);
+ pImpl->FunctionTypes[FT] = true;
+ } else {
+ FT = I->first;
}
return FT;
@@ -440,24 +436,22 @@ bool FunctionType::isValidArgumentType(Type *ArgTy) {
StructType *StructType::get(LLVMContext &Context, ArrayRef<Type*> ETypes,
bool isPacked) {
- // FIXME: std::vector is horribly inefficient for this probe.
- unsigned ETypesSize = ETypes.size();
- std::vector<Type*> Key(ETypesSize);
- for (unsigned i = 0, e = ETypesSize; i != e; ++i) {
- assert(isValidElementType(ETypes[i]) &&
- "Invalid type for structure element!");
- Key[i] = ETypes[i];
+ LLVMContextImpl *pImpl = Context.pImpl;
+ AnonStructTypeKeyInfo::KeyTy Key(ETypes, isPacked);
+ LLVMContextImpl::StructTypeMap::iterator I =
+ pImpl->AnonStructTypes.find_as(Key);
+ StructType *ST;
+
+ if (I == pImpl->AnonStructTypes.end()) {
+ // Value not found. Create a new type!
+ ST = new (Context.pImpl->TypeAllocator) StructType(Context);
+ ST->setSubclassData(SCDB_IsLiteral); // Literal struct.
+ ST->setBody(ETypes, isPacked);
+ Context.pImpl->AnonStructTypes[ST] = true;
+ } else {
+ ST = I->first;
}
- if (isPacked)
- Key.push_back(0);
-
- StructType *&ST = Context.pImpl->AnonStructTypes[Key];
- if (ST) return ST;
-
- // Value not found. Create a new type!
- ST = new (Context.pImpl->TypeAllocator) StructType(Context);
- ST->setSubclassData(SCDB_IsLiteral); // Literal struct.
- ST->setBody(ETypes, isPacked);
+
return ST;
}