1 //! A Dead-Code Elimination (DCE) pass.
2 //!
3 //! Dead code here means instructions that have no side effects and have no
4 //! result values used by other instructions.
5 
6 use crate::cursor::{Cursor, FuncCursor};
7 use crate::dominator_tree::DominatorTree;
8 use crate::entity::EntityRef;
9 use crate::inst_predicates::{any_inst_results_used, has_side_effect};
10 use crate::ir::Function;
11 use crate::timing;
12 
13 /// Perform DCE on `func`.
do_dce(func: &mut Function, domtree: &mut DominatorTree)14 pub fn do_dce(func: &mut Function, domtree: &mut DominatorTree) {
15     let _tt = timing::dce();
16     debug_assert!(domtree.is_valid());
17 
18     let mut live = vec![false; func.dfg.num_values()];
19     for &block in domtree.cfg_postorder() {
20         let mut pos = FuncCursor::new(func).at_bottom(block);
21         while let Some(inst) = pos.prev_inst() {
22             {
23                 if has_side_effect(pos.func, inst)
24                     || any_inst_results_used(inst, &live, &pos.func.dfg)
25                 {
26                     for arg in pos.func.dfg.inst_args(inst) {
27                         let v = pos.func.dfg.resolve_aliases(*arg);
28                         live[v.index()] = true;
29                     }
30                     continue;
31                 }
32             }
33             pos.remove_inst();
34         }
35     }
36 }
37