Index: clang/test/Driver/check-time-trace-sections.py =================================================================== --- clang/test/Driver/check-time-trace-sections.py +++ clang/test/Driver/check-time-trace-sections.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -import json, sys +import json, sys, time def is_inside(range1, range2): a = range1["ts"]; b = a + range1["dur"] @@ -11,11 +11,20 @@ b = range1["ts"] + range1["dur"]; c = range2["ts"] return b <= c -events = json.loads(sys.stdin.read())["traceEvents"] +log_contents = json.loads(sys.stdin.read()) +events = log_contents["traceEvents"] codegens = [event for event in events if event["name"] == "CodeGen Function"] frontends = [event for event in events if event["name"] == "Frontend"] backends = [event for event in events if event["name"] == "Backend"] +beginning_of_time = log_contents["beginningOfTime"] / 1000000 +seconds_since_epoch = time.time() + +# Make sure that the 'beginningOfTime' is not earlier than 10 seconds ago. +if seconds_since_epoch - beginning_of_time > 10: + sys.exit("'beginningOfTime' should represent the absolute time when the " + "process has started") + if not all([any([is_inside(codegen, frontend) for frontend in frontends]) for codegen in codegens]): sys.exit("Not all CodeGen sections are inside any Frontend section!") Index: clang/test/Driver/check-time-trace.cpp =================================================================== --- clang/test/Driver/check-time-trace.cpp +++ clang/test/Driver/check-time-trace.cpp @@ -3,7 +3,8 @@ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s -// CHECK: "traceEvents": [ +// CHECK: "beginningOfTime": {{[0-9]{16},}} +// CHECK-NEXT: "traceEvents": [ // CHECK: "args": // CHECK: "detail": // CHECK: "dur": Index: lld/test/ELF/time-trace.s =================================================================== --- lld/test/ELF/time-trace.s +++ lld/test/ELF/time-trace.s @@ -18,7 +18,8 @@ # RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ # RUN: | FileCheck %s -# CHECK: "traceEvents": [ +# CHECK: "beginningOfTime": {{[0-9]{16},}} +# CHECK-NEXT: "traceEvents": [ # Check one event has correct fields # CHECK: "dur": Index: llvm/lib/Support/TimeProfiler.cpp =================================================================== --- llvm/lib/Support/TimeProfiler.cpp +++ llvm/lib/Support/TimeProfiler.cpp @@ -251,6 +251,21 @@ J.arrayEnd(); J.attributeEnd(); + + // Emit synchronization point, i. e. the absolute time of StartTime. + // When combining time profiler logs from different processes, + // this attribute helps preserve relative timing. + { + const auto SystemTime = + time_point_cast(system_clock::now()); + const microseconds ProcessLocalTime = + time_point_cast(steady_clock::now()) - + time_point_cast(StartTime); + const auto BeginningOfTimeUs = SystemTime - ProcessLocalTime; + J.attribute("beginningOfTime", + BeginningOfTimeUs.time_since_epoch().count()); + } + J.objectEnd(); }