-
Notifications
You must be signed in to change notification settings - Fork 12.4k
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
demangle function names in trace files #87626
Conversation
✅ With the latest revision this PR passed the Python code formatter. |
@@ -1495,7 +1496,7 @@ void TimeProfilingPassesHandler::registerCallbacks( | |||
} | |||
|
|||
void TimeProfilingPassesHandler::runBeforePass(StringRef PassID, Any IR) { | |||
timeTraceProfilerBegin(PassID, getIRName(IR)); | |||
timeTraceProfilerBegin(PassID, demangle(getIRName(IR))); |
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 is a bit brute-force as it also runs demangle on cases like [module]
, see getIRName above around line 200.
Also for SCCs it fails to demangle since getName returns something like (func1[,func2])
.
I didn't hit the Loop and MachineFunction cases in the Debugger so not sure about those.
In general those function entries are duplicated a lot in the trace file, maybe one could limit it to certain levels in the flame graph, e.g. only once for PassManager<Function>
and not for every single pass beneath it like EarlyCSEPass
.
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.
getIRName is a locally defined function (see above in this file). In some of the cases, it is desirable to have the mangled name reported because that can be used for filtering. In this case, I don't think that there is filtering available, so demangling the name seems reasonable. However, as you noted, there are names where demangling is not appropriate. I would suggest that you add a parameter to the getIRName function (defaulting to false) to allow demangling of appropriate names and do the demangling there.
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.
See comments in response
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, thanks
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-clang Author: Trass3r (Trass3r) ChangesThis improves consistency in the trace files as other entries are demangled too. @jamieschmeiser @An-DJ Full diff: https://github.com/llvm/llvm-project/pull/87626.diff 4 Files Affected:
diff --git a/clang/test/Driver/ftime-trace-sections.py b/clang/test/Driver/ftime-trace-sections.py
old mode 100644
new mode 100755
index 02afa4ac54eb7b..eeb3aa24131a39
--- a/clang/test/Driver/ftime-trace-sections.py
+++ b/clang/test/Driver/ftime-trace-sections.py
@@ -19,9 +19,12 @@ def is_before(range1, range2):
log_contents = json.loads(sys.stdin.read())
events = log_contents["traceEvents"]
-codegens = [event for event in events if event["name"] == "CodeGen Function"]
+
+instants = [event for event in events if event["name"] == "InstantiateFunction"]
+codegens = [event for event in events if event["name"] == "CodeGen Function"]
+opts = [event for event in events if event["name"] == "OptFunction"]
frontends = [event for event in events if event["name"] == "Frontend"]
-backends = [event for event in events if event["name"] == "Backend"]
+backends = [event for event in events if event["name"] == "Backend"]
beginning_of_time = log_contents["beginningOfTime"] / 1000000
seconds_since_epoch = time.time()
@@ -48,3 +51,11 @@ def is_before(range1, range2):
]
):
sys.exit("Not all Frontend section are before all Backend sections!")
+
+# Check that entries for foo exist and are in a demangled form.
+if not any(e for e in instants if "foo<int>" in e["args"]["detail"]):
+ sys.exit("Missing Instantiate entry for foo!")
+if not any(e for e in codegens if "foo<int>" in e["args"]["detail"]):
+ sys.exit("Missing CodeGen entry for foo!")
+if not any(e for e in opts if "foo<int>" in e["args"]["detail"]):
+ sys.exit("Missing Optimize entry for foo!")
diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp
index 953f21ce740590..9e3578954418ad 100644
--- a/llvm/lib/IR/LegacyPassManager.cpp
+++ b/llvm/lib/IR/LegacyPassManager.cpp
@@ -12,6 +12,7 @@
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/Demangle/Demangle.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LLVMContext.h"
@@ -1421,7 +1422,8 @@ bool FPPassManager::runOnFunction(Function &F) {
// Store name outside of loop to avoid redundant calls.
const StringRef Name = F.getName();
- llvm::TimeTraceScope FunctionScope("OptFunction", Name);
+ llvm::TimeTraceScope FunctionScope(
+ "OptFunction", [&F]() { return demangle(F.getName().str()); });
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
FunctionPass *FP = getContainedPass(Index);
diff --git a/llvm/lib/Passes/CMakeLists.txt b/llvm/lib/Passes/CMakeLists.txt
index 6425f4934b2103..b5224327d79216 100644
--- a/llvm/lib/Passes/CMakeLists.txt
+++ b/llvm/lib/Passes/CMakeLists.txt
@@ -21,6 +21,7 @@ add_llvm_component_library(LLVMPasses
CodeGen
Core
Coroutines
+ Demangle
HipStdPar
IPO
InstCombine
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 697988b3fc7c0b..0faf865cd013c8 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -20,6 +20,7 @@
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Demangle/Demangle.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
@@ -215,12 +216,12 @@ void printIR(raw_ostream &OS, const Loop *L) {
printLoop(const_cast<Loop &>(*L), OS);
}
-std::string getIRName(Any IR) {
+std::string getIRName(Any IR, bool demangled = false) {
if (unwrapIR<Module>(IR))
return "[module]";
if (const auto *F = unwrapIR<Function>(IR))
- return F->getName().str();
+ return demangled ? demangle(F->getName()) : F->getName().str();
if (const auto *C = unwrapIR<LazyCallGraph::SCC>(IR))
return C->getName();
@@ -229,7 +230,7 @@ std::string getIRName(Any IR) {
return L->getName().str();
if (const auto *MF = unwrapIR<MachineFunction>(IR))
- return MF->getName().str();
+ return demangled ? demangle(MF->getName()) : MF->getName().str();
llvm_unreachable("Unknown wrapped IR type");
}
@@ -1495,7 +1496,7 @@ void TimeProfilingPassesHandler::registerCallbacks(
}
void TimeProfilingPassesHandler::runBeforePass(StringRef PassID, Any IR) {
- timeTraceProfilerBegin(PassID, getIRName(IR));
+ timeTraceProfilerBegin(PassID, getIRName(IR, true));
}
void TimeProfilingPassesHandler::runAfterPass() { timeTraceProfilerEnd(); }
|
Thank you @jamieschmeiser, how to proceed? Should I rebase to solve the conflict? Should I apply the clang-fornat diff (which makes things less readable IMHO)? |
Yes, the way to proceed is to rebase and resolve the conflicts. As far as the formatting changes, I think you should go with what the formatter wants. Everyone has different opinions about things like spacing, line length, etc and will never agree. The formatter keeps things consistent, which I think everyone will agree is good. |
This improves consistency in the trace files as other entries are demangled too. Fixes llvm#45901.
aef8e2f
to
5ae3eff
Compare
Ok done |
Thanks, I looked over things and they still look good. |
You may want to look at #90756 |
I haven't seen a Loop entry in a trace file yet. |
@jamieschmeiser ping |
@Trass3r, sorry, I didn't realize that you were waiting on me... I had already approved this so you can go ahead and merge it. I was just pointing you at possibly related work that might interest you. Even if you decide to expand this work, I would suggest delivering this as is and doing that as a separate piece. |
To directly answer your question: No, deliver this. If you find loop entries in the future, then consider expanding it. Also, the link to that here may help others should they decide to expand this work. |
Ok thanks, I don't have commit rights, could you merge it please? :) |
This improves consistency in the trace files as other entries are demangled too. Submitted by jamieschmeiser on behalf of trass3r @jamieschmeiser @An-DJ
Are we sure we want this behavior? Demangling is really expensive. A user noticed a significant (10%) compile time regression from this change. We could skip the demangling and do it offline. It's also worth pointing out that we have to redo this work every time we optimize the same function over and over. There is a fair amount of room for improvement in efficiency here. |
@rnk It is just a convenience to make things easier to read and should be removed if it is causing compile time issues. I just happened to see this comment now but will be unavailable for about 2 weeks. I will take care of it when I return (I'm not ignoring this...) If you wish to pull it in the mean-time, please go ahead. Sorry for any inconvenience. |
I think I'll leave this change in and file an issue about it. A 10% compile time regression with |
This reverts commit 0fa20c5. Storing raw symbol names is generally preferred in profile files. Demangling might lose information. Language frontends might use demangling schemes not supported by LLVMDemangle (#45901 (comment)). In addition, calling `demangle` for each function has a significant performance overhead (#102222). I believe that even if we decide to provide a producer-side demangling, it would not be on by default. Pull Request: #102274
This reverts commit 0fa20c5. Storing raw symbol names is generally preferred in profile files. Demangling might lose information. Language frontends might use demangling schemes not supported by LLVMDemangle (llvm#45901 (comment)). In addition, calling `demangle` for each function has a significant performance overhead (llvm#102222). I believe that even if we decide to provide a producer-side demangling, it would not be on by default. Pull Request: llvm#102274 (cherry picked from commit 72b73e2)
This reverts commit 0fa20c5. Storing raw symbol names is generally preferred in profile files. Demangling might lose information. Language frontends might use demangling schemes not supported by LLVMDemangle (llvm#45901 (comment)). In addition, calling `demangle` for each function has a significant performance overhead (llvm#102222). I believe that even if we decide to provide a producer-side demangling, it would not be on by default. Pull Request: llvm#102274 (cherry picked from commit 72b73e2)
This reverts commit 0fa20c5. Storing raw symbol names is generally preferred in profile files. Demangling might lose information. Language frontends might use demangling schemes not supported by LLVMDemangle (llvm#45901 (comment)). In addition, calling `demangle` for each function has a significant performance overhead (llvm#102222). I believe that even if we decide to provide a producer-side demangling, it would not be on by default. Pull Request: llvm#102274 (cherry picked from commit 72b73e2)
This reverts commit 0fa20c5. Storing raw symbol names is generally preferred in profile files. Demangling might lose information. Language frontends might use demangling schemes not supported by LLVMDemangle (llvm#45901 (comment)). In addition, calling `demangle` for each function has a significant performance overhead (llvm#102222). I believe that even if we decide to provide a producer-side demangling, it would not be on by default. Pull Request: llvm#102274
This improves consistency in the trace files as other entries are demangled too.
@jamieschmeiser @An-DJ