1use rustc_hash::FxHashSet;
2
3use crate::passes::{MIRPass, MIRPassData, Pass};
4use crate::project::{OptimizationLevel, ProjectSettings};
5
6use super::get_instr_calls;
7
8pub struct DCEPass;
9
10impl Pass for DCEPass {
11 fn get_name(&self) -> &'static str {
12 "dead_code_elimination"
13 }
14
15 fn should_run(&self, proj: &ProjectSettings) -> bool {
16 proj.op_level >= OptimizationLevel::Basic
17 }
18}
19
20impl MIRPass for DCEPass {
21 fn run_pass(&mut self, data: &mut MIRPassData) -> anyhow::Result<()> {
22 let mut used = FxHashSet::default();
24 for func in data.mir.functions.values() {
25 let block = &func.block;
26
27 for instr in &block.contents {
28 let calls = get_instr_calls(&instr.kind);
29 for call in calls {
30 used.insert(call.function.clone());
31 }
32 }
33 }
34
35 let mut unused = FxHashSet::default();
37 for (func_id, func) in &data.mir.functions {
38 if func.interface.annotations.preserve {
39 continue;
40 }
41 if !used.contains(func_id) {
42 unused.insert(func_id.clone());
43 }
44 }
45 for unused in unused {
46 data.mir.functions.remove(&unused);
47 }
48
49 Ok(())
50 }
51}