[llvm] 98827fe - [lit] Add --time-trace-output to lit

Russell Gallop via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 4 06:26:13 PDT 2020


Author: Russell Gallop
Date: 2020-08-04T14:25:23+01:00
New Revision: 98827feddb90b8d8bfeb3c85f7801ee411bab2cd

URL: https://github.com/llvm/llvm-project/commit/98827feddb90b8d8bfeb3c85f7801ee411bab2cd
DIFF: https://github.com/llvm/llvm-project/commit/98827feddb90b8d8bfeb3c85f7801ee411bab2cd.diff

LOG: [lit] Add --time-trace-output to lit

This produces a chrome://tracing compatible trace file in the same way
as -ftime-trace.

This can be useful in optimising test time where one long test is causing
long overall test time on a wide machine.

This also helped in finding tests which have side effects on others
(e.g. https://reviews.llvm.org/D84885).

Differential Revision: https://reviews.llvm.org/D84931

Added: 
    

Modified: 
    llvm/utils/lit/lit/Test.py
    llvm/utils/lit/lit/cl_arguments.py
    llvm/utils/lit/lit/reports.py
    llvm/utils/lit/lit/worker.py

Removed: 
    


################################################################################
diff  --git a/llvm/utils/lit/lit/Test.py b/llvm/utils/lit/lit/Test.py
index a38ea4e7717a..59fefbc7f089 100644
--- a/llvm/utils/lit/lit/Test.py
+++ b/llvm/utils/lit/lit/Test.py
@@ -150,6 +150,8 @@ def __init__(self, code, output='', elapsed=None):
         self.output = output
         # The wall timing to execute the test, if timing.
         self.elapsed = elapsed
+        self.start = None
+        self.pid = None
         # The metrics reported by this test.
         self.metrics = {}
         # The micro-test results reported by this test.

diff  --git a/llvm/utils/lit/lit/cl_arguments.py b/llvm/utils/lit/lit/cl_arguments.py
index baeb3635298f..69166e00aba8 100644
--- a/llvm/utils/lit/lit/cl_arguments.py
+++ b/llvm/utils/lit/lit/cl_arguments.py
@@ -109,6 +109,9 @@ def parse_args():
     execution_group.add_argument("--xunit-xml-output",
             type=lit.reports.XunitReport,
             help="Write XUnit-compatible XML test reports to the specified file")
+    execution_group.add_argument("--time-trace-output",
+            type=lit.reports.TimeTraceReport,
+            help="Write Chrome tracing compatible JSON to the specified file")
     execution_group.add_argument("--timeout",
             dest="maxIndividualTestTime",
             help="Maximum time to spend running a single test (in seconds). "
@@ -195,7 +198,7 @@ def parse_args():
     else:
         opts.shard = None
 
-    opts.reports = filter(None, [opts.output, opts.xunit_xml_output])
+    opts.reports = filter(None, [opts.output, opts.xunit_xml_output, opts.time_trace_output])
 
     return opts
 

diff  --git a/llvm/utils/lit/lit/reports.py b/llvm/utils/lit/lit/reports.py
index 3ce961b44029..b43f77911673 100755
--- a/llvm/utils/lit/lit/reports.py
+++ b/llvm/utils/lit/lit/reports.py
@@ -136,3 +136,35 @@ def _get_skip_reason(self, test):
         if features:
             return 'Missing required feature(s): ' + ', '.join(features)
         return 'Unsupported configuration'
+
+
+class TimeTraceReport(object):
+    def __init__(self, output_file):
+        self.output_file = output_file
+        self.skipped_codes = {lit.Test.EXCLUDED,
+                              lit.Test.SKIPPED, lit.Test.UNSUPPORTED}
+
+    def write_results(self, tests, elapsed):
+        # Find when first test started so we can make start times relative.
+        first_start_time = min([t.result.start for t in tests])
+        events = [self._get_test_event(
+            x, first_start_time) for x in tests if x.result.code not in self.skipped_codes]
+
+        json_data = {'traceEvents': events}
+
+        with open(self.output_file, "w") as time_trace_file:
+            json.dump(json_data, time_trace_file, indent=2, sort_keys=True)
+
+    def _get_test_event(self, test, first_start_time):
+        test_name = test.getFullName()
+        elapsed_time = test.result.elapsed or 0.0
+        start_time = test.result.start - first_start_time if test.result.start else 0.0
+        pid = test.result.pid or 0
+        return {
+            'pid': pid,
+            'tid': 1,
+            'ph': 'X',
+            'ts': int(start_time * 1000000.),
+            'dur': int(elapsed_time * 1000000.),
+            'name': test_name,
+        }

diff  --git a/llvm/utils/lit/lit/worker.py b/llvm/utils/lit/lit/worker.py
index 04fc77239e02..ba9b919f50eb 100644
--- a/llvm/utils/lit/lit/worker.py
+++ b/llvm/utils/lit/lit/worker.py
@@ -6,6 +6,7 @@
 and store it in global variables. This reduces the cost of each task.
 """
 import contextlib
+import os
 import signal
 import time
 import traceback
@@ -65,6 +66,8 @@ def _execute(test, lit_config):
     start = time.time()
     result = _execute_test_handle_errors(test, lit_config)
     result.elapsed = time.time() - start
+    result.start = start
+    result.pid = os.getpid()
     return result
 
 


        


More information about the llvm-commits mailing list