-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[time-trace] Add a new time trace scope variable named "ParseDeclarationOrFunctionDefinition". #65268
Conversation
Gentle ping ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems fine to me, but it's hard to understand if this is redundant with some other "ParseFunction" scope from the tests. WDYT @MaskRay ?
I share similar concern but I am not familiar with the parser... |
Gentle ping ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies on the delayed review! Thank you for working on this; we really could use better time trace output in Clang to start helping us get a better handle on improving compile time performance.
a9552dc
to
deecf8c
Compare
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Author: None (MaggieYingYi) ChangesWhen profiling code using Full diff: https://github.com/llvm/llvm-project/pull/65268.diff 3 Files Affected:
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 0f930248e77174b..533a9af173178b0 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 {
@@ -1259,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
new file mode 100644
index 000000000000000..96bb37d57823e8b
--- /dev/null
+++ b/clang/test/Driver/check-time-trace-ParseDeclarationOrFunctionDefinition.cpp
@@ -0,0 +1,14 @@
+// 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: "name": "ParseFunctionDefinition"
+// CHECK-DAG: "detail": "foo"
+// CHECK-DAG: "name": "ParseFunctionDefinition"
+// CHECK-DAG: "detail": "bar"
+
+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..f69a54692b0072a 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 (<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
+| | 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
+| | 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)
| PerformPendingInstantiations
)");
@@ -213,8 +220,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
)");
|
Gentle ping ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you for this! Please add a release note letting users know about the improvement when you land the changes.
Hi @AaronBallman, Thanks for reviewing and approving the patch. I have added a release note in the commit 014ad43. Since I haven't ever added a release note before, could you please let me know is it the correct file and the correct location to add a release note? If not, could you please give me some suggestions/links on how to add a release note? Many thanks, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your release note looks great, just a few formatting related nits with it.
014ad43
to
7cd2841
Compare
7cd2841
to
8ff407f
Compare
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. A release note is added as well. Reviewed by: Aaron Ballman Pull request: llvm#65268
8ff407f
to
5b75038
Compare
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. A release note is added as well. Reviewed by: Aaron Ballman Pull request: #65268
I tried to use |
I've reverted this change because it causes a large compile-time regression: http://llvm-compile-time-tracker.com/compare.php?from=61b9176cf70444c54f3ac6eebd82fc9ffd69944d&to=33b85867e30e1adc2ff2173039c199b81c10f52b&stat=instructions:u From a quick glance at your implementation, I suspect the issues is that the used strings may be expensive to compute. TimeTraceScope has an overload accepting a closure that calculates the detail string for such cases. |
Hi @nikic, thanks for spotting the issue and reverted the commit. Hi @AaronBallman, As @nikic mentioned that the issue is that the used strings may be expensive to compute. If we remove the change to record the function name and function location, I think the issue will be fixed. This means:
To:
Could you please let me know your thoughts? or any suggestion? Thanks, |
I think the suggestion from @nikic is to use the
|
…tead of the one accepting a string to avoid the compile-time regression.
Hi @AaronBallman, Thanks so much for the explanation using an example. I now understand. I have updated the patch in the commit f66e7d2. Kind regards, |
Hi @AaronBallman and @nikic, are you happy for me to recommit the change? Thanks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you!
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. A release note is added as well. Reviewed by: Aaron Ballman Pull request: #65268
Thanks @AaronBallman, the patch is recommitted. |
When profiling code using
-ftime-trace
with the defaulttime-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 namedEvaluateAsConstExpr
. This change adds an enclosing time trace scope for the functionParser::ParseDeclarationOrFunctionDefinition
to record the time spent parsing the function's declaration or definition.