| 514 | } |
| 515 | |
| 516 | StatusOr<std::unique_ptr<Executable>> GpuCompiler::RunBackend( |
| 517 | std::unique_ptr<HloModule> module, se::StreamExecutor* stream_exec, |
| 518 | se::DeviceMemoryAllocator* device_allocator) { |
| 519 | XLA_SCOPED_LOGGING_TIMER("GpuCompiler::RunBackend"); |
| 520 | auto slow_compile_alarm = SlowCompilationAlarm(); |
| 521 | |
| 522 | TF_RET_CHECK(stream_exec != nullptr); |
| 523 | |
| 524 | llvm::LLVMContext llvm_context; |
| 525 | std::string buffer; |
| 526 | llvm::raw_string_ostream error(buffer); |
| 527 | llvm::DiagnosticPrinterRawOStream printer(error); |
| 528 | auto DiagnosticHandler = [](const llvm::DiagnosticInfo& diag_info, |
| 529 | void* Context) { |
| 530 | auto printer = static_cast<llvm::DiagnosticPrinterRawOStream*>(Context); |
| 531 | diag_info.print(*printer); |
| 532 | }; |
| 533 | llvm_context.setDiagnosticHandlerCallBack(DiagnosticHandler, &printer); |
| 534 | |
| 535 | GpuDeviceInfo gpu_device_info = GetGpuDeviceInfo(stream_exec); |
| 536 | |
| 537 | absl::optional<CudaComputeCapability> cuda_compute_capability = |
| 538 | [&]() -> absl::optional<CudaComputeCapability> { |
| 539 | CudaComputeCapability cuda_compute_capability; |
| 540 | stream_exec->GetDeviceDescription().cuda_compute_capability( |
| 541 | &cuda_compute_capability.cc_major, &cuda_compute_capability.cc_minor); |
| 542 | if (cuda_compute_capability.cc_major == -1) { |
| 543 | return absl::nullopt; |
| 544 | } |
| 545 | return cuda_compute_capability; |
| 546 | }(); |
| 547 | |
| 548 | std::unique_ptr<llvm::Module> llvm_module; |
| 549 | std::unique_ptr<StreamAssignment> stream_assignment; |
| 550 | std::unique_ptr<GpuHloSchedule> hlo_schedule; |
| 551 | std::unique_ptr<BufferAssignment> buffer_assignment; |
| 552 | std::unique_ptr<ThunkSequence> thunk_sequence; |
| 553 | |
| 554 | TF_RETURN_IF_ERROR(CompileModuleToLlvmIrImpl( |
| 555 | module.get(), &llvm_context, target_triple_, data_layout_, |
| 556 | stream_exec->platform()->Name(), gpu_device_info, cuda_compute_capability, |
| 557 | GetCanShareBuffer(), pointer_size_, &llvm_module, &stream_assignment, |
| 558 | &hlo_schedule, &buffer_assignment, &thunk_sequence)); |
| 559 | |
| 560 | if (user_pre_optimization_hook_) { |
| 561 | user_pre_optimization_hook_(*llvm_module); |
| 562 | } |
| 563 | string ir_module_string_before_opt; |
| 564 | const bool embed_ir_in_executable = |
| 565 | module->config().debug_options().xla_embed_ir_in_executable(); |
| 566 | if (embed_ir_in_executable) { |
| 567 | ir_module_string_before_opt = llvm_ir::DumpModuleToString(*llvm_module); |
| 568 | } |
| 569 | |
| 570 | llvm_ir::DumpIrIfEnabled(*module, *llvm_module, /*optimized=*/false); |
| 571 | |
| 572 | { |
| 573 | XLA_SCOPED_LOGGING_TIMER("GpuCompiler::RunBackend - Running LLVM verifier"); |