diff --git a/llvm/test/tools/llc/time-trace.ll b/llvm/test/tools/llc/time-trace.ll new file mode 100644 index 000000000000..49e2890f58de --- /dev/null +++ b/llvm/test/tools/llc/time-trace.ll @@ -0,0 +1,8 @@ +; RUN: llc -o /dev/null -O2 -time-trace -time-trace-granularity=100 -time-trace-file=%t.json +; RUN: FileCheck --input-file=%t.json %s + +; CHECK: "traceEvents" + +define void @f() { + ret void +} diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp index ea0de16d4d22..9d80f062c8f9 100644 --- a/llvm/tools/llc/llc.cpp +++ b/llvm/tools/llc/llc.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/Triple.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/CodeGen/CommandFlags.h" @@ -49,6 +50,7 @@ #include "llvm/Support/PluginLoader.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetSelect.h" +#include "llvm/Support/TimeProfiler.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/WithColor.h" #include "llvm/Target/TargetLoweringObjectFile.h" @@ -82,6 +84,19 @@ TimeCompilations("time-compilations", cl::Hidden, cl::init(1u), cl::value_desc("N"), cl::desc("Repeat compilation N times for timing")); +static cl::opt TimeTrace("time-trace", cl::desc("Record time trace")); + +static cl::opt TimeTraceGranularity( + "time-trace-granularity", + cl::desc( + "Minimum time granularity (in microseconds) traced by time profiler"), + cl::init(500), cl::Hidden); + +static cl::opt + TimeTraceFile("time-trace-file", + cl::desc("Specify time trace file destination"), + cl::value_desc("filename")); + static cl::opt BinutilsVersion("binutils-version", cl::Hidden, cl::desc("Produced object files can use all ELF features " @@ -363,6 +378,20 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); + if (TimeTrace) + timeTraceProfilerInitialize(TimeTraceGranularity, argv[0]); + auto TimeTraceScopeExit = make_scope_exit([]() { + if (TimeTrace) { + if (auto E = timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) { + handleAllErrors(std::move(E), [&](const StringError &SE) { + errs() << SE.getMessage() << "\n"; + }); + return; + } + timeTraceProfilerCleanup(); + } + }); + LLVMContext Context; Context.setDiscardValueNames(DiscardValueNames);