]> granicus.if.org Git - clang/commitdiff
[AST] Memoize ASTContext::getTypeInfo().
authorDaniel Dunbar <daniel@zuster.org>
Fri, 9 Mar 2012 04:12:54 +0000 (04:12 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Fri, 9 Mar 2012 04:12:54 +0000 (04:12 +0000)
 - On -emit-llvm-only of 403.gcc/combine.c, for example, we make 160k calls to
   getTypeInfo but only ever deal with 680 some distinct types.

I saw these speedups (user time):
  403.gcc/combine.c -- 3.1%
  OmniGroupFrameworks/NSBezierPath-OAExtensions.m -- 3.6%
  JavaScriptCore/Interpreter.cpp -- 1.4%
which seems pretty sweet.

I ran some histograms on those compiles and we end up doing a ton of
getTypeInfo() on 'char' and 'int'. I tried splitting out a fast path for builtin
types, but this wasn't a win. Still kinda seems like we could be doing better
here.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152377 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
lib/AST/ASTContext.cpp

index 3bdac2de9ac09aee88bb7045998ec5670a0e7d2e..425ee3cdb23112148e23ef5576f32063906d3a91 100644 (file)
@@ -147,6 +147,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
   mutable llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*>
     ObjCLayouts;
 
+  /// TypeInfoMap - A cache from types to size and alignment information.
+  typedef llvm::DenseMap<const Type*,
+                         std::pair<uint64_t, unsigned> > TypeInfoMap;
+  mutable TypeInfoMap MemoizedTypeInfo;
+
   /// KeyFunctions - A cache mapping from CXXRecordDecls to key functions.
   llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*> KeyFunctions;
   
@@ -1220,6 +1225,7 @@ public:
 
 private:
   CanQualType getFromTargetType(unsigned Type) const;
+  std::pair<uint64_t, unsigned> getTypeInfoImpl(const Type *T) const;
 
   //===--------------------------------------------------------------------===//
   //                         Type Predicates.
index 0d6f6e612c9ffd3ab500033f45039caac31b327c..ba3f503e3b0c1c5fad14b06fd6a270c299847ba4 100644 (file)
@@ -815,14 +815,24 @@ ASTContext::getTypeInfoInChars(QualType T) const {
   return getTypeInfoInChars(T.getTypePtr());
 }
 
-/// getTypeSize - Return the size of the specified type, in bits.  This method
-/// does not work on incomplete types.
+std::pair<uint64_t, unsigned> ASTContext::getTypeInfo(const Type *T) const {
+  TypeInfoMap::iterator it = MemoizedTypeInfo.find(T);
+  if (it != MemoizedTypeInfo.end())
+    return it->second;
+
+  std::pair<uint64_t, unsigned> Info = getTypeInfoImpl(T);
+  MemoizedTypeInfo.insert(std::make_pair(T, Info));
+  return Info;
+}
+
+/// getTypeInfoImpl - Return the size of the specified type, in bits.  This
+/// method does not work on incomplete types.
 ///
 /// FIXME: Pointers into different addr spaces could have different sizes and
 /// alignment requirements: getPointerInfo should take an AddrSpace, this
 /// should take a QualType, &c.
 std::pair<uint64_t, unsigned>
-ASTContext::getTypeInfo(const Type *T) const {
+ASTContext::getTypeInfoImpl(const Type *T) const {
   uint64_t Width=0;
   unsigned Align=8;
   switch (T->getTypeClass()) {
@@ -851,7 +861,8 @@ ASTContext::getTypeInfo(const Type *T) const {
 
     std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(CAT->getElementType());
     uint64_t Size = CAT->getSize().getZExtValue();
-    assert((Size == 0 || EltInfo.first <= (uint64_t)(-1)/Size) && "Overflow in array type bit size evaluation");
+    assert((Size == 0 || EltInfo.first <= (uint64_t)(-1)/Size) && 
+           "Overflow in array type bit size evaluation");
     Width = EltInfo.first*Size;
     Align = EltInfo.second;
     Width = llvm::RoundUpToAlignment(Width, Align);