[llvm-commits] [llvm] r151049 - in /llvm/trunk/lib/VMCore: LLVMContextImpl.h Type.cpp
Duncan Sands
baldrick at free.fr
Tue Feb 21 01:56:15 PST 2012
Hi Jay, this nightly test builder
http://lab.llvm.org:8011/builders/clang-x86_64-debian-fnt
is showing many failures since your commit.
Ciao, Duncan.
On 21/02/12 10:25, Jay Foad wrote:
> Author: foad
> Date: Tue Feb 21 03:25:52 2012
> New Revision: 151049
>
> URL: http://llvm.org/viewvc/llvm-project?rev=151049&view=rev
> Log:
> 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!
>
> Modified:
> llvm/trunk/lib/VMCore/LLVMContextImpl.h
> llvm/trunk/lib/VMCore/Type.cpp
>
> Modified: llvm/trunk/lib/VMCore/LLVMContextImpl.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/LLVMContextImpl.h?rev=151049&r1=151048&r2=151049&view=diff
> ==============================================================================
> --- llvm/trunk/lib/VMCore/LLVMContextImpl.h (original)
> +++ llvm/trunk/lib/VMCore/LLVMContextImpl.h Tue Feb 21 03:25:52 2012
> @@ -29,6 +29,7 @@
> #include "llvm/ADT/FoldingSet.h"
> #include "llvm/ADT/SmallPtrSet.h"
> #include "llvm/ADT/StringMap.h"
> +#include "llvm/ADT/Hashing.h"
> #include<vector>
>
> namespace llvm {
> @@ -89,6 +90,107 @@
> }
> };
>
> +struct AnonStructTypeKeyInfo {
> + struct KeyTy {
> + ArrayRef<Type*> ETypes;
> + bool isPacked;
> + KeyTy(const ArrayRef<Type*>& E, bool P) :
> + ETypes(E), isPacked(P) {}
> + KeyTy(const KeyTy& that) :
> + ETypes(that.ETypes), isPacked(that.isPacked) {}
> + KeyTy(const StructType* ST) :
> + ETypes(ArrayRef<Type*>(ST->element_begin(), ST->element_end())),
> + isPacked(ST->isPacked()) {}
> + bool operator==(const KeyTy& that) const {
> + if (isPacked != that.isPacked)
> + return false;
> + if (ETypes != that.ETypes)
> + return false;
> + return true;
> + }
> + bool operator!=(const KeyTy& that) const {
> + return !this->operator==(that);
> + }
> + };
> + static inline StructType* getEmptyKey() {
> + return DenseMapInfo<StructType*>::getEmptyKey();
> + }
> + static inline StructType* getTombstoneKey() {
> + return DenseMapInfo<StructType*>::getTombstoneKey();
> + }
> + static unsigned getHashValue(const KeyTy& Key) {
> + GeneralHash Hash;
> + Hash.add(Key.ETypes);
> + Hash.add(Key.isPacked);
> + return Hash.finish();
> + }
> + static unsigned getHashValue(const StructType *ST) {
> + return getHashValue(KeyTy(ST));
> + }
> + static bool isEqual(const KeyTy& LHS, const StructType *RHS) {
> + if (RHS == getEmptyKey() || RHS == getTombstoneKey())
> + return false;
> + return LHS == KeyTy(RHS);
> + }
> + static bool isEqual(const StructType *LHS, const StructType *RHS) {
> + return LHS == RHS;
> + }
> +};
> +
> +struct FunctionTypeKeyInfo {
> + struct KeyTy {
> + const Type *ReturnType;
> + ArrayRef<Type*> Params;
> + bool isVarArg;
> + KeyTy(const Type* R, const ArrayRef<Type*>& P, bool V) :
> + ReturnType(R), Params(P), isVarArg(V) {}
> + KeyTy(const KeyTy& that) :
> + ReturnType(that.ReturnType),
> + Params(that.Params),
> + isVarArg(that.isVarArg) {}
> + KeyTy(const FunctionType* FT) :
> + ReturnType(FT->getReturnType()),
> + Params(ArrayRef<Type*>(FT->param_begin(), FT->param_end())),
> + isVarArg(FT->isVarArg()) {}
> + bool operator==(const KeyTy& that) const {
> + if (ReturnType != that.ReturnType)
> + return false;
> + if (isVarArg != that.isVarArg)
> + return false;
> + if (Params != that.Params)
> + return false;
> + return true;
> + }
> + bool operator!=(const KeyTy& that) const {
> + return !this->operator==(that);
> + }
> + };
> + static inline FunctionType* getEmptyKey() {
> + return DenseMapInfo<FunctionType*>::getEmptyKey();
> + }
> + static inline FunctionType* getTombstoneKey() {
> + return DenseMapInfo<FunctionType*>::getTombstoneKey();
> + }
> + static unsigned getHashValue(const KeyTy& Key) {
> + GeneralHash Hash;
> + Hash.add(Key.ReturnType);
> + Hash.add(Key.Params);
> + Hash.add(Key.isVarArg);
> + return Hash.finish();
> + }
> + static unsigned getHashValue(const FunctionType *FT) {
> + return getHashValue(KeyTy(FT));
> + }
> + static bool isEqual(const KeyTy& LHS, const FunctionType *RHS) {
> + if (RHS == getEmptyKey() || RHS == getTombstoneKey())
> + return false;
> + return LHS == KeyTy(RHS);
> + }
> + static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) {
> + return LHS == RHS;
> + }
> +};
> +
> /// DebugRecVH - This is a CallbackVH used to keep the Scope -> index maps
> /// up to date as MDNodes mutate. This class is implemented in DebugLoc.cpp.
> class DebugRecVH : public CallbackVH {
> @@ -180,9 +282,10 @@
>
> DenseMap<unsigned, IntegerType*> IntegerTypes;
>
> - // TODO: Optimize FunctionTypes/AnonStructTypes!
> - std::map<std::vector<Type*>, FunctionType*> FunctionTypes;
> - std::map<std::vector<Type*>, StructType*> AnonStructTypes;
> + typedef DenseMap<FunctionType*, bool, FunctionTypeKeyInfo> FunctionTypeMap;
> + FunctionTypeMap FunctionTypes;
> + typedef DenseMap<StructType*, bool, AnonStructTypeKeyInfo> StructTypeMap;
> + StructTypeMap AnonStructTypes;
> StringMap<StructType*> NamedStructTypes;
> unsigned NamedStructTypesUniqueID;
>
>
> Modified: llvm/trunk/lib/VMCore/Type.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Type.cpp?rev=151049&r1=151048&r2=151049&view=diff
> ==============================================================================
> --- llvm/trunk/lib/VMCore/Type.cpp (original)
> +++ llvm/trunk/lib/VMCore/Type.cpp Tue Feb 21 03:25:52 2012
> @@ -390,24 +390,20 @@
> // 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 @@
>
> 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;
> }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list