MCPcopy Create free account
hub / github.com/Rust-GPU/rust-cuda / codegen_bitcode_modules

Function codegen_bitcode_modules

crates/rustc_codegen_nvvm/src/nvvm.rs:52–137  ·  view source on GitHub ↗

Take a list of bitcode module bytes and their names and codegen it into ptx bytes. The final PTX *should* be utf8, but just to be on the safe side it returns a vector of bytes. Note that this will implicitly try to find libdevice and add it, so don't do that step before this. It will fatal error if it cannot find it.

(
    opts: &[NvvmOption],
    sess: &Session,
    modules: Vec<Vec<u8>>,
    llcx: &Context,
)

Source from the content-addressed store, hash-verified

50/// Note that this will implicitly try to find libdevice and add it, so don't do that
51/// step before this. It will fatal error if it cannot find it.
52pub fn codegen_bitcode_modules(
53 opts: &[NvvmOption],
54 sess: &Session,
55 modules: Vec<Vec<u8>>,
56 llcx: &Context,
57) -> Result<Vec<u8>, CodegenErr> {
58 debug!("Codegenning bitcode to PTX");
59
60 // make sure the nvvm version is high enough so users don't get confusing compilation errors.
61 let (major, minor) = nvvm::ir_version();
62
63 if minor < 6 || major < 1 {
64 sess.fatal("rustc_codegen_nvvm requires at least libnvvm 1.6 (CUDA 11.2)");
65 }
66
67 // first, create the nvvm program we will add modules to.
68 let prog = NvvmProgram::new()?;
69
70 let module = merge_llvm_modules(modules, llcx);
71 unsafe {
72 internalize_pass(module, llcx);
73 dce_pass(module);
74
75 if sess.opts.debuginfo != DebugInfo::None {
76 cleanup_dicompileunit(module);
77 }
78
79 let (dbg_major, dbg_minor) = nvvm::dbg_version();
80
81 // needed for debug info or else nvvm complains about ir version mismatch for some
82 // reason. It works if you don't use debug info though...
83 let ty_i32 = LLVMInt32TypeInContext(llcx);
84 let major = LLVMConstInt(ty_i32, major as u64, False);
85 let minor = LLVMConstInt(ty_i32, minor as u64, False);
86 let dbg_major = LLVMConstInt(ty_i32, dbg_major as u64, False);
87 let dbg_minor = LLVMConstInt(ty_i32, dbg_minor as u64, False);
88 let vals = vec![major, minor, dbg_major, dbg_minor];
89 let node = LLVMMDNodeInContext(llcx, vals.as_ptr(), vals.len() as u32);
90
91 LLVMAddNamedMetadataOperand(module, "nvvmir.version\0".as_ptr().cast(), node);
92 }
93 let buf = ThinBuffer::new(module);
94
95 prog.add_module(buf.data(), "merged".to_string())?;
96
97 let libdevice = if let Some(bc) = find_libdevice() {
98 bc
99 } else {
100 // i would put a more helpful error here, but to actually use the codegen
101 // it needs to find libnvvm before this, and libdevice is in the nvvm directory
102 // so if it can find libnvvm there is almost no way it can't find libdevice.
103 sess.fatal("Could not find the libdevice library (libdevice.10.bc) in the CUDA directory")
104 };
105
106 prog.add_lazy_module(&libdevice, "libdevice".to_string())?;
107 prog.add_lazy_module(LIBINTRINSICS, "libintrinsics".to_string())?;
108
109 // for now, while the codegen is young, we always run verification on the program.

Callers 1

codegen_into_ptx_fileFunction · 0.85

Calls 15

ir_versionFunction · 0.85
newFunction · 0.85
merge_llvm_modulesFunction · 0.85
internalize_passFunction · 0.85
dce_passFunction · 0.85
cleanup_dicompileunitFunction · 0.85
dbg_versionFunction · 0.85
find_libdeviceFunction · 0.85
fatalMethod · 0.80
as_ptrMethod · 0.80
add_moduleMethod · 0.80
add_lazy_moduleMethod · 0.80

Tested by

no test coverage detected