https://github.com/MaggieYingYi updated https://github.com/llvm/llvm-project/pull/65268
>From cc5cf9500cbdbb2fdd332c7de26c0516e49594bf Mon Sep 17 00:00:00 2001 From: Ying Yi <maggieyi...@gmail.com> Date: Fri, 1 Sep 2023 15:30:44 +0100 Subject: [PATCH 1/3] Add a new time trace scope variable named "ParseDeclarationOrFunctionDefinition". When profiling code using `-ftime-trace` with the default `time-trace-granularity` value (500 microseconds), in some code there is a large empty timeline in the flame chart profiling view (using Chrome Tracing view). If you pass `-ftime-trace-granularity=0` in order to show all time traces, the empty timeline consists of a large number of small time scopes named `EvaluateAsConstExpr`. This change adds an enclosing time trace scope for the function `Parser::ParseDeclarationOrFunctionDefinition` to record the time spent parsing the function's declaration or definition. --- clang/lib/Parse/Parser.cpp | 6 ++- ...e-ParseDeclarationOrFunctionDefinition.cpp | 10 +++++ clang/unittests/Support/TimeProfilerTest.cpp | 42 +++++++++++-------- 3 files changed, 39 insertions(+), 19 deletions(-) create mode 100644 clang/test/Driver/check-time-trace-ParseDeclarationOrFunctionDefinition.cpp diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 0f930248e77174b..ef0d98d60746f9c 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,9 @@ 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"); if (DS) { return ParseDeclOrFunctionDefInternal(Attrs, DeclSpecAttrs, *DS, AS); } else { 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 000000000000000..be1cc51cc6669f3 --- /dev/null +++ b/clang/test/Driver/check-time-trace-ParseDeclarationOrFunctionDefinition.cpp @@ -0,0 +1,10 @@ +// 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: "name": "ParseDeclarationOrFunctionDefinition" + +template <typename T> +void foo(T) {} +void bar() { foo(0); } diff --git a/clang/unittests/Support/TimeProfilerTest.cpp b/clang/unittests/Support/TimeProfilerTest.cpp index a7ca2bf91e474ef..62b37ab5c5e6424 100644 --- a/clang/unittests/Support/TimeProfilerTest.cpp +++ b/clang/unittests/Support/TimeProfilerTest.cpp @@ -177,22 +177,27 @@ 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 (<test.cc:8:21>) -| EvaluateForOverflow (<test.cc:8:21, col:25>) -| EvaluateForOverflow (<test.cc:8:30, col:32>) -| EvaluateAsRValue (<test.cc:9:14>) -| EvaluateForOverflow (<test.cc:9:9, col:14>) -| isPotentialConstantExpr (slow_namespace::slow_func) -| EvaluateAsBooleanCondition (<test.cc:8:21, col:25>) -| | EvaluateAsRValue (<test.cc:8:21, col:25>) -| EvaluateAsBooleanCondition (<test.cc:8:21, col:25>) -| | EvaluateAsRValue (<test.cc:8:21, col:25>) -| EvaluateAsInitializer (slow_value) -| EvaluateAsConstantExpr (<test.cc:17:33, col:59>) -| EvaluateAsConstantExpr (<test.cc:18:11, col:37>) -| EvaluateAsConstantExpr (<test.cc:23:31, col:57>) -| EvaluateAsRValue (<test.cc:22:14, line:23:58>) -| EvaluateAsInitializer (slow_init_list) +| ParseDeclarationOrFunctionDefinition +| ParseDeclarationOrFunctionDefinition +| | EvaluateAsRValue (<test.cc:8:21>) +| | EvaluateForOverflow (<test.cc:8:21, col:25>) +| | EvaluateForOverflow (<test.cc:8:30, col:32>) +| | EvaluateAsRValue (<test.cc:9:14>) +| | EvaluateForOverflow (<test.cc:9:9, col:14>) +| | isPotentialConstantExpr (slow_namespace::slow_func) +| | EvaluateAsBooleanCondition (<test.cc:8:21, col:25>) +| | | EvaluateAsRValue (<test.cc:8:21, col:25>) +| | EvaluateAsBooleanCondition (<test.cc:8:21, col:25>) +| | | EvaluateAsRValue (<test.cc:8:21, col:25>) +| ParseDeclarationOrFunctionDefinition +| | EvaluateAsInitializer (slow_value) +| | EvaluateAsConstantExpr (<test.cc:17:33, col:59>) +| | EvaluateAsConstantExpr (<test.cc:18:11, col:37>) +| | EvaluateAsConstantExpr (<test.cc:23:31, col:57>) +| ParseDeclarationOrFunctionDefinition +| | EvaluateAsRValue (<test.cc:22:14, line:23:58>) +| ParseDeclarationOrFunctionDefinition +| | EvaluateAsInitializer (slow_init_list) | PerformPendingInstantiations )"); @@ -213,8 +218,9 @@ struct { std::string TraceGraph = buildTraceGraph(Json); ASSERT_TRUE(TraceGraph == R"( Frontend -| isIntegerConstantExpr (<test.c:3:18>) -| EvaluateKnownConstIntCheckOverflow (<test.c:3:18>) +| ParseDeclarationOrFunctionDefinition +| | isIntegerConstantExpr (<test.c:3:18>) +| | EvaluateKnownConstIntCheckOverflow (<test.c:3:18>) | PerformPendingInstantiations )"); >From deecf8c2607890993b0a2b19fb82fce3fd657106 Mon Sep 17 00:00:00 2001 From: Ying Yi <maggieyi...@gmail.com> Date: Thu, 12 Oct 2023 09:22:50 +0100 Subject: [PATCH 2/3] Add a new time trace variable to record the name of the defined function. --- clang/lib/Parse/Parser.cpp | 4 +++ ...e-ParseDeclarationOrFunctionDefinition.cpp | 6 +++- clang/unittests/Support/TimeProfilerTest.cpp | 30 ++++++++++--------- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index ef0d98d60746f9c..533a9af173178b0 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1263,6 +1263,10 @@ Parser::DeclGroupPtrTy Parser::ParseDeclarationOrFunctionDefinition( Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, LateParsedAttrList *LateParsedAttrs) { + llvm::TimeTraceScope TimeScope( + "ParseFunctionDefinition", + 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 index be1cc51cc6669f3..96bb37d57823e8b 100644 --- a/clang/test/Driver/check-time-trace-ParseDeclarationOrFunctionDefinition.cpp +++ b/clang/test/Driver/check-time-trace-ParseDeclarationOrFunctionDefinition.cpp @@ -3,7 +3,11 @@ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s -// CHECK: "name": "ParseDeclarationOrFunctionDefinition" +// CHECK-DAG: "name": "ParseDeclarationOrFunctionDefinition" +// CHECK-DAG: "name": "ParseFunctionDefinition" +// CHECK-DAG: "detail": "foo" +// CHECK-DAG: "name": "ParseFunctionDefinition" +// CHECK-DAG: "detail": "bar" template <typename T> void foo(T) {} diff --git a/clang/unittests/Support/TimeProfilerTest.cpp b/clang/unittests/Support/TimeProfilerTest.cpp index 62b37ab5c5e6424..f69a54692b0072a 100644 --- a/clang/unittests/Support/TimeProfilerTest.cpp +++ b/clang/unittests/Support/TimeProfilerTest.cpp @@ -179,22 +179,24 @@ constexpr int slow_init_list[] = {1, 1, 2, 3, 5, 8, 13, 21}; // 25th line Frontend | ParseDeclarationOrFunctionDefinition | ParseDeclarationOrFunctionDefinition -| | EvaluateAsRValue (<test.cc:8:21>) -| | EvaluateForOverflow (<test.cc:8:21, col:25>) -| | EvaluateForOverflow (<test.cc:8:30, col:32>) -| | EvaluateAsRValue (<test.cc:9:14>) -| | EvaluateForOverflow (<test.cc:9:9, col:14>) -| | isPotentialConstantExpr (slow_namespace::slow_func) -| | EvaluateAsBooleanCondition (<test.cc:8:21, col:25>) -| | | EvaluateAsRValue (<test.cc:8:21, col:25>) -| | EvaluateAsBooleanCondition (<test.cc:8:21, col:25>) -| | | EvaluateAsRValue (<test.cc:8:21, col:25>) +| | ParseFunctionDefinition (slow_func) +| | | EvaluateAsRValue (<test.cc:8:21>) +| | | EvaluateForOverflow (<test.cc:8:21, col:25>) +| | | EvaluateForOverflow (<test.cc:8:30, col:32>) +| | | EvaluateAsRValue (<test.cc:9:14>) +| | | EvaluateForOverflow (<test.cc:9:9, col:14>) +| | | isPotentialConstantExpr (slow_namespace::slow_func) +| | | EvaluateAsBooleanCondition (<test.cc:8:21, col:25>) +| | | | EvaluateAsRValue (<test.cc:8:21, col:25>) +| | | EvaluateAsBooleanCondition (<test.cc:8:21, col:25>) +| | | | EvaluateAsRValue (<test.cc:8:21, col:25>) | ParseDeclarationOrFunctionDefinition -| | EvaluateAsInitializer (slow_value) -| | EvaluateAsConstantExpr (<test.cc:17:33, col:59>) -| | EvaluateAsConstantExpr (<test.cc:18:11, col:37>) -| | EvaluateAsConstantExpr (<test.cc:23:31, col:57>) +| | ParseFunctionDefinition (slow_test) +| | | EvaluateAsInitializer (slow_value) +| | | EvaluateAsConstantExpr (<test.cc:17:33, col:59>) +| | | EvaluateAsConstantExpr (<test.cc:18:11, col:37>) | ParseDeclarationOrFunctionDefinition +| | EvaluateAsConstantExpr (<test.cc:23:31, col:57>) | | EvaluateAsRValue (<test.cc:22:14, line:23:58>) | ParseDeclarationOrFunctionDefinition | | EvaluateAsInitializer (slow_init_list) >From fa0503d3b75dde8724694f779b6c6b21872f7bda Mon Sep 17 00:00:00 2001 From: Ying Yi <ying...@sony.com> Date: Fri, 13 Oct 2023 23:59:26 +0100 Subject: [PATCH 3/3] Add function's source location to the time scope variable of "ParseDeclarationOrFunctionDefinition". --- clang/lib/Parse/Parser.cpp | 6 +++++- ...me-trace-ParseDeclarationOrFunctionDefinition.cpp | 1 + clang/unittests/Support/TimeProfilerTest.cpp | 12 ++++++------ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 533a9af173178b0..bef3a0dcb285efd 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1232,7 +1232,11 @@ Parser::DeclGroupPtrTy Parser::ParseDeclarationOrFunctionDefinition( ParsingDeclSpec *DS, AccessSpecifier AS) { // Add an enclosing time trace scope for a bunch of small scopes with // "EvaluateAsConstExpr". - llvm::TimeTraceScope TimeScope("ParseDeclarationOrFunctionDefinition"); + llvm::TimeTraceScope TimeScope( + "ParseDeclarationOrFunctionDefinition", + Tok.getLocation().printToString( + Actions.getASTContext().getSourceManager())); + if (DS) { return ParseDeclOrFunctionDefInternal(Attrs, DeclSpecAttrs, *DS, AS); } else { diff --git a/clang/test/Driver/check-time-trace-ParseDeclarationOrFunctionDefinition.cpp b/clang/test/Driver/check-time-trace-ParseDeclarationOrFunctionDefinition.cpp index 96bb37d57823e8b..f854cddadbfcc1d 100644 --- a/clang/test/Driver/check-time-trace-ParseDeclarationOrFunctionDefinition.cpp +++ b/clang/test/Driver/check-time-trace-ParseDeclarationOrFunctionDefinition.cpp @@ -4,6 +4,7 @@ // 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" diff --git a/clang/unittests/Support/TimeProfilerTest.cpp b/clang/unittests/Support/TimeProfilerTest.cpp index f69a54692b0072a..97fdbb7232b1351 100644 --- a/clang/unittests/Support/TimeProfilerTest.cpp +++ b/clang/unittests/Support/TimeProfilerTest.cpp @@ -177,8 +177,8 @@ 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 -| ParseDeclarationOrFunctionDefinition -| ParseDeclarationOrFunctionDefinition +| ParseDeclarationOrFunctionDefinition (test.cc:2:1) +| ParseDeclarationOrFunctionDefinition (test.cc:6:1) | | ParseFunctionDefinition (slow_func) | | | EvaluateAsRValue (<test.cc:8:21>) | | | EvaluateForOverflow (<test.cc:8:21, col:25>) @@ -190,15 +190,15 @@ Frontend | | | | EvaluateAsRValue (<test.cc:8:21, col:25>) | | | EvaluateAsBooleanCondition (<test.cc:8:21, col:25>) | | | | EvaluateAsRValue (<test.cc:8:21, col:25>) -| ParseDeclarationOrFunctionDefinition +| ParseDeclarationOrFunctionDefinition (test.cc:16:1) | | ParseFunctionDefinition (slow_test) | | | EvaluateAsInitializer (slow_value) | | | EvaluateAsConstantExpr (<test.cc:17:33, col:59>) | | | EvaluateAsConstantExpr (<test.cc:18:11, col:37>) -| ParseDeclarationOrFunctionDefinition +| ParseDeclarationOrFunctionDefinition (test.cc:22:1) | | EvaluateAsConstantExpr (<test.cc:23:31, col:57>) | | EvaluateAsRValue (<test.cc:22:14, line:23:58>) -| ParseDeclarationOrFunctionDefinition +| ParseDeclarationOrFunctionDefinition (test.cc:25:1) | | EvaluateAsInitializer (slow_init_list) | PerformPendingInstantiations )"); @@ -220,7 +220,7 @@ struct { std::string TraceGraph = buildTraceGraph(Json); ASSERT_TRUE(TraceGraph == R"( Frontend -| ParseDeclarationOrFunctionDefinition +| ParseDeclarationOrFunctionDefinition (test.c:2:1) | | isIntegerConstantExpr (<test.c:3:18>) | | EvaluateKnownConstIntCheckOverflow (<test.c:3:18>) | PerformPendingInstantiations _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits