r179436 - Speed-up ObjCMethodDecl::getOverriddenMethods().

Jordan Rose jordan_rose at apple.com
Fri Apr 12 18:23:34 PDT 2013


Can you promise that you will have seen all categories by the time this is first called?

Jordan


On Apr 12, 2013, at 18:04 , Argyrios Kyrtzidis <akyrtzi at gmail.com> wrote:

> Author: akirtzidis
> Date: Fri Apr 12 20:04:01 2013
> New Revision: 179436
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=179436&view=rev
> Log:
> Speed-up ObjCMethodDecl::getOverriddenMethods().
> 
> Use an newly introduce ASTContext::getBaseObjCCategoriesAfterInterface() which caches its
> results instead of re-calculating the categories multiple times.
> 
> Modified:
>    cfe/trunk/include/clang/AST/ASTContext.h
>    cfe/trunk/lib/AST/ASTContext.cpp
>    cfe/trunk/lib/AST/DeclObjC.cpp
> 
> Modified: cfe/trunk/include/clang/AST/ASTContext.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=179436&r1=179435&r2=179436&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> +++ cfe/trunk/include/clang/AST/ASTContext.h Fri Apr 12 20:04:01 2013
> @@ -328,6 +328,10 @@ class ASTContext : public RefCountedBase
>   typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector;
>   llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
> 
> +  /// \brief Used to cache results from \c getBaseObjCCategoriesAfterInterface.
> +  mutable llvm::DenseMap<const ObjCInterfaceDecl *,
> +            llvm::SmallVector<const ObjCCategoryDecl *, 2> > CatsAfterInterface;
> +
>   /// \brief Mapping from each declaration context to its corresponding lambda 
>   /// mangling context.
>   llvm::DenseMap<const DeclContext *, LambdaMangleContext> LambdaMangleContexts;
> @@ -682,7 +686,12 @@ public:
>   void getOverriddenMethods(
>                         const NamedDecl *Method,
>                         SmallVectorImpl<const NamedDecl *> &Overridden) const;
> -  
> +
> +  /// \brief Returns the ObjC categories of base classes, that were declared
> +  /// after the given interface declaration.
> +  void getBaseObjCCategoriesAfterInterface(const ObjCInterfaceDecl *D,
> +                         SmallVectorImpl<const ObjCCategoryDecl *> &Cats) const;
> +
>   /// \brief Notify the AST context that a new import declaration has been
>   /// parsed or implicitly created within this translation unit.
>   void addedLocalImportDecl(ImportDecl *Import);
> 
> Modified: cfe/trunk/lib/AST/ASTContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=179436&r1=179435&r2=179436&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
> +++ cfe/trunk/lib/AST/ASTContext.cpp Fri Apr 12 20:04:01 2013
> @@ -1127,8 +1127,8 @@ void ASTContext::getOverriddenMethods(
>   assert(D);
> 
>   if (const CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
> -    Overridden.append(CXXMethod->begin_overridden_methods(),
> -                      CXXMethod->end_overridden_methods());
> +    Overridden.append(overridden_methods_begin(CXXMethod),
> +                      overridden_methods_end(CXXMethod));
>     return;
>   }
> 
> @@ -1141,6 +1141,39 @@ void ASTContext::getOverriddenMethods(
>   Overridden.append(OverDecls.begin(), OverDecls.end());
> }
> 
> +void ASTContext::getBaseObjCCategoriesAfterInterface(
> +                        const ObjCInterfaceDecl *D,
> +                        SmallVectorImpl<const ObjCCategoryDecl *> &Cats) const {
> +  if (!D)
> +    return;
> +  
> +  typedef llvm::SmallVector<const ObjCCategoryDecl *, 2> VecTy;
> +  typedef llvm::DenseMap<const ObjCInterfaceDecl *, VecTy> MapTy;
> +  
> +  std::pair<MapTy::iterator, bool>
> +    InsertOp = CatsAfterInterface.insert(std::make_pair(D, VecTy()));
> +  VecTy &Vec = InsertOp.first->second;
> +  if (!InsertOp.second) {
> +    // already in map.
> +    Cats.append(Vec.begin(), Vec.end());
> +    return;
> +  }
> +  
> +  SourceLocation Loc = D->getLocation();
> +  for (const ObjCInterfaceDecl *
> +         Class = D->getSuperClass(); Class; Class = Class->getSuperClass()) {
> +    for (ObjCInterfaceDecl::known_categories_iterator
> +           CatI = Class->known_categories_begin(),
> +           CatEnd = Class->known_categories_end();
> +         CatI != CatEnd; ++CatI) {
> +      if (SourceMgr.isBeforeInTranslationUnit(Loc, CatI->getLocation()))
> +        Vec.push_back(*CatI);
> +    }
> +  }
> +
> +  Cats.append(Vec.begin(), Vec.end());
> +}
> +
> void ASTContext::addedLocalImportDecl(ImportDecl *Import) {
>   assert(!Import->NextLocalImport && "Import declaration already in the chain");
>   assert(!Import->isFromASTFile() && "Non-local import declaration");
> 
> Modified: cfe/trunk/lib/AST/DeclObjC.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=179436&r1=179435&r2=179436&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/DeclObjC.cpp (original)
> +++ cfe/trunk/lib/AST/DeclObjC.cpp Fri Apr 12 20:04:01 2013
> @@ -959,26 +959,6 @@ static void collectOverriddenMethodsSlow
>   }
> }
> 
> -static void collectOnCategoriesAfterLocation(SourceLocation Loc,
> -                                             const ObjCInterfaceDecl *Class,
> -                                             SourceManager &SM,
> -                                             const ObjCMethodDecl *Method,
> -                             SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
> -  if (!Class)
> -    return;
> -
> -  for (ObjCInterfaceDecl::known_categories_iterator
> -         Cat = Class->known_categories_begin(),
> -         CatEnd = Class->known_categories_end();
> -       Cat != CatEnd; ++Cat) {
> -    if (SM.isBeforeInTranslationUnit(Loc, Cat->getLocation()))
> -      CollectOverriddenMethodsRecurse(*Cat, Method, Methods, true);
> -  }
> -  
> -  collectOnCategoriesAfterLocation(Loc, Class->getSuperClass(), SM,
> -                                   Method, Methods);
> -}
> -
> /// \brief Faster collection that is enabled when ObjCMethodDecl::isOverriding()
> /// returns false.
> /// You'd think that in that case there are no overrides but categories can
> @@ -988,7 +968,7 @@ static void collectOnCategoriesAfterLoca
> /// further in super classes.
> /// Methods in an implementation can overide methods in super class's category
> /// but not in current class's category. But, such methods
> -static void collectOverriddenMethodsFast(SourceManager &SM,
> +static void collectOverriddenMethodsFast(ASTContext &Ctx,
>                                          const ObjCMethodDecl *Method,
>                              SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
>   assert(!Method->isOverriding());
> @@ -1001,8 +981,11 @@ static void collectOverriddenMethodsFast
>   if (!Class)
>     return;
> 
> -  collectOnCategoriesAfterLocation(Class->getLocation(), Class->getSuperClass(),
> -                                   SM, Method, Methods);
> +  SmallVector<const ObjCCategoryDecl *, 32> Cats;
> +  Ctx.getBaseObjCCategoriesAfterInterface(Class, Cats);
> +  for (SmallVectorImpl<const ObjCCategoryDecl *>::iterator
> +         I = Cats.begin(), E = Cats.end(); I != E; ++I)
> +    CollectOverriddenMethodsRecurse(*I, Method, Methods, true);
> }
> 
> void ObjCMethodDecl::getOverriddenMethods(
> @@ -1015,8 +998,7 @@ void ObjCMethodDecl::getOverriddenMethod
>   }
> 
>   if (!Method->isOverriding()) {
> -    collectOverriddenMethodsFast(getASTContext().getSourceManager(),
> -                                 Method, Overridden);
> +    collectOverriddenMethodsFast(getASTContext(), Method, Overridden);
>   } else {
>     collectOverriddenMethodsSlow(Method, Overridden);
>     assert(!Overridden.empty() &&
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list