[cfe-commits] r39311 - in /cfe/cfe/trunk: AST/ASTContext.cpp AST/Type.cpp include/clang/AST/ASTContext.h include/clang/AST/Type.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:42:53 PDT 2007


Author: sabre
Date: Wed Jul 11 11:42:53 2007
New Revision: 39311

URL: http://llvm.org/viewvc/llvm-project?rev=39311&view=rev
Log:
Eliminate "obviously braindead" canonicalization of function types, using
a foldingset instead.  This reduces the number of slow type lookups from
32K to 10K, which speeds up parsing of carbon.h from 11s to 3.5s.

Modified:
    cfe/cfe/trunk/AST/ASTContext.cpp
    cfe/cfe/trunk/AST/Type.cpp
    cfe/cfe/trunk/include/clang/AST/ASTContext.h
    cfe/cfe/trunk/include/clang/AST/Type.h

Modified: cfe/cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/ASTContext.cpp?rev=39311&r1=39310&r2=39311&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/cfe/trunk/AST/ASTContext.cpp Wed Jul 11 11:42:53 2007
@@ -203,27 +203,16 @@
 /// list.  isVariadic indicates whether the argument list includes '...'.
 TypeRef ASTContext::getFunctionType(TypeRef ResultTy, TypeRef *ArgArray,
                                     unsigned NumArgs, bool isVariadic) {
-  // FIXME: This is obviously braindead!
   // Unique functions, to guarantee there is only one function of a particular
   // structure.
-  ++NumSlowLookups;
-  for (unsigned i = 0, e = Types.size(); i != e; ++i) {
-    if (FunctionTypeProto *FTy = dyn_cast<FunctionTypeProto>(Types[i]))
-      if (FTy->getResultType() == ResultTy &&
-          FTy->getNumArgs() == NumArgs &&
-          FTy->isVariadic() == isVariadic) {
-        bool Match = true;
-        for (unsigned arg = 0; arg != NumArgs; ++arg) {
-          if (FTy->getArgType(arg) != ArgArray[arg]) {
-            Match = false;
-            break;
-          }
-        } 
-        if (Match)
-          return Types[i];
-      }
-  }
-  
+  FoldingSetNodeID ID;
+  FunctionTypeProto::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic);
+
+  void *InsertPos = 0;
+  if (FunctionTypeProto *FTP = 
+        FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos))
+    return FTP;
+    
   // Determine whether the type being created is already canonical or not.  
   bool isCanonical = ResultTy->isCanonical();
   for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
@@ -241,6 +230,11 @@
     Canonical = getFunctionType(ResultTy.getCanonicalType(),
                                 &CanonicalArgs[0], NumArgs,
                                 isVariadic).getTypePtr();
+    
+    // Get the new insert position for the node we care about.
+    FunctionTypeProto *NewIP =
+      FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!");
   }
   
   // FunctionTypeProto objects are not allocated with new because they have a
@@ -252,6 +246,7 @@
                               Canonical);
   
   Types.push_back(FTP);
+  FunctionTypeProtos.InsertNode(FTP, InsertPos);
   return FTP;
 }
 

Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39311&r1=39310&r2=39311&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:42:53 2007
@@ -75,6 +75,15 @@
   }
 }
 
+void FunctionTypeProto::Profile(FoldingSetNodeID &ID, TypeRef Result,
+                                TypeRef* ArgTys,
+                                unsigned NumArgs, bool isVariadic) {
+  ID.AddPointer(Result.getAsOpaquePtr());
+  for (unsigned i = 0; i != NumArgs; ++i)
+    ID.AddPointer(ArgTys[i].getAsOpaquePtr());
+  ID.AddInteger(isVariadic);
+}
+
 bool RecordType::classof(const Type *T) {
   if (const TaggedType *TT = dyn_cast<TaggedType>(T))
     return isa<RecordDecl>(TT->getDecl());

Modified: cfe/cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/ASTContext.h?rev=39311&r1=39310&r2=39311&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/cfe/trunk/include/clang/AST/ASTContext.h Wed Jul 11 11:42:53 2007
@@ -25,9 +25,9 @@
 /// ASTContext - This class holds long-lived AST nodes (such as types and
 /// decls) that can be referred to throughout the semantic analysis of a file.
 class ASTContext {
-  // FIXME: This is a stupid data structure.
   std::vector<Type*> Types;
   unsigned NumSlowLookups;
+  FoldingSet<FunctionTypeProto> FunctionTypeProtos;
 public:
   Preprocessor &PP;
   TargetInfo &Target;

Modified: cfe/cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Type.h?rev=39311&r1=39310&r2=39311&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:42:53 2007
@@ -15,9 +15,7 @@
 #define LLVM_CLANG_AST_TYPE_H
 
 #include "llvm/Support/Casting.h"
-#include "llvm/Support/DataTypes.h"
-#include <cassert>
-#include <string>
+#include "llvm/ADT/FoldingSet.h"
 
 namespace llvm {
 namespace clang {
@@ -325,7 +323,7 @@
 /// FunctionTypeProto - Represents a prototype with argument type info, e.g.
 /// 'int foo(int)' or 'int foo(void)'.  'void' is represented as having no
 /// arguments, not as having a single void argument.
-class FunctionTypeProto : public FunctionType {
+class FunctionTypeProto : public FunctionType, public FoldingSetNode {
   FunctionTypeProto(TypeRef Result, TypeRef *ArgArray, unsigned numArgs,
                     bool isVariadic, Type *Canonical)
     : FunctionType(FunctionProto, Result, isVariadic, Canonical),
@@ -357,6 +355,12 @@
     return T->getTypeClass() == FunctionProto;
   }
   static bool classof(const FunctionTypeProto *) { return true; }
+  
+  void Profile(FoldingSetNodeID &ID) {
+    Profile(ID, getResultType(), ArgInfo, NumArgs, isVariadic());
+  }
+  static void Profile(FoldingSetNodeID &ID, TypeRef Result, TypeRef* ArgTys,
+                      unsigned NumArgs, bool isVariadic);
 };
 
 





More information about the cfe-commits mailing list