| ... | ... | @@ -46,7 +46,9 @@ |
| 46 | 46 | #include <llvm/Support/CommandLine.h> |
| 47 | 47 | #include <llvm/Support/Host.h> |
| 48 | 48 | #include <llvm/Support/FileSystem.h> |
| 49 | #include <llvm/Support/Process.h> |
| 49 | 50 | #include <llvm/Support/TargetParser.h> |
| 51 | #include <llvm/Support/TimeProfiler.h> |
| 50 | 52 | #include <llvm/Support/Timer.h> |
| 51 | 53 | #include <llvm/Support/raw_ostream.h> |
| 52 | 54 | #include <llvm/Support/TargetRegistry.h> |
| ... | ... | @@ -187,13 +189,48 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) { |
| 187 | 189 | return unwrap(TD)->getProgramAddressSpace(); |
| 188 | 190 | } |
| 189 | 191 | |
| 192 | namespace { |
| 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. |
| 196 | struct 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 | |
| 190 | 229 | bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, |
| 191 | 230 | char **error_message, bool is_debug, |
| 192 | 231 | bool is_small, bool time_report, bool tsan, bool lto, |
| 193 | 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 | 234 | TimePassesIsEnabled = time_report; |
| 198 | 235 | |
| 199 | 236 | raw_fd_ostream *dest_asm_ptr = nullptr; |
| ... | ... | @@ -219,6 +256,12 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 219 | 256 | std::unique_ptr<raw_fd_ostream> dest_asm(dest_asm_ptr), |
| 220 | 257 | dest_bin(dest_bin_ptr); |
| 221 | 258 | |
| 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 | 265 | TargetMachine &target_machine = *reinterpret_cast<TargetMachine*>(targ_machine_ref); |
| 223 | 266 | target_machine.setO0WantsFastISel(true); |
| 224 | 267 | |