Adding New-Ftime-Report Option

Greetings,
I’ve tried implementing a Ftime-Report Option and it gives me clang: warning: argument unused during compilation: ‘-ftime-report-detailed’ [-Wunused-command-line-argument]

The Timer logic should be fine afterwards but there seems to be a very subtle issue with this code, Not sure if I’m injecting it correctly or CC1 is complaining here but seems right to me.

From 60aa318de0139baf090ad5509f25a0e7b4f38415 Mon Sep 17 00:00:00 2001
From: Nicholas Krause <xerofoify@gmail.com>
Date: Thu, 22 May 2025 02:05:57 -0400
Subject: [PATCH] Test

Signed-off-by: Nicholas Krause <xerofoify@gmail.com>
---
 clang/include/clang/Basic/CodeGenOptions.def | 1 +
 clang/include/clang/Driver/Options.td        | 4 ++++
 clang/lib/CodeGen/BackendUtil.cpp            | 5 ++++-
 clang/lib/Frontend/CompilerInvocation.cpp    | 8 +++++++-
 4 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index aad4e107cbeb..54daab38f2bd 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -320,6 +320,7 @@ CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0) ///< Enable fine-grained bitfield
 CODEGENOPT(StrictEnums       , 1, 0) ///< Optimize based on strict enum definition.
 CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers
 CODEGENOPT(TimePasses        , 1, 0) ///< Set when -ftime-report or -ftime-report= or -ftime-report-json is enabled.
+CODEGENOPT(TimePassesDetailed, 1, 0) ///< Set when -ftime-report-detailed is enabled.
 CODEGENOPT(TimePassesPerRun  , 1, 0) ///< Set when -ftime-report=per-pass-run is enabled.
 CODEGENOPT(TimePassesJson    , 1, 0) ///< Set when -ftime-report-json is enabled.
 CODEGENOPT(TimeTrace         , 1, 0) ///< Set when -ftime-trace is enabled.
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 9a4253113488..49982605fa51 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4134,6 +4134,10 @@ defm ms_tls_guards : BoolFOption<"ms-tls-guards",
 def ftime_report : Flag<["-"], "ftime-report">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
   MarshallingInfoFlag<CodeGenOpts<"TimePasses">>;
+def ftime_report_detailed : Flag<["-"], "ftime-report-detailed">,
+  HelpText<"Enable detailed time report for code generation passes with function context">,
+  Visibility<[ClangOption, CC1Option]>,
+  MarshallingInfoFlag<CodeGenOpts<"TimePassesDetailed">>;
 def ftime_report_json
     : Flag<["-"], "ftime-report-json">,
       Group<f_Group>,
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 42c59377688b..092d3d1803fc 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -924,6 +924,9 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
       TheModule->getContext(),
       (CodeGenOpts.DebugPassManager || DebugPassStructure),
       CodeGenOpts.VerifyEach, PrintPassOpts);
+  if (CodeGenOpts.TimePassesDetailed) {
+  llvm::setTimePassesDetailedEnabled(true); // Enable detailed reporting
+  }
   SI.registerCallbacks(PIC, &MAM);
   PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC);
 
@@ -1141,7 +1144,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
   // requires code generation because there will already be a verifier pass in
   // the code-generation pipeline.
   // Since we already added a verifier pass above, this
-  // might even not run the analysis, if previous passes caused no changes.
+  // might even not uun the analysis, if previous passes caused no changes.
   if (!actionRequiresCodeGen(Action) && CodeGenOpts.VerifyModule)
     MPM.addPass(VerifierPass());
 
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 3c23073fc6a8..4cf45ad84036 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2023,8 +2023,14 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
             << A->getAsString(Args) << A->getValue();
     }
 
-    if (Args.getLastArg(OPT_ftime_report_json))
+    // Parse -ftime-report-detailed
+   if (Args.getLastArg(OPT_ftime_report_detailed))
+       CodeGenOpts.TimePassesDetailed = true; // Enable detailed time reporting
+
+   if (Args.getLastArg(OPT_ftime_report_json))
       Opts.TimePassesJson = true;
+    
+    
   }
 
   Opts.PrepareForLTO = false;
-- 
2.49.0

I think there are a few things.

  1. You should add Group<f_Group> to Options.td so it’s marked as being in the -f group appropriately.
  2. Where you’ve added the logic in CompilerInvocation.cpp is in a block that’s looking at a list of time report-related diagnostic options, but you’ve not added OPT_ftime_report_json to the predicates, so you only get into this block if you also pas another time report option as well as -ftime-report-detailed
  3. You’re missing analogous code in GenerateCodeGenArgs().
  4. You should add Args.AddLastArg(CmdArgs, options::OPT_ftime_report_detailed); in Clang.cpp’s ConstructJob() function so that the argument is consumed.

I think if you do those things, everything should work for you as expected.

It still gives me this:
clang -ftime-report-detailed test.c

clang: error: unknown argument: ‘-ftime-report-detailed’
So something into is still not parsing or injecting properly.

after injecting into ClangDriver. Here is the code I’ve tried step by step

From d4443560ea837df58d1ef9e150590629934c2f8e Mon Sep 17 00:00:00 2001
From: Nicholas Krause <xerofoify@gmail.com>
Date: Thu, 22 May 2025 06:26:41 -0400
Subject: [PATCH 1/3] Test 2

Signed-off-by: Nicholas Krause <xerofoify@gmail.com>
---
 clang/lib/Frontend/CompilerInvocation.cpp |  3 ++-
 llvm/include/llvm/Support/Timer.h         |  2 ++
 llvm/lib/Support/Timer.cpp                | 17 +++++++++++++++++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 4cf45ad84036..8748bd6f8e47 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -86,6 +86,7 @@
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/TargetParser/Host.h"
 #include "llvm/TargetParser/Triple.h"
+#include "llvm/Support/Timer.h"
 #include <algorithm>
 #include <atomic>
 #include <cassert>
@@ -2025,7 +2026,7 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
 
     // Parse -ftime-report-detailed
    if (Args.getLastArg(OPT_ftime_report_detailed))
-       CodeGenOpts.TimePassesDetailed = true; // Enable detailed time reporting
+       Opts.TimePassesDetailed = true; // Enable detailed time reporting
 
    if (Args.getLastArg(OPT_ftime_report_json))
       Opts.TimePassesJson = true;
diff --git a/llvm/include/llvm/Support/Timer.h b/llvm/include/llvm/Support/Timer.h
index 36890c75a65e..9f5bc76dfee8 100644
--- a/llvm/include/llvm/Support/Timer.h
+++ b/llvm/include/llvm/Support/Timer.h
@@ -24,6 +24,8 @@ namespace llvm {
 class TimerGlobals;
 class TimerGroup;
 class raw_ostream;
+void setTimePassesDetailedEnabled(bool Enabled);
+bool getTimePassesDetailedIsEnabled();
 
 class TimeRecord {
   double WallTime = 0.0;             ///< Wall clock time elapsed in seconds.
diff --git a/llvm/lib/Support/Timer.cpp b/llvm/lib/Support/Timer.cpp
index 22811d7b4af0..86e9c7a55a56 100644
--- a/llvm/lib/Support/Timer.cpp
+++ b/llvm/lib/Support/Timer.cpp
@@ -38,6 +38,23 @@
 #endif
 
 using namespace llvm;
+namespace llvm {
+
+// Flag to enable/disable detailed time reporting
+static bool TimePassesDetailedIsEnabled = false;
+
+// Function to enable detailed time reporting
+void setTimePassesDetailedEnabled(bool Enabled) {
+    TimePassesDetailedIsEnabled = Enabled;
+}
+
+// Function to check if detailed time reporting is enabled
+bool getTimePassesDetailedIsEnabled() {
+    return TimePassesDetailedIsEnabled;
+}
+
+} // namespace llvm
+
 
 //===----------------------------------------------------------------------===//
 // Forward declarations for Managed Timer Globals getters.
-- 
2.49.0


From 1e1407ad524783ef92847f7ea92590d71d571c88 Mon Sep 17 00:00:00 2001
From: Nicholas Krause <xerofoify@gmail.com>
Date: Thu, 22 May 2025 15:00:53 -0400
Subject: [PATCH 2/3] Add GenArgs Injection

Signed-off-by: Nicholas Krause <xerofoify@gmail.com>
---
 clang/include/clang/Driver/Options.td     | 2 +-
 clang/lib/Frontend/CompilerInvocation.cpp | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 49982605fa51..e63197636495 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4134,7 +4134,7 @@ defm ms_tls_guards : BoolFOption<"ms-tls-guards",
 def ftime_report : Flag<["-"], "ftime-report">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
   MarshallingInfoFlag<CodeGenOpts<"TimePasses">>;
-def ftime_report_detailed : Flag<["-"], "ftime-report-detailed">,
+def ftime_report_detailed : Flag<["-"], "ftime-report-detailed">, Group<f_Group>
   HelpText<"Enable detailed time report for code generation passes with function context">,
   Visibility<[ClangOption, CC1Option]>,
   MarshallingInfoFlag<CodeGenOpts<"TimePassesDetailed">>;
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 8748bd6f8e47..ee9e12ab7349 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1703,6 +1703,9 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
 
     if (Opts.TimePassesJson)
       GenerateArg(Consumer, OPT_ftime_report_json);
+    
+    if (Opts.TimePassesDetailed) 
+	GenerateArg(Consumer,OPT_ftime_report_detailed);
   }
 
   if (Opts.PrepareForLTO && !Opts.PrepareForThinLTO)
-- 
2.49.0
From 83e959534bf9c234bcd0dfa8f58cf30d56439429 Mon Sep 17 00:00:00 2001
From: Nicholas Krause <xerofoify@gmail.com>
Date: Thu, 22 May 2025 17:41:35 -0400
Subject: [PATCH 3/3] Driver File

Signed-off-by: Nicholas Krause <xerofoify@gmail.com>
---
 clang/include/clang/Driver/Options.td | 2 +-
 clang/lib/Driver/ToolChains/Clang.cpp | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index e63197636495..518b088d1ce7 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4134,7 +4134,7 @@ defm ms_tls_guards : BoolFOption<"ms-tls-guards",
 def ftime_report : Flag<["-"], "ftime-report">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
   MarshallingInfoFlag<CodeGenOpts<"TimePasses">>;
-def ftime_report_detailed : Flag<["-"], "ftime-report-detailed">, Group<f_Group>
+def ftime_report_detailed : Flag<["-"], "ftime-report-detailed">, Group<f_Group>,
   HelpText<"Enable detailed time report for code generation passes with function context">,
   Visibility<[ClangOption, CC1Option]>,
   MarshallingInfoFlag<CodeGenOpts<"TimePassesDetailed">>;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 355a48be9f49..dea3b7d9182e 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7019,6 +7019,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
   Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
+  Args.AddLastArg(CmdArgs, options::OPT_ftime_report_detailed);
   Args.AddLastArg(CmdArgs, options::OPT_ftime_report_EQ);
   Args.AddLastArg(CmdArgs, options::OPT_ftime_report_json);
   Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
-- 
2.49.0

I think you’re missing changes here: llvm-project/clang/lib/Frontend/CompilerInvocation.cpp at f3b404be973507432cf86c177978d9de708d850c · llvm/llvm-project · GitHub – you should add OPT_ftime_report_detailed to the list there.

Works now as I get:
./bin/clang-21 -ftime-report-detailed
clang-21: error: no input files

Thanks for being patient as was not very familiar with the clang injection points. The final thing is for a adding printing out that would be in Timer.cpp and the print Queue function just checking for the new option, unless I’m again misunderstanding the correct points of ftime’s timing core printing information internals.

1 Like

Excellent, glad that helped! I think your next steps sound reasonable.