Skip to content

Conversation

jurahul
Copy link
Contributor

@jurahul jurahul commented Aug 7, 2025

Add an include file that defines time profiler related command line options, move the TimeProfiler RAII helper class from optdriver.cpp to this file, and adopt this in various LLVM tools.

@jurahul jurahul force-pushed the time_trace_profile_tool branch from 94f5f64 to 700a9a3 Compare August 7, 2025 05:07
@jurahul jurahul force-pushed the time_trace_profile_tool branch from 700a9a3 to 88bc420 Compare August 7, 2025 06:05
@jurahul jurahul changed the title [NFC][Support] Add a header for time profiler helpers [NFC][Support] Add a include file for time profiler helpers for tools Aug 7, 2025
@jurahul jurahul marked this pull request as ready for review August 7, 2025 06:49
@jurahul jurahul requested a review from mshockwave August 7, 2025 06:49
@jurahul jurahul requested review from nico and nikic August 7, 2025 06:50
@llvmbot
Copy link
Member

llvmbot commented Aug 7, 2025

@llvm/pr-subscribers-llvm-support

Author: Rahul Joshi (jurahul)

Changes

Add a include file that defines time profiler related command line options, move the TimeProfiler RAII helper class to this file as well, and adopt this in various LLVM tools.


Full diff: https://github.com/llvm/llvm-project/pull/152416.diff

4 Files Affected:

  • (added) llvm/include/llvm/Support/TimeProfilerTool.inc (+62)
  • (modified) llvm/tools/llc/llc.cpp (+2-27)
  • (modified) llvm/tools/llvm-mc/llvm-mc.cpp (+2-26)
  • (modified) llvm/tools/opt/optdriver.cpp (+2-33)
diff --git a/llvm/include/llvm/Support/TimeProfilerTool.inc b/llvm/include/llvm/Support/TimeProfilerTool.inc
new file mode 100644
index 0000000000000..785597033eb52
--- /dev/null
+++ b/llvm/include/llvm/Support/TimeProfilerTool.inc
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines command line options and helper class for tools that want
+// to use time trace profiling. It is intended for inclusion in a tool's .cpp
+// file.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TIMEROFILER_TOOL_INC
+#define LLVM_SUPPORT_TIMEROFILER_TOOL_INC
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/TimeProfiler.h"
+
+static llvm::cl::opt<bool> TimeTrace("time-trace",
+                                     llvm::cl::desc("Record time trace"));
+
+static llvm::cl::opt<unsigned> TimeTraceGranularity(
+    "time-trace-granularity",
+    llvm::cl::desc(
+        "Minimum time granularity (in microseconds) traced by time profiler"),
+    llvm::cl::init(500), llvm::cl::Hidden);
+
+static llvm::cl::opt<std::string>
+    TimeTraceFile("time-trace-file",
+                  llvm::cl::desc("Specify time trace file destination"),
+                  llvm::cl::value_desc("filename"));
+
+namespace {
+
+/// The TimeTraceProfilerRAII is a helper class to initialize and write the time
+/// trace profile, intended for use in various tools.
+class TimeTraceProfilerRAII {
+private:
+  llvm::StringRef OutputFilename;
+
+public:
+  TimeTraceProfilerRAII(llvm::StringRef ProgramName,
+                        llvm::StringRef OutputFilename)
+      : OutputFilename(OutputFilename) {
+    if (TimeTrace)
+      llvm::timeTraceProfilerInitialize(TimeTraceGranularity, ProgramName);
+  }
+  ~TimeTraceProfilerRAII() {
+    if (!TimeTrace)
+      return;
+    if (auto E = llvm::timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) {
+      llvm::logAllUnhandledErrors(std::move(E), llvm::errs());
+      return;
+    }
+    llvm::timeTraceProfilerCleanup();
+  }
+};
+
+} // namespace
+
+#endif // LLVM_SUPPORT_TIMEROFILER_TOOL_INC
diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index b3d7185e7f144..d80cd99273663 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -47,7 +47,7 @@
 #include "llvm/Support/PluginLoader.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/TimeProfiler.h"
+#include "llvm/Support/TimeProfilerTool.inc"
 #include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Support/WithColor.h"
 #include "llvm/Target/TargetLoweringObjectFile.h"
@@ -88,19 +88,6 @@ TimeCompilations("time-compilations", cl::Hidden, cl::init(1u),
                  cl::value_desc("N"),
                  cl::desc("Repeat compilation N times for timing"));
 
-static cl::opt<bool> TimeTrace("time-trace", cl::desc("Record time trace"));
-
-static cl::opt<unsigned> TimeTraceGranularity(
-    "time-trace-granularity",
-    cl::desc(
-        "Minimum time granularity (in microseconds) traced by time profiler"),
-    cl::init(500), cl::Hidden);
-
-static cl::opt<std::string>
-    TimeTraceFile("time-trace-file",
-                  cl::desc("Specify time trace file destination"),
-                  cl::value_desc("filename"));
-
 static cl::opt<std::string>
     BinutilsVersion("binutils-version", cl::Hidden,
                     cl::desc("Produced object files can use all ELF features "
@@ -367,19 +354,7 @@ int main(int argc, char **argv) {
     return 1;
   }
 
-  if (TimeTrace)
-    timeTraceProfilerInitialize(TimeTraceGranularity, argv[0]);
-  auto TimeTraceScopeExit = make_scope_exit([]() {
-    if (TimeTrace) {
-      if (auto E = timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) {
-        handleAllErrors(std::move(E), [&](const StringError &SE) {
-          errs() << SE.getMessage() << "\n";
-        });
-        return;
-      }
-      timeTraceProfilerCleanup();
-    }
-  });
+  TimeTraceProfilerRAII TimeTracer(argv[0], OutputFilename);
 
   LLVMContext Context;
   Context.setDiscardValueNames(DiscardValueNames);
diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp
index f69f7c725c6b4..4f82ede6361a3 100644
--- a/llvm/tools/llvm-mc/llvm-mc.cpp
+++ b/llvm/tools/llvm-mc/llvm-mc.cpp
@@ -38,7 +38,7 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/TimeProfiler.h"
+#include "llvm/Support/TimeProfilerTool.inc"
 #include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Support/WithColor.h"
 #include "llvm/TargetParser/Host.h"
@@ -246,19 +246,6 @@ static cl::opt<unsigned>
     NumBenchmarkRuns("runs", cl::desc("Number of runs for benchmarking"),
                      cl::cat(MCCategory));
 
-static cl::opt<bool> TimeTrace("time-trace", cl::desc("Record time trace"));
-
-static cl::opt<unsigned> TimeTraceGranularity(
-    "time-trace-granularity",
-    cl::desc(
-        "Minimum time granularity (in microseconds) traced by time profiler"),
-    cl::init(500), cl::Hidden);
-
-static cl::opt<std::string>
-    TimeTraceFile("time-trace-file",
-                  cl::desc("Specify time trace file destination"),
-                  cl::value_desc("filename"));
-
 static const Target *GetTarget(const char *ProgName) {
   // Figure out the target triple.
   if (TripleName.empty())
@@ -391,18 +378,7 @@ int main(int argc, char **argv) {
   cl::HideUnrelatedOptions({&MCCategory, &getColorCategory()});
   cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
 
-  if (TimeTrace)
-    timeTraceProfilerInitialize(TimeTraceGranularity, argv[0]);
-
-  auto TimeTraceScopeExit = make_scope_exit([]() {
-    if (!TimeTrace)
-      return;
-    if (auto E = timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) {
-      logAllUnhandledErrors(std::move(E), errs());
-      return;
-    }
-    timeTraceProfilerCleanup();
-  });
+  TimeTraceProfilerRAII TimeTracer(argv[0], OutputFilename);
 
   MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
   MCOptions.CompressDebugSections = CompressDebugSections.getValue();
diff --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp
index a185ea464decc..9b0f2f923e5e9 100644
--- a/llvm/tools/opt/optdriver.cpp
+++ b/llvm/tools/opt/optdriver.cpp
@@ -47,7 +47,7 @@
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/SystemUtils.h"
 #include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/TimeProfiler.h"
+#include "llvm/Support/TimeProfilerTool.inc"
 #include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Support/YAMLTraits.h"
 #include "llvm/Target/TargetMachine.h"
@@ -252,19 +252,6 @@ static cl::opt<bool> DiscardValueNames(
     cl::desc("Discard names from Value (other than GlobalValue)."),
     cl::init(false), cl::Hidden);
 
-static cl::opt<bool> TimeTrace("time-trace", cl::desc("Record time trace"));
-
-static cl::opt<unsigned> TimeTraceGranularity(
-    "time-trace-granularity",
-    cl::desc(
-        "Minimum time granularity (in microseconds) traced by time profiler"),
-    cl::init(500), cl::Hidden);
-
-static cl::opt<std::string>
-    TimeTraceFile("time-trace-file",
-                  cl::desc("Specify time trace file destination"),
-                  cl::value_desc("filename"));
-
 static cl::opt<bool> RemarksWithHotness(
     "pass-remarks-with-hotness",
     cl::desc("With PGO, include profile count in optimization remarks"),
@@ -306,24 +293,6 @@ static CodeGenOptLevel GetCodeGenOptLevel() {
   return static_cast<CodeGenOptLevel>(unsigned(CodeGenOptLevelCL));
 }
 
-struct TimeTracerRAII {
-  TimeTracerRAII(StringRef ProgramName) {
-    if (TimeTrace)
-      timeTraceProfilerInitialize(TimeTraceGranularity, ProgramName);
-  }
-  ~TimeTracerRAII() {
-    if (TimeTrace) {
-      if (auto E = timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) {
-        handleAllErrors(std::move(E), [&](const StringError &SE) {
-          errs() << SE.getMessage() << "\n";
-        });
-        return;
-      }
-      timeTraceProfilerCleanup();
-    }
-  }
-};
-
 // For use in NPM transition. Currently this contains most codegen-specific
 // passes. Remove passes from here when porting to the NPM.
 // TODO: use a codegen version of PassRegistry.def/PassBuilder::is*Pass() once
@@ -503,7 +472,7 @@ extern "C" int optMain(
     return 0;
   }
 
-  TimeTracerRAII TimeTracer(argv[0]);
+  TimeTraceProfilerRAII TimeTracer(argv[0], OutputFilename);
 
   SMDiagnostic Err;
 

@jurahul jurahul changed the title [NFC][Support] Add a include file for time profiler helpers for tools [NFC][Support] Add an include file for time profiler helpers for tools Aug 7, 2025
Copy link
Member

@mshockwave mshockwave left a comment

Choose a reason for hiding this comment

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

I feel like this approach is not really different from putting it in 'traditional' header file. Namely:

  1. Put the RAII class in llvm/Support/TimeProfiler.h
  2. Define command line options in lib/Support/TimeProfile.cpp, and maybe provide getter functions for options that user might want to access (e.g. time-trace-file)

For the RAII class, you could provide a variety of ctors so that users can either choose to supply their time trace file path / granularity or using the ones given by the command line options.


public:
TimeTraceProfilerRAII(llvm::StringRef ProgramName,
llvm::StringRef OutputFilename)
Copy link
Member

Choose a reason for hiding this comment

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

should we be consistent with timeTraceProfilerWrite's API description and use FallbackFilename?

@jurahul
Copy link
Contributor Author

jurahul commented Aug 22, 2025

Sorry, getting back to this, (1) seems ok but if we define the options in the .cpp file they will be linked into and available in any tool that links Support which is not what we want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants