1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use std::cell::Cell;
use leo_asg::*;
pub struct DeadCodeElimination {}
impl<'a> ReconstructingReducerExpression<'a> for DeadCodeElimination {}
impl<'a> ReconstructingReducerProgram<'a> for DeadCodeElimination {}
impl<'a> ReconstructingReducerStatement<'a> for DeadCodeElimination {
fn reduce_statement_alloc(
&mut self,
context: AsgContext<'a>,
_input: &'a Statement<'a>,
value: Statement<'a>,
) -> &'a Statement<'a> {
match &value {
Statement::Conditional(conditional) => match conditional.condition.get().const_value() {
Some(ConstValue::Boolean(true)) => conditional.result.get(),
Some(ConstValue::Boolean(false)) => {
if let Some(if_false) = conditional.next.get() {
if_false
} else {
context.alloc_statement(Statement::Empty(conditional.span.clone()))
}
}
_ => context.alloc_statement(value),
},
_ => context.alloc_statement(value),
}
}
fn reduce_block(&mut self, input: BlockStatement<'a>, mut statements: Vec<&'a Statement<'a>>) -> Statement<'a> {
let first_return = statements.iter().position(|x| matches!(x, Statement::Return(_)));
if let Some(first_return) = first_return {
statements.truncate(first_return + 1);
}
Statement::Block(BlockStatement {
parent: input.parent,
span: input.span,
statements: statements.into_iter().map(Cell::new).collect(),
scope: input.scope,
})
}
}
impl<'a> AsgPass<'a> for DeadCodeElimination {
fn do_pass(asg: Program<'a>) -> Result<Program<'a>, FormattedError> {
let pass = DeadCodeElimination {};
let mut director = ReconstructingDirector::new(asg.context, pass);
Ok(director.reduce_program(asg))
}
}