mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-25 08:14:12 +00:00
Add DCE-φ pass
This commit is contained in:
parent
f0f0f318ec
commit
40359bdb56
@ -7,8 +7,8 @@
|
||||
//! *references* a rooted thing is also rooted, not the other way around - but that's the basic
|
||||
//! concept.
|
||||
|
||||
use rspirv::dr::{Instruction, Module};
|
||||
use rspirv::spirv::Word;
|
||||
use rspirv::dr::{Function, Instruction, Module};
|
||||
use rspirv::spirv::{Op, Word};
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub fn dce(module: &mut Module) {
|
||||
@ -85,3 +85,27 @@ fn kill_unrooted(module: &mut Module, rooted: &HashSet<Word>) {
|
||||
.functions
|
||||
.retain(|f| is_rooted(f.def.as_ref().unwrap(), rooted));
|
||||
}
|
||||
|
||||
pub fn dce_phi(func: &mut Function) {
|
||||
let mut used = HashSet::new();
|
||||
loop {
|
||||
let mut changed = false;
|
||||
for inst in func.all_inst_iter() {
|
||||
if inst.class.opcode != Op::Phi || used.contains(&inst.result_id.unwrap()) {
|
||||
for op in &inst.operands {
|
||||
if let Some(id) = op.id_ref_any() {
|
||||
changed |= used.insert(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !changed {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for block in &mut func.blocks {
|
||||
block
|
||||
.instructions
|
||||
.retain(|inst| inst.class.opcode != Op::Phi || used.contains(&inst.result_id.unwrap()))
|
||||
}
|
||||
}
|
||||
|
@ -237,6 +237,8 @@ pub fn link(sess: &Session, mut inputs: Vec<Module>, opts: &Options) -> Result<L
|
||||
&constants,
|
||||
func,
|
||||
);
|
||||
// mem2reg produces minimal SSA form, not pruned, so DCE the dead ones
|
||||
dce::dce_phi(func);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user