This is the meat of the codegen, taking all of the llvm bitcode modules we have, and giving them to nvvm to make into a final
(
allocator: &Option<CompiledModule>,
sess: &Session,
objects: &[PathBuf],
rlibs: &[PathBuf],
out_filename: &Path,
)
| 197 | /// This is the meat of the codegen, taking all of the llvm bitcode modules we have, and giving them to |
| 198 | /// nvvm to make into a final |
| 199 | fn codegen_into_ptx_file( |
| 200 | allocator: &Option<CompiledModule>, |
| 201 | sess: &Session, |
| 202 | objects: &[PathBuf], |
| 203 | rlibs: &[PathBuf], |
| 204 | out_filename: &Path, |
| 205 | ) -> io::Result<()> { |
| 206 | debug!("Codegenning crate into PTX, allocator: {}, objects:\n{:#?}, rlibs:\n{:#?}, out_filename:\n{:#?}", |
| 207 | allocator.is_some(), |
| 208 | objects, |
| 209 | rlibs, |
| 210 | out_filename |
| 211 | ); |
| 212 | |
| 213 | // we need to make a new llvm context because we need it for linking together modules, |
| 214 | // but we dont have our original one because rustc drops tyctxt and codegencx before linking. |
| 215 | let cx = LlvmMod::new("link_tmp"); |
| 216 | |
| 217 | let mut modules = Vec::with_capacity(objects.len() + rlibs.len()); |
| 218 | |
| 219 | // object files (theyre not object files, they are impostors ඞ) are the bitcode modules produced by this codegen session |
| 220 | // they *should* be the final crate. |
| 221 | for obj in objects { |
| 222 | let bitcode = std::fs::read(obj)?; |
| 223 | modules.push(bitcode); |
| 224 | } |
| 225 | |
| 226 | // rlibs are archives that we made previously, they are usually made for crates that are referenced |
| 227 | // in this crate. We must unpack them and devour their bitcode to link in. |
| 228 | for rlib in rlibs { |
| 229 | let mut cgus = Vec::with_capacity(16); |
| 230 | for entry in Archive::new(File::open(rlib)?).entries()? { |
| 231 | let mut entry = entry?; |
| 232 | // metadata is where rustc puts rlib metadata, so its not a cgu we are interested in. |
| 233 | if entry.path().unwrap() != Path::new(".metadata") { |
| 234 | // std::fs::read adds 1 to the size, so do the same here - see comment: |
| 235 | // https://github.com/rust-lang/rust/blob/72868e017bdade60603a25889e253f556305f996/library/std/src/fs.rs#L200-L202 |
| 236 | let mut bitcode = Vec::with_capacity(entry.size() as usize + 1); |
| 237 | entry.read_to_end(&mut bitcode).unwrap(); |
| 238 | cgus.push(bitcode); |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | modules.extend(cgus); |
| 243 | } |
| 244 | |
| 245 | if let Some(alloc) = allocator { |
| 246 | let bc = std::fs::read( |
| 247 | alloc |
| 248 | .object |
| 249 | .clone() |
| 250 | .expect("expected obj path for allocator module"), |
| 251 | )?; |
| 252 | modules.push(bc); |
| 253 | } |
| 254 | |
| 255 | // now that we have our nice bitcode modules, we just need to find libdevice and give our |
| 256 | // modules to nvvm to make a final ptx file |