Optimize a little bit of kill_linkage_instructions that I forgot, which reduces time by another 2-3x

Also add various other timers, and use the helpful timer() function
This commit is contained in:
khyperia 2020-09-29 13:04:55 +02:00
parent 9bd7db20df
commit eaf350d2a8
3 changed files with 34 additions and 31 deletions

View File

@ -171,18 +171,15 @@ fn replace_all_uses_with(module: &mut rspirv::dr::Module, rules: &HashMap<u32, u
fn kill_linkage_instructions(module: &mut rspirv::dr::Module, rewrite_rules: &HashMap<u32, u32>) {
// drop imported functions
for &id in rewrite_rules.keys() {
module
.functions
.retain(|f| id != f.def.as_ref().unwrap().result_id.unwrap());
}
module
.functions
.retain(|f| !rewrite_rules.contains_key(&f.def.as_ref().unwrap().result_id.unwrap()));
// drop imported variables
for &id in rewrite_rules.keys() {
module
.types_global_values
.retain(|v| v.result_id.map_or(true, |v| v != id));
}
module.types_global_values.retain(|v| {
v.result_id
.map_or(true, |v| !rewrite_rules.contains_key(&v))
});
module.annotations.retain(|inst| {
inst.class.opcode != spirv::Op::Decorate

View File

@ -270,7 +270,7 @@ impl CodegenBackend for SpirvCodegenBackend {
return Ok(());
}
let timer = sess.prof.generic_activity("link_crate");
let timer = sess.timer("link_crate");
link::link(
sess,
&codegen_results,
@ -449,7 +449,7 @@ impl ExtraBackendMethods for SpirvCodegenBackend {
) -> (ModuleCodegen<Self::Module>, u64) {
let _timer = tcx
.prof
.generic_activity_with_arg("codegen_module", cgu_name.to_string());
.extra_verbose_generic_activity("codegen_module", cgu_name.to_string());
// TODO: Do dep_graph stuff
let cgu = tcx.codegen_unit(cgu_name);

View File

@ -119,6 +119,7 @@ fn link_exe(
do_link(sess, &objects, &rlibs, out_filename);
if env::var("SPIRV_OPT").is_ok() {
let _timer = sess.timer("link_spirv_opt");
do_spirv_opt(out_filename);
}
}
@ -280,6 +281,7 @@ pub fn read_metadata(rlib: &Path) -> MetadataRef {
/// This is the actual guts of linking: the rest of the link-related functions are just digging through rustc's
/// shenanigans to collect all the object files we need to link.
fn do_link(sess: &Session, objects: &[PathBuf], rlibs: &[PathBuf], out_filename: &Path) {
let load_modules_timer = sess.timer("link_load_modules");
let mut modules = Vec::new();
// `objects` are the plain obj files we need to link - usually produced by the final crate.
for obj in objects {
@ -315,35 +317,39 @@ fn do_link(sess: &Session, objects: &[PathBuf], rlibs: &[PathBuf], out_filename:
.unwrap();
}
}
drop(load_modules_timer);
// Do the link...
let result =
match rspirv_linker::link(&mut module_refs, |name| sess.prof.generic_activity(name)) {
Ok(result) => result,
Err(err) => {
if let Ok(ref path) = env::var("DUMP_MODULE_ON_PANIC") {
let path = Path::new(path);
if path.is_file() {
std::fs::remove_file(path).unwrap();
}
std::fs::create_dir_all(path).unwrap();
for (num, module) in modules.iter().enumerate() {
File::create(path.join(format!("mod_{}.spv", num)))
.unwrap()
.write_all(crate::slice_u32_to_u8(&module.assemble()))
.unwrap();
}
let link_result = rspirv_linker::link(&mut module_refs, |name| sess.timer(name));
let save_modules_timer = sess.timer("link_save_modules");
let assembled = match link_result {
Ok(v) => v,
Err(err) => {
if let Ok(ref path) = env::var("DUMP_MODULE_ON_PANIC") {
let path = Path::new(path);
if path.is_file() {
std::fs::remove_file(path).unwrap();
}
std::fs::create_dir_all(path).unwrap();
for (num, module) in modules.iter().enumerate() {
File::create(path.join(format!("mod_{}.spv", num)))
.unwrap()
.write_all(crate::slice_u32_to_u8(&module.assemble()))
.unwrap();
}
panic!("Linker error: {}", err)
}
};
panic!("Linker error: {}", err)
}
};
// And finally write out the linked binary.
use rspirv::binary::Assemble;
File::create(out_filename)
.unwrap()
.write_all(crate::slice_u32_to_u8(&result.assemble()))
.write_all(crate::slice_u32_to_u8(&assembled.assemble()))
.unwrap();
drop(save_modules_timer);
fn load(bytes: &[u8]) -> rspirv::dr::Module {
let mut loader = rspirv::dr::Loader::new();