From: Douglas Gregor Date: Tue, 30 Mar 2010 18:56:13 +0000 (+0000) Subject: Introduce new AST statistics that keep track of the number of isa (or X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f540305c5d834ad9412b41805b81a74249b7c5af;p=clang Introduce new AST statistics that keep track of the number of isa (or dyn_cast) invocations for C++ and Objective-C types, declarations, expressions, and statements. The statistics will be printed when -print-stats is provided to Clang -cc1, with results such as: 277073 clang - Number of checks for C++ declaration nodes 13311 clang - Number of checks for C++ expression nodes 18 clang - Number of checks for C++ statement nodes 174182 clang - Number of checks for C++ type nodes 92300 clang - Number of checks for Objective-C declaration nodes 9800 clang - Number of checks for Objective-C expression nodes 7 clang - Number of checks for Objective-C statement nodes 65733 clang - Number of checks for Objective-C type nodes The statistics are only gathered when NDEBUG is not defined, since they introduce potentially-expensive operations into very low-level routines (isa). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99912 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index d5913e236c..8021873352 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_DECLBASE_H #include "clang/AST/Attr.h" +#include "clang/AST/Statistics.h" #include "clang/AST/Type.h" #include "clang/Basic/Specifiers.h" #include "llvm/Support/PrettyStackTrace.h" @@ -1069,6 +1070,15 @@ struct cast_convert_decl_context { } }; +#ifndef NDEBUG + /// \brief The number of times we have dynamically checked for an + /// Objective-C-specific declaration node. + extern llvm::Statistic objc_decl_checks; + + /// \brief The number of times we have dynamically checked for a + /// C++-specific declaration node. + extern llvm::Statistic cxx_decl_checks; +#endif } // end clang. diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 1a1bf4e481..2ed2cefe5d 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -1881,4 +1881,18 @@ const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, } // end namespace clang +// Enumerate C++ declarations +CLANG_ISA_STATISTIC(NamespaceDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(UsingDirectiveDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(NamespaceAliasDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(CXXRecordDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(CXXMethodDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(CXXConstructorDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(CXXDestructorDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(CXXConversionDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(UsingDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(UsingShadowDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(LinkageSpecDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(StaticAssertDecl, cxx_decl_checks) + #endif diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h index 99ef738980..c17dae8665 100644 --- a/include/clang/AST/DeclFriend.h +++ b/include/clang/AST/DeclFriend.h @@ -164,4 +164,7 @@ inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) { } +// Enumerate C++ declarations +CLANG_ISA_STATISTIC(FriendDecl, cxx_decl_checks) + #endif diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index a1f565341e..4db0c7b25e 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -1397,4 +1397,22 @@ public: }; } // end namespace clang + +// Enumerate Objective-C declarations +CLANG_ISA_STATISTIC(ObjCIvarDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCAtDefsFieldDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCMethodDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCContainerDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCCategoryDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCProtocolDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCInterfaceDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCImplDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCCategoryImplDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCImplementationDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCPropertyDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCCompatibleAliasDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCPropertyImplDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCForwardProtocolDecl, objc_decl_checks) +CLANG_ISA_STATISTIC(ObjCClassDecl, objc_decl_checks) + #endif diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 8d1a4caccb..dee0a8614c 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -1314,4 +1314,17 @@ inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD) } /* end of namespace clang */ +// Enumerate C++ declarations +CLANG_ISA_STATISTIC(UnresolvedUsingTypenameDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(ClassTemplateSpecializationDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(ClassTemplatePartialSpecializationDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(TemplateTypeParmDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(UnresolvedUsingValueDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(NonTypeTemplateParmDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(TemplateDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(FunctionTemplateDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(ClassTemplateDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(TemplateTemplateParmDecl, cxx_decl_checks) +CLANG_ISA_STATISTIC(FriendTemplateDecl, cxx_decl_checks) + #endif diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 6b14e47cbe..39530dba36 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -3058,6 +3058,15 @@ public: virtual child_iterator child_end(); }; +#ifndef NDEBUG + /// \brief The number of times we have dynamically checked for an + /// Objective-C-specific expression node. + extern llvm::Statistic objc_expr_checks; + + /// \brief The number of times we have dynamically checked for a + /// C++-specific expression node. + extern llvm::Statistic cxx_expr_checks; +#endif } // end namespace clang #endif diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index d1351b8b14..afab9679e6 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -2134,4 +2134,35 @@ inline ExplicitTemplateArgumentList &OverloadExpr::getExplicitTemplateArgs() { } // end namespace clang +// Enumerate C++ expressions +CLANG_ISA_STATISTIC(CXXOperatorCallExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXMemberCallExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXNamedCastExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXStaticCastExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXDynamicCastExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXReinterpretCastExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXConstCastExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXFunctionalCastExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXTypeidExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXBoolLiteralExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXNullPtrLiteralExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXThisExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXThrowExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXDefaultArgExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXZeroInitValueExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXNewExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXDeleteExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXPseudoDestructorExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(UnresolvedLookupExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(UnaryTypeTraitExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(DependentScopeDeclRefExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXConstructExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXBindTemporaryExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXBindReferenceExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXExprWithTemporaries, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXTemporaryObjectExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXUnresolvedConstructExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(CXXDependentScopeMemberExpr, cxx_expr_checks) +CLANG_ISA_STATISTIC(UnresolvedMemberExpr, cxx_expr_checks) + #endif diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 6f43973a3e..6a0120b78b 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -577,4 +577,16 @@ public: } // end namespace clang +// Enumerate Objective-C expressions +CLANG_ISA_STATISTIC(ObjCStringLiteral, objc_expr_checks) +CLANG_ISA_STATISTIC(ObjCEncodeExpr, objc_expr_checks) +CLANG_ISA_STATISTIC(ObjCMessageExpr, objc_expr_checks) +CLANG_ISA_STATISTIC(ObjCSelectorExpr, objc_expr_checks) +CLANG_ISA_STATISTIC(ObjCProtocolExpr, objc_expr_checks) +CLANG_ISA_STATISTIC(ObjCIvarRefExpr, objc_expr_checks) +CLANG_ISA_STATISTIC(ObjCPropertyRefExpr, objc_expr_checks) +CLANG_ISA_STATISTIC(ObjCImplicitSetterGetterRefExpr, objc_expr_checks) +CLANG_ISA_STATISTIC(ObjCSuperExpr, objc_expr_checks) +CLANG_ISA_STATISTIC(ObjCIsaExpr, objc_expr_checks) + #endif diff --git a/include/clang/AST/Statistics.h b/include/clang/AST/Statistics.h new file mode 100644 index 0000000000..052135b8f6 --- /dev/null +++ b/include/clang/AST/Statistics.h @@ -0,0 +1,43 @@ +//===--- Statistics.h - Helpers for Clang AST Statistics --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides helper classes, functions, and macros for tracking +// various statistics about the Clang AST and its usage. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_AST_STATISTICS_H +#define LLVM_CLANG_AST_STATISTICS_H + +#ifndef NDEBUG +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/Casting.h" + +/** \brief Tracks the number of time the \c isa() function template is + * used to try to cast to the given \c Type, by bumping the \c Counter. + * + * Note that this macro must be expanded in the global scope, and that + * both the type and the counter will be assumed to reside within the + * \c clang namespace. + */ +#define CLANG_ISA_STATISTIC(Type,Counter) \ +namespace llvm { \ +template \ +struct isa_impl { \ + static inline bool doit(const From &Val) { \ + ++clang::Counter; \ + return clang::Type::classof(&Val); \ + } \ +}; \ +} + +#else +#define CLANG_ISA_STATISTIC(Type,Counter) +#endif + +#endif // LLVM_CLANG_AST_STATISTICS_H diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 466848976c..be59427d83 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -21,6 +21,7 @@ #include "clang/AST/StmtIterator.h" #include "clang/AST/DeclGroup.h" #include "clang/AST/FullExpr.h" +#include "clang/AST/Statistics.h" #include "llvm/ADT/SmallVector.h" #include "clang/AST/ASTContext.h" #include @@ -1360,6 +1361,16 @@ public: virtual child_iterator child_end(); }; +#ifndef NDEBUG + /// \brief The number of times we have dynamically checked for an + /// Objective-C-specific statement node. + extern llvm::Statistic objc_stmt_checks; + + /// \brief The number of times we have dynamically checked for a + /// C++-specific statement node. + extern llvm::Statistic cxx_stmt_checks; +#endif + } // end namespace clang #endif diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h index 4e87c2701c..4e3b32a9f9 100644 --- a/include/clang/AST/StmtCXX.h +++ b/include/clang/AST/StmtCXX.h @@ -107,7 +107,10 @@ public: virtual child_iterator child_end(); }; - } // end namespace clang +// Enumerate C++ statements +CLANG_ISA_STATISTIC(CXXCatchStmt, cxx_stmt_checks) +CLANG_ISA_STATISTIC(CXXTryStmt, cxx_stmt_checks) + #endif diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h index 3fd8f1672d..c9caed18b1 100644 --- a/include/clang/AST/StmtObjC.h +++ b/include/clang/AST/StmtObjC.h @@ -304,4 +304,12 @@ public: } // end namespace clang +// Enumerate Objective-C statements +CLANG_ISA_STATISTIC(ObjCAtTryStmt, objc_stmt_checks) +CLANG_ISA_STATISTIC(ObjCAtCatchStmt, objc_stmt_checks) +CLANG_ISA_STATISTIC(ObjCAtFinallyStmt, objc_stmt_checks) +CLANG_ISA_STATISTIC(ObjCAtThrowStmt, objc_stmt_checks) +CLANG_ISA_STATISTIC(ObjCAtSynchronizedStmt, objc_stmt_checks) +CLANG_ISA_STATISTIC(ObjCForCollectionStmt, objc_stmt_checks) + #endif diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index e9368e8866..eee1183495 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -18,6 +18,7 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/Linkage.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/Statistics.h" #include "clang/AST/TemplateName.h" #include "llvm/Support/Casting.h" #include "llvm/Support/type_traits.h" @@ -3179,6 +3180,35 @@ template const T *Type::getAs() const { return cast(getUnqualifiedDesugaredType()); } +#ifndef NDEBUG + /// \brief The number of times we have dynamically checked for an + /// Objective-C-specific type node. + extern llvm::Statistic objc_type_checks; + + /// \brief The number of times we have dynamically checked for a + /// C++-specific type node. + extern llvm::Statistic cxx_type_checks; +#endif } // end namespace clang +// Enumerate Objective-C types +CLANG_ISA_STATISTIC(ObjCInterfaceType, objc_type_checks) +CLANG_ISA_STATISTIC(ObjCObjectPointerType, objc_type_checks) + +// Enumerate C++ types +CLANG_ISA_STATISTIC(ReferenceType, cxx_type_checks) +CLANG_ISA_STATISTIC(LValueReferenceType, cxx_type_checks) +CLANG_ISA_STATISTIC(RValueReferenceType, cxx_type_checks) +CLANG_ISA_STATISTIC(MemberPointerType, cxx_type_checks) +CLANG_ISA_STATISTIC(DependentSizedArrayType, cxx_type_checks) +CLANG_ISA_STATISTIC(DependentSizedExtVectorType, cxx_type_checks) +CLANG_ISA_STATISTIC(UnresolvedUsingType, cxx_type_checks) +CLANG_ISA_STATISTIC(DecltypeType, cxx_type_checks) +CLANG_ISA_STATISTIC(TemplateTypeParmType, cxx_type_checks) +CLANG_ISA_STATISTIC(SubstTemplateTypeParmType, cxx_type_checks) +CLANG_ISA_STATISTIC(TemplateSpecializationType, cxx_type_checks) +CLANG_ISA_STATISTIC(QualifiedNameType, cxx_type_checks) +CLANG_ISA_STATISTIC(InjectedClassNameType, cxx_type_checks) +CLANG_ISA_STATISTIC(TypenameType, cxx_type_checks) + #endif diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index c693e153dd..522875f64f 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -35,6 +35,13 @@ using namespace clang; // Statistics //===----------------------------------------------------------------------===// +#ifndef NDEBUG +llvm::Statistic clang::objc_decl_checks = + { "clang", "Number of checks for Objective-C declaration nodes", 0, 0 }; +llvm::Statistic clang::cxx_decl_checks = + { "clang", "Number of checks for C++ declaration nodes", 0, 0 }; +#endif + #define DECL(Derived, Base) static int n##Derived##s = 0; #include "clang/AST/DeclNodes.def" diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index b4e5a5d960..935a2080dc 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -27,6 +27,13 @@ #include using namespace clang; +#ifndef NDEBUG +llvm::Statistic clang::objc_expr_checks = + { "clang", "Number of checks for Objective-C expression nodes", 0, 0 }; +llvm::Statistic clang::cxx_expr_checks = + { "clang", "Number of checks for C++ expression nodes", 0, 0 }; +#endif + //===----------------------------------------------------------------------===// // Primary Expressions. //===----------------------------------------------------------------------===// diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 8347249a46..bb6db228d2 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -22,6 +22,13 @@ #include using namespace clang; +#ifndef NDEBUG +llvm::Statistic clang::objc_stmt_checks = + { "clang", "Number of checks for Objective-C statement nodes", 0, 0 }; +llvm::Statistic clang::cxx_stmt_checks = + { "clang", "Number of checks for C++ statement nodes", 0, 0 }; +#endif + static struct StmtClassNameTable { const char *Name; unsigned Counter; diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 8a64f8ea97..22dd2ecd64 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -22,6 +22,13 @@ #include "llvm/Support/raw_ostream.h" using namespace clang; +#ifndef NDEBUG +llvm::Statistic clang::objc_type_checks = + { "clang", "Number of checks for Objective-C type nodes", 0, 0 }; +llvm::Statistic clang::cxx_type_checks = + { "clang", "Number of checks for C++ type nodes", 0, 0 }; +#endif + bool QualType::isConstant(QualType T, ASTContext &Ctx) { if (T.isConstQualified()) return true;