nak: Add a dead-code pass

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand 2023-01-30 20:53:16 -06:00 committed by Marge Bot
parent 9769f19c7e
commit 4e95cb908f
3 changed files with 98 additions and 0 deletions

View file

@ -6,6 +6,7 @@
mod nak_from_nir;
mod nak_ir;
mod nak_opt_copy_prop;
mod nak_opt_dce;
mod nir;
use nak_bindings::*;
@ -40,5 +41,9 @@ pub extern "C" fn nak_compile_shader(
println!("NAK IR:\n{}", &s);
s.opt_dce();
println!("NAK IR:\n{}", &s);
std::ptr::null_mut()
}

View file

@ -595,6 +595,13 @@ impl Instr {
pub fn num_srcs(&self) -> usize {
self.srcs().len()
}
pub fn can_eliminate(&self) -> bool {
match self.op {
Opcode::FS_OUT | Opcode::EXIT | Opcode::AST(_) => false,
_ => true,
}
}
}
pub struct MetaInstr {

View file

@ -0,0 +1,86 @@
/*
* Copyright © 2022 Collabora, Ltd.
* SPDX-License-Identifier: MIT
*/
use crate::nak_ir::*;
use std::collections::HashSet;
struct DeadCodePass {
live_ssa: HashSet<SSAValue>,
}
impl DeadCodePass {
pub fn new() -> DeadCodePass {
DeadCodePass {
live_ssa: HashSet::new(),
}
}
fn mark_ssa_live(&mut self, ssa: &SSAValue) {
self.live_ssa.insert(*ssa);
}
fn mark_instr_live(&mut self, instr: &Instr) {
for src in instr.srcs() {
if let Src::SSA(ssa) = src {
self.mark_ssa_live(ssa);
}
}
}
fn is_dst_live(&self, dst: &Dst) -> bool {
match dst {
Ref::SSA(ssa) => self.live_ssa.get(ssa).is_some(),
Ref::Zero => false,
_ => panic!("Invalid SSA destination"),
}
}
fn is_instr_live(&self, instr: &Instr) -> bool {
if !instr.can_eliminate() {
return true;
}
for dst in instr.dsts() {
if self.is_dst_live(dst) {
return true;
}
}
false
}
pub fn run(&mut self, f: &mut Function) {
let mut has_any_dead = false;
for b in f.blocks.iter().rev() {
for instr in b.instrs.iter().rev() {
if self.is_instr_live(instr) {
self.mark_instr_live(instr);
} else {
has_any_dead = true;
}
}
}
if has_any_dead {
f.map_instrs(&|instr: Instr| -> Instr {
if self.is_instr_live(&instr) {
instr
} else {
Instr::new_noop()
}
})
}
}
}
impl Shader {
pub fn opt_dce(&mut self) {
for f in &mut self.functions {
DeadCodePass::new().run(f);
}
}
}