1351278Sdim//===- llvm/Support/TimeProfiler.h - Hierarchical Time Profiler -*- C++ -*-===//
2351278Sdim//
3351278Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4351278Sdim// See https://llvm.org/LICENSE.txt for license information.
5351278Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6351278Sdim//
7351278Sdim//===----------------------------------------------------------------------===//
8351278Sdim
9351278Sdim#ifndef LLVM_SUPPORT_TIME_PROFILER_H
10351278Sdim#define LLVM_SUPPORT_TIME_PROFILER_H
11351278Sdim
12351278Sdim#include "llvm/Support/raw_ostream.h"
13351278Sdim
14351278Sdimnamespace llvm {
15351278Sdim
16351278Sdimstruct TimeTraceProfiler;
17351278Sdimextern TimeTraceProfiler *TimeTraceProfilerInstance;
18351278Sdim
19351278Sdim/// Initialize the time trace profiler.
20351278Sdim/// This sets up the global \p TimeTraceProfilerInstance
21351278Sdim/// variable to be the profiler instance.
22360784Sdimvoid timeTraceProfilerInitialize(unsigned TimeTraceGranularity,
23360784Sdim                                 StringRef ProcName);
24351278Sdim
25351278Sdim/// Cleanup the time trace profiler, if it was initialized.
26351278Sdimvoid timeTraceProfilerCleanup();
27351278Sdim
28351278Sdim/// Is the time trace profiler enabled, i.e. initialized?
29351278Sdiminline bool timeTraceProfilerEnabled() {
30351278Sdim  return TimeTraceProfilerInstance != nullptr;
31351278Sdim}
32351278Sdim
33351278Sdim/// Write profiling data to output file.
34351278Sdim/// Data produced is JSON, in Chrome "Trace Event" format, see
35351278Sdim/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
36351278Sdimvoid timeTraceProfilerWrite(raw_pwrite_stream &OS);
37351278Sdim
38351278Sdim/// Manually begin a time section, with the given \p Name and \p Detail.
39351278Sdim/// Profiler copies the string data, so the pointers can be given into
40351278Sdim/// temporaries. Time sections can be hierarchical; every Begin must have a
41351278Sdim/// matching End pair but they can nest.
42351278Sdimvoid timeTraceProfilerBegin(StringRef Name, StringRef Detail);
43351278Sdimvoid timeTraceProfilerBegin(StringRef Name,
44351278Sdim                            llvm::function_ref<std::string()> Detail);
45351278Sdim
46351278Sdim/// Manually end the last time section.
47351278Sdimvoid timeTraceProfilerEnd();
48351278Sdim
49351278Sdim/// The TimeTraceScope is a helper class to call the begin and end functions
50351278Sdim/// of the time trace profiler.  When the object is constructed, it begins
51351278Sdim/// the section; and when it is destroyed, it stops it. If the time profiler
52351278Sdim/// is not initialized, the overhead is a single branch.
53351278Sdimstruct TimeTraceScope {
54351278Sdim
55351278Sdim  TimeTraceScope() = delete;
56351278Sdim  TimeTraceScope(const TimeTraceScope &) = delete;
57351278Sdim  TimeTraceScope &operator=(const TimeTraceScope &) = delete;
58351278Sdim  TimeTraceScope(TimeTraceScope &&) = delete;
59351278Sdim  TimeTraceScope &operator=(TimeTraceScope &&) = delete;
60351278Sdim
61360784Sdim  TimeTraceScope(StringRef Name) {
62360784Sdim    if (TimeTraceProfilerInstance != nullptr)
63360784Sdim      timeTraceProfilerBegin(Name, StringRef(""));
64360784Sdim  }
65351278Sdim  TimeTraceScope(StringRef Name, StringRef Detail) {
66351278Sdim    if (TimeTraceProfilerInstance != nullptr)
67351278Sdim      timeTraceProfilerBegin(Name, Detail);
68351278Sdim  }
69351278Sdim  TimeTraceScope(StringRef Name, llvm::function_ref<std::string()> Detail) {
70351278Sdim    if (TimeTraceProfilerInstance != nullptr)
71351278Sdim      timeTraceProfilerBegin(Name, Detail);
72351278Sdim  }
73351278Sdim  ~TimeTraceScope() {
74351278Sdim    if (TimeTraceProfilerInstance != nullptr)
75351278Sdim      timeTraceProfilerEnd();
76351278Sdim  }
77351278Sdim};
78351278Sdim
79351278Sdim} // end namespace llvm
80351278Sdim
81351278Sdim#endif
82