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,18 +3,19 @@ // 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: "args": -// CHECK: "detail": -// CHECK: "dur": -// CHECK: "name": +// CHECK: "beginningOfTime": {{[0-9]{16},}} +// CHECK-NEXT: "traceEvents": [ +// CHECK: "args": +// CHECK: "detail": +// CHECK: "dur": +// CHECK: "name": // CHECK-NEXT: "ph": // CHECK-NEXT: "pid": // CHECK-NEXT: "tid": // CHECK-NEXT: "ts": -// CHECK: "name": "clang{{.*}}" -// CHECK: "name": "process_name" -// CHECK: "name": "thread_name" +// CHECK: "name": "clang{{.*}}" +// CHECK: "name": "process_name" +// CHECK: "name": "thread_name" template struct Struct { 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 @@ -75,9 +75,9 @@ struct llvm::TimeTraceProfiler { TimeTraceProfiler(unsigned TimeTraceGranularity = 0, StringRef ProcName = "") - : StartTime(steady_clock::now()), ProcName(ProcName), - Pid(sys::Process::getProcessId()), Tid(llvm::get_threadid()), - TimeTraceGranularity(TimeTraceGranularity) { + : BeginningOfTime(system_clock::now()), StartTime(steady_clock::now()), + ProcName(ProcName), Pid(sys::Process::getProcessId()), + Tid(llvm::get_threadid()), TimeTraceGranularity(TimeTraceGranularity) { llvm::get_thread_name(ThreadName); } @@ -234,12 +234,22 @@ J.arrayEnd(); J.attributeEnd(); + + // Emit the absolute time of the moment when this TimeProfiler started + // measurements. This can be used to combine the profiling data from + // multiple processes and preserve actual time intervals. + J.attribute("beginningOfTime", + time_point_cast(BeginningOfTime) + .time_since_epoch() + .count()); + J.objectEnd(); } SmallVector Stack; SmallVector Entries; StringMap CountAndTotalPerName; + const time_point BeginningOfTime; const TimePointType StartTime; const std::string ProcName; const sys::Process::Pid Pid;