diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 7866537c64..722b77406e 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -46,7 +46,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -187,13 +189,48 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) { return unwrap(TD)->getProgramAddressSpace(); } +namespace { +// LLVM's time profiler can provide a hierarchy view of the time spent +// in each component. It generates JSON report in Chrome's "Trace Event" +// format. So the report can be easily visualized by the Chrome browser. +struct TimeTracerRAII { + // Granularity in ms + unsigned TimeTraceGranularity; + StringRef TimeTraceFile, OutputFilename; + bool EnableTimeTrace; + + TimeTracerRAII(StringRef ProgramName, StringRef OF) + : TimeTraceGranularity(500U), + TimeTraceFile(std::getenv("ZIG_LLVM_TIME_TRACE_FILE")), + OutputFilename(OF), + EnableTimeTrace(!TimeTraceFile.empty()) { + if (EnableTimeTrace) { + if (const char *G = std::getenv("ZIG_LLVM_TIME_TRACE_GRANULARITY")) + TimeTraceGranularity = (unsigned)std::atoi(G); + + llvm::timeTraceProfilerInitialize(TimeTraceGranularity, ProgramName); + } + } + + ~TimeTracerRAII() { + if (EnableTimeTrace) { + if (auto E = llvm::timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) { + handleAllErrors(std::move(E), [&](const StringError &SE) { + errs() << SE.getMessage() << "\n"; + }); + return; + } + timeTraceProfilerCleanup(); + } + } +}; +} // end anonymous namespace + bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, char **error_message, bool is_debug, bool is_small, bool time_report, bool tsan, bool lto, const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename) { - // TODO: Maybe we should collect time trace rather than using timer - // to get a more hierarchical timeline view TimePassesIsEnabled = time_report; raw_fd_ostream *dest_asm_ptr = nullptr; @@ -219,6 +256,12 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM std::unique_ptr dest_asm(dest_asm_ptr), dest_bin(dest_bin_ptr); + auto PID = sys::Process::getProcessId(); + std::string ProcName = "zig-"; + ProcName += std::to_string(PID); + TimeTracerRAII TimeTracer(ProcName, + bin_filename? bin_filename : asm_filename); + TargetMachine &target_machine = *reinterpret_cast(targ_machine_ref); target_machine.setO0WantsFastISel(true);