diff options
| author | Jay Foad <jay.foad@gmail.com> | 2012-02-21 09:25:52 +0000 | 
|---|---|---|
| committer | Jay Foad <jay.foad@gmail.com> | 2012-02-21 09:25:52 +0000 | 
| commit | 3f99d381b4bb00cedeef049cfdcf03aa3e1f689c (patch) | |
| tree | 568b2c31a1d5e186ebd9f048bc77613579e828db /llvm/lib/VMCore/LLVMContextImpl.h | |
| parent | 6ea6de7cadfbf59f0bf2956dedceea0760aedae6 (diff) | |
| download | bcm5719-llvm-3f99d381b4bb00cedeef049cfdcf03aa3e1f689c.tar.gz bcm5719-llvm-3f99d381b4bb00cedeef049cfdcf03aa3e1f689c.zip | |
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!
llvm-svn: 151049
Diffstat (limited to 'llvm/lib/VMCore/LLVMContextImpl.h')
| -rw-r--r-- | llvm/lib/VMCore/LLVMContextImpl.h | 109 | 
1 files changed, 106 insertions, 3 deletions
| diff --git a/llvm/lib/VMCore/LLVMContextImpl.h b/llvm/lib/VMCore/LLVMContextImpl.h index a27afc08b9f..9aba73781c4 100644 --- a/llvm/lib/VMCore/LLVMContextImpl.h +++ b/llvm/lib/VMCore/LLVMContextImpl.h @@ -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 DenseMapAPFloatKeyInfo {    }  }; +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 @@ public:    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; | 

