diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 89c35af565fde..103dcbeb79624 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -427,6 +427,14 @@ Improvements to Clang's diagnostics (or, more commonly, ``NULL`` when the platform defines it as ``__null``) to be more consistent with GCC. +Improvements to Clang's time-trace +---------------------------------- +- Two time-trace scope variables are added. A time trace scope variable of + ``ParseDeclarationOrFunctionDefinition`` with the function's source location + is added to record the time spent parsing the function's declaration or + definition. Another time trace scope variable of ``ParseFunctionDefinition`` + is also added to record the name of the defined function. + Bug Fixes in This Version ------------------------- - Fixed an issue where a class template specialization whose declaration is diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 0f930248e7717..176d2149e7318 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -13,8 +13,8 @@ #include "clang/Parse/Parser.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" -#include "clang/AST/DeclTemplate.h" #include "clang/AST/ASTLambda.h" +#include "clang/AST/DeclTemplate.h" #include "clang/Basic/FileManager.h" #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/RAIIObjectsForParser.h" @@ -22,6 +22,7 @@ #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "llvm/Support/Path.h" +#include "llvm/Support/TimeProfiler.h" using namespace clang; @@ -1229,6 +1230,13 @@ Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal( Parser::DeclGroupPtrTy Parser::ParseDeclarationOrFunctionDefinition( ParsedAttributes &Attrs, ParsedAttributes &DeclSpecAttrs, ParsingDeclSpec *DS, AccessSpecifier AS) { + // Add an enclosing time trace scope for a bunch of small scopes with + // "EvaluateAsConstExpr". + llvm::TimeTraceScope TimeScope("ParseDeclarationOrFunctionDefinition", [&]() { + return Tok.getLocation().printToString( + Actions.getASTContext().getSourceManager()); + }); + if (DS) { return ParseDeclOrFunctionDefInternal(Attrs, DeclSpecAttrs, *DS, AS); } else { @@ -1259,6 +1267,10 @@ Parser::DeclGroupPtrTy Parser::ParseDeclarationOrFunctionDefinition( Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, LateParsedAttrList *LateParsedAttrs) { + llvm::TimeTraceScope TimeScope("ParseFunctionDefinition", [&]() { + return Actions.GetNameForDeclarator(D).getName().getAsString(); + }); + // Poison SEH identifiers so they are flagged as illegal in function bodies. PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true); const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); diff --git a/clang/test/Driver/check-time-trace-ParseDeclarationOrFunctionDefinition.cpp b/clang/test/Driver/check-time-trace-ParseDeclarationOrFunctionDefinition.cpp new file mode 100644 index 0000000000000..f854cddadbfcc --- /dev/null +++ b/clang/test/Driver/check-time-trace-ParseDeclarationOrFunctionDefinition.cpp @@ -0,0 +1,15 @@ +// RUN: %clangxx -S -ftime-trace -ftime-trace-granularity=0 -o %T/check-time-trace-ParseDeclarationOrFunctionDefinition %s +// RUN: cat %T/check-time-trace-ParseDeclarationOrFunctionDefinition.json \ +// RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ +// RUN: | FileCheck %s + +// CHECK-DAG: "name": "ParseDeclarationOrFunctionDefinition" +// CHECK-DAG: "detail": "{{.*}}check-time-trace-ParseDeclarationOrFunctionDefinition.cpp:15:1" +// CHECK-DAG: "name": "ParseFunctionDefinition" +// CHECK-DAG: "detail": "foo" +// CHECK-DAG: "name": "ParseFunctionDefinition" +// CHECK-DAG: "detail": "bar" + +template +void foo(T) {} +void bar() { foo(0); } diff --git a/clang/unittests/Support/TimeProfilerTest.cpp b/clang/unittests/Support/TimeProfilerTest.cpp index a7ca2bf91e474..97fdbb7232b13 100644 --- a/clang/unittests/Support/TimeProfilerTest.cpp +++ b/clang/unittests/Support/TimeProfilerTest.cpp @@ -177,22 +177,29 @@ constexpr int slow_init_list[] = {1, 1, 2, 3, 5, 8, 13, 21}; // 25th line std::string TraceGraph = buildTraceGraph(Json); ASSERT_TRUE(TraceGraph == R"( Frontend -| EvaluateAsRValue () -| EvaluateForOverflow () -| EvaluateForOverflow () -| EvaluateAsRValue () -| EvaluateForOverflow () -| isPotentialConstantExpr (slow_namespace::slow_func) -| EvaluateAsBooleanCondition () -| | EvaluateAsRValue () -| EvaluateAsBooleanCondition () -| | EvaluateAsRValue () -| EvaluateAsInitializer (slow_value) -| EvaluateAsConstantExpr () -| EvaluateAsConstantExpr () -| EvaluateAsConstantExpr () -| EvaluateAsRValue () -| EvaluateAsInitializer (slow_init_list) +| ParseDeclarationOrFunctionDefinition (test.cc:2:1) +| ParseDeclarationOrFunctionDefinition (test.cc:6:1) +| | ParseFunctionDefinition (slow_func) +| | | EvaluateAsRValue () +| | | EvaluateForOverflow () +| | | EvaluateForOverflow () +| | | EvaluateAsRValue () +| | | EvaluateForOverflow () +| | | isPotentialConstantExpr (slow_namespace::slow_func) +| | | EvaluateAsBooleanCondition () +| | | | EvaluateAsRValue () +| | | EvaluateAsBooleanCondition () +| | | | EvaluateAsRValue () +| ParseDeclarationOrFunctionDefinition (test.cc:16:1) +| | ParseFunctionDefinition (slow_test) +| | | EvaluateAsInitializer (slow_value) +| | | EvaluateAsConstantExpr () +| | | EvaluateAsConstantExpr () +| ParseDeclarationOrFunctionDefinition (test.cc:22:1) +| | EvaluateAsConstantExpr () +| | EvaluateAsRValue () +| ParseDeclarationOrFunctionDefinition (test.cc:25:1) +| | EvaluateAsInitializer (slow_init_list) | PerformPendingInstantiations )"); @@ -213,8 +220,9 @@ struct { std::string TraceGraph = buildTraceGraph(Json); ASSERT_TRUE(TraceGraph == R"( Frontend -| isIntegerConstantExpr () -| EvaluateKnownConstIntCheckOverflow () +| ParseDeclarationOrFunctionDefinition (test.c:2:1) +| | isIntegerConstantExpr () +| | EvaluateKnownConstIntCheckOverflow () | PerformPendingInstantiations )");