<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">On Apr 12, 2013, at 6:23 PM, Jordan Rose <<a href="mailto:jordan_rose@apple.com">jordan_rose@apple.com</a>> wrote:<br><div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">Can you promise that you will have seen all categories by the time this is first called?<br></div></blockquote><div><br></div><div>Good point. I'll look into it..</div><br><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>Jordan<br><br><br>On Apr 12, 2013, at 18:04 , Argyrios Kyrtzidis <<a href="mailto:akyrtzi@gmail.com">akyrtzi@gmail.com</a>> wrote:<br><br><blockquote type="cite">Author: akirtzidis<br>Date: Fri Apr 12 20:04:01 2013<br>New Revision: 179436<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=179436&view=rev">http://llvm.org/viewvc/llvm-project?rev=179436&view=rev</a><br>Log:<br>Speed-up ObjCMethodDecl::getOverriddenMethods().<br><br>Use an newly introduce ASTContext::getBaseObjCCategoriesAfterInterface() which caches its<br>results instead of re-calculating the categories multiple times.<br><br>Modified:<br>  cfe/trunk/include/clang/AST/ASTContext.h<br>  cfe/trunk/lib/AST/ASTContext.cpp<br>  cfe/trunk/lib/AST/DeclObjC.cpp<br><br>Modified: cfe/trunk/include/clang/AST/ASTContext.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=179436&r1=179435&r2=179436&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=179436&r1=179435&r2=179436&view=diff</a><br>==============================================================================<br>--- cfe/trunk/include/clang/AST/ASTContext.h (original)<br>+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Apr 12 20:04:01 2013<br>@@ -328,6 +328,10 @@ class ASTContext : public RefCountedBase<br> typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector;<br> llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;<br><br>+  /// \brief Used to cache results from \c getBaseObjCCategoriesAfterInterface.<br>+  mutable llvm::DenseMap<const ObjCInterfaceDecl *,<br>+            llvm::SmallVector<const ObjCCategoryDecl *, 2> > CatsAfterInterface;<br>+<br> /// \brief Mapping from each declaration context to its corresponding lambda<span class="Apple-converted-space"> </span><br> /// mangling context.<br> llvm::DenseMap<const DeclContext *, LambdaMangleContext> LambdaMangleContexts;<br>@@ -682,7 +686,12 @@ public:<br> void getOverriddenMethods(<br>                       const NamedDecl *Method,<br>                       SmallVectorImpl<const NamedDecl *> &Overridden) const;<br>-  <br>+<br>+  /// \brief Returns the ObjC categories of base classes, that were declared<br>+  /// after the given interface declaration.<br>+  void getBaseObjCCategoriesAfterInterface(const ObjCInterfaceDecl *D,<br>+                         SmallVectorImpl<const ObjCCategoryDecl *> &Cats) const;<br>+<br> /// \brief Notify the AST context that a new import declaration has been<br> /// parsed or implicitly created within this translation unit.<br> void addedLocalImportDecl(ImportDecl *Import);<br><br>Modified: cfe/trunk/lib/AST/ASTContext.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=179436&r1=179435&r2=179436&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=179436&r1=179435&r2=179436&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/AST/ASTContext.cpp (original)<br>+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Apr 12 20:04:01 2013<br>@@ -1127,8 +1127,8 @@ void ASTContext::getOverriddenMethods(<br> assert(D);<br><br> if (const CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {<br>-    Overridden.append(CXXMethod->begin_overridden_methods(),<br>-                      CXXMethod->end_overridden_methods());<br>+    Overridden.append(overridden_methods_begin(CXXMethod),<br>+                      overridden_methods_end(CXXMethod));<br>   return;<br> }<br><br>@@ -1141,6 +1141,39 @@ void ASTContext::getOverriddenMethods(<br> Overridden.append(OverDecls.begin(), OverDecls.end());<br>}<br><br>+void ASTContext::getBaseObjCCategoriesAfterInterface(<br>+                        const ObjCInterfaceDecl *D,<br>+                        SmallVectorImpl<const ObjCCategoryDecl *> &Cats) const {<br>+  if (!D)<br>+    return;<br>+  <br>+  typedef llvm::SmallVector<const ObjCCategoryDecl *, 2> VecTy;<br>+  typedef llvm::DenseMap<const ObjCInterfaceDecl *, VecTy> MapTy;<br>+  <br>+  std::pair<MapTy::iterator, bool><br>+    InsertOp = CatsAfterInterface.insert(std::make_pair(D, VecTy()));<br>+  VecTy &Vec = InsertOp.first->second;<br>+  if (!InsertOp.second) {<br>+    // already in map.<br>+    Cats.append(Vec.begin(), Vec.end());<br>+    return;<br>+  }<br>+  <br>+  SourceLocation Loc = D->getLocation();<br>+  for (const ObjCInterfaceDecl *<br>+         Class = D->getSuperClass(); Class; Class = Class->getSuperClass()) {<br>+    for (ObjCInterfaceDecl::known_categories_iterator<br>+           CatI = Class->known_categories_begin(),<br>+           CatEnd = Class->known_categories_end();<br>+         CatI != CatEnd; ++CatI) {<br>+      if (SourceMgr.isBeforeInTranslationUnit(Loc, CatI->getLocation()))<br>+        Vec.push_back(*CatI);<br>+    }<br>+  }<br>+<br>+  Cats.append(Vec.begin(), Vec.end());<br>+}<br>+<br>void ASTContext::addedLocalImportDecl(ImportDecl *Import) {<br> assert(!Import->NextLocalImport && "Import declaration already in the chain");<br> assert(!Import->isFromASTFile() && "Non-local import declaration");<br><br>Modified: cfe/trunk/lib/AST/DeclObjC.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=179436&r1=179435&r2=179436&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=179436&r1=179435&r2=179436&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/AST/DeclObjC.cpp (original)<br>+++ cfe/trunk/lib/AST/DeclObjC.cpp Fri Apr 12 20:04:01 2013<br>@@ -959,26 +959,6 @@ static void collectOverriddenMethodsSlow<br> }<br>}<br><br>-static void collectOnCategoriesAfterLocation(SourceLocation Loc,<br>-                                             const ObjCInterfaceDecl *Class,<br>-                                             SourceManager &SM,<br>-                                             const ObjCMethodDecl *Method,<br>-                             SmallVectorImpl<const ObjCMethodDecl *> &Methods) {<br>-  if (!Class)<br>-    return;<br>-<br>-  for (ObjCInterfaceDecl::known_categories_iterator<br>-         Cat = Class->known_categories_begin(),<br>-         CatEnd = Class->known_categories_end();<br>-       Cat != CatEnd; ++Cat) {<br>-    if (SM.isBeforeInTranslationUnit(Loc, Cat->getLocation()))<br>-      CollectOverriddenMethodsRecurse(*Cat, Method, Methods, true);<br>-  }<br>-  <br>-  collectOnCategoriesAfterLocation(Loc, Class->getSuperClass(), SM,<br>-                                   Method, Methods);<br>-}<br>-<br>/// \brief Faster collection that is enabled when ObjCMethodDecl::isOverriding()<br>/// returns false.<br>/// You'd think that in that case there are no overrides but categories can<br>@@ -988,7 +968,7 @@ static void collectOnCategoriesAfterLoca<br>/// further in super classes.<br>/// Methods in an implementation can overide methods in super class's category<br>/// but not in current class's category. But, such methods<br>-static void collectOverriddenMethodsFast(SourceManager &SM,<br>+static void collectOverriddenMethodsFast(ASTContext &Ctx,<br>                                        const ObjCMethodDecl *Method,<br>                            SmallVectorImpl<const ObjCMethodDecl *> &Methods) {<br> assert(!Method->isOverriding());<br>@@ -1001,8 +981,11 @@ static void collectOverriddenMethodsFast<br> if (!Class)<br>   return;<br><br>-  collectOnCategoriesAfterLocation(Class->getLocation(), Class->getSuperClass(),<br>-                                   SM, Method, Methods);<br>+  SmallVector<const ObjCCategoryDecl *, 32> Cats;<br>+  Ctx.getBaseObjCCategoriesAfterInterface(Class, Cats);<br>+  for (SmallVectorImpl<const ObjCCategoryDecl *>::iterator<br>+         I = Cats.begin(), E = Cats.end(); I != E; ++I)<br>+    CollectOverriddenMethodsRecurse(*I, Method, Methods, true);<br>}<br><br>void ObjCMethodDecl::getOverriddenMethods(<br>@@ -1015,8 +998,7 @@ void ObjCMethodDecl::getOverriddenMethod<br> }<br><br> if (!Method->isOverriding()) {<br>-    collectOverriddenMethodsFast(getASTContext().getSourceManager(),<br>-                                 Method, Overridden);<br>+    collectOverriddenMethodsFast(getASTContext(), Method, Overridden);<br> } else {<br>   collectOverriddenMethodsSlow(Method, Overridden);<br>   assert(!Overridden.empty() &&<br><br><br>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</blockquote></div></blockquote></div><br></body></html>