| 150 | } |
| 151 | |
| 152 | pub fn link( |
| 153 | sess: &Session, |
| 154 | mut inputs: Vec<Module>, |
| 155 | opts: &Options, |
| 156 | outputs: &OutputFilenames, |
| 157 | disambiguated_crate_name_for_dumps: &OsStr, |
| 158 | ) -> Result<LinkResult> { |
| 159 | let mut output = { |
| 160 | let _timer = sess.timer("link_merge"); |
| 161 | // shift all the ids |
| 162 | let mut bound = inputs[0].header.as_ref().unwrap().bound - 1; |
| 163 | let version = inputs[0].header.as_ref().unwrap().version(); |
| 164 | |
| 165 | for module in inputs.iter_mut().skip(1) { |
| 166 | simple_passes::shift_ids(module, bound); |
| 167 | bound += module.header.as_ref().unwrap().bound - 1; |
| 168 | let this_version = module.header.as_ref().unwrap().version(); |
| 169 | if version != this_version { |
| 170 | return Err(sess.err(format!( |
| 171 | "cannot link two modules with different SPIR-V versions: v{}.{} and v{}.{}", |
| 172 | version.0, version.1, this_version.0, this_version.1 |
| 173 | ))); |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | // merge the binaries |
| 178 | let mut loader = Loader::new(); |
| 179 | |
| 180 | for module in inputs { |
| 181 | module.all_inst_iter().for_each(|inst| { |
| 182 | loader.consume_instruction(inst.clone()); |
| 183 | }); |
| 184 | } |
| 185 | |
| 186 | let mut output = loader.module(); |
| 187 | let mut header = ModuleHeader::new(bound + 1); |
| 188 | header.set_version(version.0, version.1); |
| 189 | header.generator = 0x001B_0000; |
| 190 | output.header = Some(header); |
| 191 | output |
| 192 | }; |
| 193 | |
| 194 | if let Some(dir) = &opts.dump_post_merge { |
| 195 | std::fs::write( |
| 196 | dir.join(disambiguated_crate_name_for_dumps) |
| 197 | .with_extension("spv"), |
| 198 | spirv_tools::binary::from_binary(&output.assemble()), |
| 199 | ) |
| 200 | .unwrap(); |
| 201 | } |
| 202 | |
| 203 | // remove duplicates (https://github.com/KhronosGroup/SPIRV-Tools/blob/e7866de4b1dc2a7e8672867caeb0bdca49f458d3/source/opt/remove_duplicates_pass.cpp) |
| 204 | { |
| 205 | let _timer = sess.timer("link_remove_duplicates"); |
| 206 | duplicates::remove_duplicate_extensions(&mut output); |
| 207 | duplicates::remove_duplicate_capablities(&mut output); |
| 208 | duplicates::remove_duplicate_ext_inst_imports(&mut output); |
| 209 | duplicates::remove_duplicate_types(&mut output); |