From 6b842e35dcd7faf2b05b2ef9b1892c29050f3607 Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Tue, 21 Feb 2012 09:25:52 +0000 Subject: 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 --- lib/VMCore/Type.cpp | 56 ++++++++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 31 deletions(-) (limited to 'lib/VMCore/Type.cpp') 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 Params, // FunctionType::get - The factory function for the FunctionType class. FunctionType *FunctionType::get(Type *ReturnType, ArrayRef Params, bool isVarArg) { - // TODO: This is brutally slow. - unsigned ParamsSize = Params.size(); - std::vector Key; - Key.reserve(ParamsSize + 2); - Key.push_back(const_cast(ReturnType)); - for (unsigned i = 0, e = ParamsSize; i != e; ++i) - Key.push_back(const_cast(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::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 ETypes, bool isPacked) { - // FIXME: std::vector is horribly inefficient for this probe. - unsigned ETypesSize = ETypes.size(); - std::vector 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; } -- cgit v1.2.3