Skip to content
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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Trass3r
Copy link
Contributor

@Trass3r Trass3r commented Apr 4, 2024

This improves consistency in the trace files as other entries are demangled too.

@jamieschmeiser @An-DJ

Copy link

github-actions bot commented Apr 4, 2024

✅ 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)));
Copy link
Contributor Author

@Trass3r Trass3r Apr 4, 2024

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.

Copy link
Contributor

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.

Copy link
Contributor

@jamieschmeiser jamieschmeiser left a 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

Copy link
Contributor

@jamieschmeiser jamieschmeiser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks

@Trass3r Trass3r marked this pull request as ready for review April 9, 2024 22:44
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' llvm:ir labels Apr 9, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Apr 9, 2024

@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Author: Trass3r (Trass3r)

Changes

This 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:

  • (modified) clang/test/Driver/ftime-trace-sections.py (+13-2)
  • (modified) llvm/lib/IR/LegacyPassManager.cpp (+3-1)
  • (modified) llvm/lib/Passes/CMakeLists.txt (+1)
  • (modified) llvm/lib/Passes/StandardInstrumentations.cpp (+5-4)
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(); }

@Trass3r
Copy link
Contributor Author

Trass3r commented Apr 17, 2024

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)?

@jamieschmeiser
Copy link
Contributor

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.
@Trass3r
Copy link
Contributor Author

Trass3r commented May 6, 2024

Ok done

@jamieschmeiser
Copy link
Contributor

Thanks, I looked over things and they still look good.

@jamieschmeiser
Copy link
Contributor

You may want to look at #90756

@Trass3r
Copy link
Contributor Author

Trass3r commented May 6, 2024

I haven't seen a Loop entry in a trace file yet.
Do we want to change it anyway, @jamieschmeiser?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category llvm:ir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants