duskphantom_middle/transform/
dead_code_elim.rs1use anyhow::Result;
18
19use crate::analysis::effect_analysis::EffectAnalysis;
20use crate::ir::instruction::InstType;
21use crate::ir::{InstPtr, Operand};
22use crate::Program;
23
24use super::Transform;
25
26#[allow(unused)]
27pub fn optimize_program(program: &mut Program) -> Result<bool> {
28 let effect_analysis = EffectAnalysis::new(program);
29 DeadCodeElim::new(program, &effect_analysis).run_and_log()
30}
31
32pub struct DeadCodeElim<'a> {
33 program: &'a mut Program,
34 effect_analysis: &'a EffectAnalysis,
35}
36
37impl<'a> Transform for DeadCodeElim<'a> {
38 fn get_program_mut(&mut self) -> &mut Program {
39 self.program
40 }
41
42 fn name() -> String {
43 "dead_code_elim".to_string()
44 }
45
46 fn run(&mut self) -> Result<bool> {
47 let mut changed = false;
48 for func in self.program.module.functions.clone().iter() {
49 if func.is_lib() {
50 continue;
51 }
52 for bb in func.po_iter() {
53 for inst in bb.iter() {
54 changed |= self.dead_code_elim_inst(inst)?;
55 }
56 }
57 }
58
59 let len0 = self.program.module.global_variables.len();
61 self.program
62 .module
63 .global_variables
64 .retain(|var| !var.as_ref().get_user().is_empty());
65 let len1 = self.program.module.global_variables.len();
66 changed |= len0 != len1;
67 Ok(changed)
68 }
69}
70
71impl<'a> DeadCodeElim<'a> {
72 pub fn new(program: &'a mut Program, effect_analysis: &'a EffectAnalysis) -> Self {
73 Self {
74 program,
75 effect_analysis,
76 }
77 }
78
79 fn dead_code_elim_inst(&mut self, mut inst: InstPtr) -> Result<bool> {
80 if !inst.get_user().is_empty() || self.has_side_effect(inst) {
81 return Ok(false);
82 }
83 let operands: Vec<_> = inst.get_operand().into();
84 inst.remove_self();
85 for op in operands {
86 if let Operand::Instruction(inst) = op {
87 self.dead_code_elim_inst(inst)?;
88 }
89 }
90 Ok(true)
91 }
92
93 fn has_side_effect(&mut self, inst: InstPtr) -> bool {
94 matches!(
95 inst.get_type(),
96 InstType::Store | InstType::Ret | InstType::Br
97 ) || self.effect_analysis.has_effect(inst)
98 }
99}