authorgravatar for minyihh@uci.eduMin-Yih Hsu <minyihh@uci.edu> 2021-06-04 00:32:37-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-06-04 09:32:37+02:00
log83e0a49ba4938fb90b27c01ce9adc3dbe2984164
tree92a7463ec5c24c5edacafbf1f46517c38f6b913f
parent9c08a33b2226239b8e0cf08ebcef17d710a54d8a
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

llvm: Add support for collecting time trace (#8546)

LLVM time profiler can collect time traces and present them in a hierarchical view. Which breakdowns the time spent in each Pass or even IR unit. The result is also exported into a format that can be easily visualized by the Chrome browser. Currently this features is controlled by the following environment variables: - `ZIG_LLVM_TIME_TRACE_FILE` toggles this feature and specifies the output time trace file. - `ZIG_LLVM_TIME_TRACE_GRANULARITY` controls the time granularity in ms (default to 500).

1 files changed, 45 insertions(+), 2 deletions(-)

src/zig_llvm.cpp+45-2
...@@ -46,7 +46,9 @@...@@ -46,7 +46,9 @@
46#include <llvm/Support/CommandLine.h>46#include <llvm/Support/CommandLine.h>
47#include <llvm/Support/Host.h>47#include <llvm/Support/Host.h>
48#include <llvm/Support/FileSystem.h>48#include <llvm/Support/FileSystem.h>
49#include <llvm/Support/Process.h>
49#include <llvm/Support/TargetParser.h>50#include <llvm/Support/TargetParser.h>
51#include <llvm/Support/TimeProfiler.h>
50#include <llvm/Support/Timer.h>52#include <llvm/Support/Timer.h>
51#include <llvm/Support/raw_ostream.h>53#include <llvm/Support/raw_ostream.h>
52#include <llvm/Support/TargetRegistry.h>54#include <llvm/Support/TargetRegistry.h>
...@@ -187,13 +189,48 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) {...@@ -187,13 +189,48 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) {
187 return unwrap(TD)->getProgramAddressSpace();189 return unwrap(TD)->getProgramAddressSpace();
188}190}
189191
192namespace {
193// LLVM's time profiler can provide a hierarchy view of the time spent
194// in each component. It generates JSON report in Chrome's "Trace Event"
195// format. So the report can be easily visualized by the Chrome browser.
196struct TimeTracerRAII {
197 // Granularity in ms
198 unsigned TimeTraceGranularity;
199 StringRef TimeTraceFile, OutputFilename;
200 bool EnableTimeTrace;
201
202 TimeTracerRAII(StringRef ProgramName, StringRef OF)
203 : TimeTraceGranularity(500U),
204 TimeTraceFile(std::getenv("ZIG_LLVM_TIME_TRACE_FILE")),
205 OutputFilename(OF),
206 EnableTimeTrace(!TimeTraceFile.empty()) {
207 if (EnableTimeTrace) {
208 if (const char *G = std::getenv("ZIG_LLVM_TIME_TRACE_GRANULARITY"))
209 TimeTraceGranularity = (unsigned)std::atoi(G);
210
211 llvm::timeTraceProfilerInitialize(TimeTraceGranularity, ProgramName);
212 }
213 }
214
215 ~TimeTracerRAII() {
216 if (EnableTimeTrace) {
217 if (auto E = llvm::timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) {
218 handleAllErrors(std::move(E), [&](const StringError &SE) {
219 errs() << SE.getMessage() << "\n";
220 });
221 return;
222 }
223 timeTraceProfilerCleanup();
224 }
225 }
226};
227} // end anonymous namespace
228
190bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,229bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
191 char **error_message, bool is_debug,230 char **error_message, bool is_debug,
192 bool is_small, bool time_report, bool tsan, bool lto,231 bool is_small, bool time_report, bool tsan, bool lto,
193 const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename)232 const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename)
194{233{
195 // TODO: Maybe we should collect time trace rather than using timer
196 // to get a more hierarchical timeline view
197 TimePassesIsEnabled = time_report;234 TimePassesIsEnabled = time_report;
198235
199 raw_fd_ostream *dest_asm_ptr = nullptr;236 raw_fd_ostream *dest_asm_ptr = nullptr;
...@@ -219,6 +256,12 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM...@@ -219,6 +256,12 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
219 std::unique_ptr<raw_fd_ostream> dest_asm(dest_asm_ptr),256 std::unique_ptr<raw_fd_ostream> dest_asm(dest_asm_ptr),
220 dest_bin(dest_bin_ptr);257 dest_bin(dest_bin_ptr);
221258
259 auto PID = sys::Process::getProcessId();
260 std::string ProcName = "zig-";
261 ProcName += std::to_string(PID);
262 TimeTracerRAII TimeTracer(ProcName,
263 bin_filename? bin_filename : asm_filename);
264
222 TargetMachine &target_machine = *reinterpret_cast<TargetMachine*>(targ_machine_ref);265 TargetMachine &target_machine = *reinterpret_cast<TargetMachine*>(targ_machine_ref);
223 target_machine.setO0WantsFastISel(true);266 target_machine.setO0WantsFastISel(true);
224267