Compile a single module (in an nvvm context this means getting the llvm bitcode out of it)
(
cgcx: &CodegenContext<NvvmCodegenBackend>,
diag_handler: &Handler,
module: ModuleCodegen<LlvmMod>,
config: &ModuleConfig,
)
| 159 | |
| 160 | /// Compile a single module (in an nvvm context this means getting the llvm bitcode out of it) |
| 161 | pub(crate) unsafe fn codegen( |
| 162 | cgcx: &CodegenContext<NvvmCodegenBackend>, |
| 163 | diag_handler: &Handler, |
| 164 | module: ModuleCodegen<LlvmMod>, |
| 165 | config: &ModuleConfig, |
| 166 | ) -> Result<CompiledModule, FatalError> { |
| 167 | // For NVVM, all the codegen we need to do is turn the llvm modules |
| 168 | // into llvm bitcode and write them to a tempdir. nvvm expects llvm |
| 169 | // bitcode as the modules to be added to the program. Then as the last step |
| 170 | // we gather all those tasty bitcode files, add them to the nvvm program |
| 171 | // and finally tell nvvm to compile it, which gives us a ptx file. |
| 172 | // |
| 173 | // we also implement emit_ir so we can dump the IR fed to nvvm in case we |
| 174 | // feed it anything it doesnt like |
| 175 | |
| 176 | let _timer = cgcx |
| 177 | .prof |
| 178 | .generic_activity_with_arg("NVVM_module_codegen", &module.name[..]); |
| 179 | |
| 180 | let llmod = module.module_llvm.llmod.as_ref().unwrap(); |
| 181 | let mod_name = module.name.clone(); |
| 182 | let module_name = Some(&mod_name[..]); |
| 183 | |
| 184 | let out = cgcx |
| 185 | .output_filenames |
| 186 | .temp_path(OutputType::Object, module_name); |
| 187 | |
| 188 | // nvvm ir *is* llvm ir so emit_ir fits the expectation of llvm ir which is why we |
| 189 | // implement this. this is copy and pasted straight from rustc_codegen_llvm |
| 190 | // because im too lazy to make it seem like i rewrote this when its the same logic |
| 191 | if config.emit_ir { |
| 192 | let _timer = cgcx |
| 193 | .prof |
| 194 | .generic_activity_with_arg("NVVM_module_codegen_emit_ir", &module.name[..]); |
| 195 | let out = cgcx |
| 196 | .output_filenames |
| 197 | .temp_path(OutputType::LlvmAssembly, module_name); |
| 198 | let out_c = path_to_c_string(&out); |
| 199 | |
| 200 | let result = llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback); |
| 201 | |
| 202 | result.into_result().map_err(|()| { |
| 203 | let msg = format!("failed to write NVVM IR to {}", out.display()); |
| 204 | llvm_err(diag_handler, &msg) |
| 205 | })?; |
| 206 | } |
| 207 | |
| 208 | let _bc_timer = cgcx |
| 209 | .prof |
| 210 | .generic_activity_with_arg("NVVM_module_codegen_make_bitcode", &module.name[..]); |
| 211 | |
| 212 | let thin = ThinBuffer::new(llmod); |
| 213 | |
| 214 | let data = thin.data(); |
| 215 | |
| 216 | let _bc_emit_timer = cgcx |
| 217 | .prof |
| 218 | .generic_activity_with_arg("NVVM_module_codegen_emit_bitcode", &module.name[..]); |
no test coverage detected