From f49687eda5ec2bd4fae34c362192ae6739f8c0f9 Mon Sep 17 00:00:00 2001
From: Heli <helishah1729@gmail.com>
Date: Mon, 4 May 2026 15:46:33 +0530
Subject: [PATCH] gcc: Add initial -ftime-trace support

Signed-off-by: Heli <helishah1729@gmail.com>
---
 gcc/common.opt                       |  4 +++
 gcc/doc/invoke.texi                  |  8 ++++-
 gcc/testsuite/gcc.dg/ftime-trace-1.c |  7 ++++
 gcc/toplev.cc                        | 52 ++++++++++++++++++++++++++++
 4 files changed, 70 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/ftime-trace-1.c

diff --git a/gcc/common.opt b/gcc/common.opt
index 5d0e255a40d..ac487b6896c 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -3156,6 +3156,10 @@ ftime-report
 Common Var(time_report)
 Report the time taken by each compiler pass.
 
+ftime-trace
+Common Var(flag_time_trace)
+Generate a JSON trace file showing where the compiler spends time.
+
 ftime-report-details
 Common Var(time_report_details)
 Record times taken by sub-phases separately.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 756af474310..22cb88a0622 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -860,7 +860,7 @@ Objective-C and Objective-C++ Dialects}.
 -fmultiflags  -fprofile-report
 -frandom-seed=@var{string}  -fsched-verbose=@var{n}
 -fsel-sched-verbose  -fsel-sched-dump-cfg  -fsel-sched-pipelining-verbose
--fstats  -fstack-usage  -ftime-report  -ftime-report-details
+-fstats  -fstack-usage  -ftime-report  -ftime-report-details -ftime-trace
 -fvar-tracking-assignments-toggle  -gtoggle
 -print-autofdo-gcov-version
 -print-file-name=@var{library}  -print-libgcc-file-name
@@ -20896,6 +20896,11 @@ finishes.
 @opindex ftime-report
 @opindex fno-time-report
 @item -ftime-report
+@opindex ftime-trace
+@item -ftime-trace
+Emit a JSON trace file containing timing information for the compilation.
+The output is intended to be compatible with trace-viewing tools such as
+Chrome's tracing viewer.
 Makes the compiler print some statistics to stderr about the time consumed
 by each pass when it finishes.
 
@@ -20910,6 +20915,7 @@ slightly different place within the compiler.
 @opindex ftime-report-details
 @opindex fno-time-report-details
 @item -ftime-report-details
+
 Record the time consumed by infrastructure parts separately for each pass.
 
 @opindex fira-verbose
diff --git a/gcc/testsuite/gcc.dg/ftime-trace-1.c b/gcc/testsuite/gcc.dg/ftime-trace-1.c
new file mode 100644
index 00000000000..949f6b08476
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ftime-trace-1.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-ftime-trace" } */
+
+int main(void)
+{
+  return 0;
+}
diff --git a/gcc/toplev.cc b/gcc/toplev.cc
index 66fa927c53d..481c78468e7 100644
--- a/gcc/toplev.cc
+++ b/gcc/toplev.cc
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
    Error messages and low-level interface to malloc also handled here.  */
 
 #define INCLUDE_VECTOR
+#include <time.h>
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
@@ -2141,11 +2142,55 @@ standard_type_bitsize (int bitsize)
     return true;
   return false;
 }
+/*Adding helper function*/
+static long long
+gcc_time_trace_now_us ()
+{
+  struct timespec ts;
+  clock_gettime (CLOCK_MONOTONIC, &ts);
+  return (long long) ts.tv_sec * 1000000LL + ts.tv_nsec / 1000;
+}
+
+static void
+gcc_write_simple_time_trace (const char *filename,
+                             long long start_us,
+                             long long end_us)
+{
+  if (!filename)
+    filename = "gcc-time-trace";
+
+  char trace_name[4096];
+
+  snprintf (trace_name, sizeof (trace_name), "%s.json", filename);
 
+  FILE *f = fopen (trace_name, "w");
+  if (!f)
+    return;
+
+  fprintf (f, "{\n");
+  fprintf (f, "  \"traceEvents\": [\n");
+  fprintf (f, "    {\n");
+  fprintf (f, "      \"name\": \"total compilation\",\n");
+  fprintf (f, "      \"ph\": \"X\",\n");
+  fprintf (f, "      \"ts\": 0,\n");
+  fprintf (f, "      \"dur\": %lld,\n", end_us - start_us);
+  fprintf (f, "      \"pid\": 1,\n");
+  fprintf (f, "      \"tid\": 1\n");
+  fprintf (f, "    }\n");
+  fprintf (f, "  ],\n");
+  fprintf (f, "  \"displayTimeUnit\": \"us\"\n");
+  fprintf (f, "}\n");
+
+  fclose (f);
+}
 /* Initialize the compiler, and compile the input file.  */
 static void
 do_compile ()
 {
+  long long time_trace_start_us = 0;
+
+  if (flag_time_trace)
+    time_trace_start_us = gcc_time_trace_now_us ();
   /* Don't do any more if an error has already occurred.  */
   if (!seen_error ())
     {
@@ -2235,6 +2280,13 @@ do_compile ()
 
       timevar_stop (TV_PHASE_FINALIZE);
     }
+  if (flag_time_trace)
+    {
+      long long time_trace_end_us = gcc_time_trace_now_us ();
+      gcc_write_simple_time_trace (main_input_filename,
+                                   time_trace_start_us,
+                                   time_trace_end_us);
+    }
 }
 
 toplev::toplev (timer *external_timer,
-- 
2.34.1

