Minor improvements to the optimizer.
This commit is contained in:
parent
91317c0d3e
commit
9bd66c7db3
@ -3,6 +3,26 @@ use crate::parser::{Expr, Stmt};
|
||||
|
||||
fn optimize_stmt(stmt: Stmt, changed: &mut bool, preserve_result: bool) -> Stmt {
|
||||
match stmt {
|
||||
Stmt::IfElse(expr, stmt1, None) if stmt1.is_noop() => {
|
||||
*changed = true;
|
||||
|
||||
let pos = expr.position();
|
||||
let expr = optimize_expr(*expr, changed);
|
||||
|
||||
match expr {
|
||||
Expr::False(_) | Expr::True(_) => Stmt::Noop(stmt1.position()),
|
||||
expr => {
|
||||
let stmt = Stmt::Expr(Box::new(expr));
|
||||
|
||||
if preserve_result {
|
||||
Stmt::Block(vec![stmt, *stmt1], pos)
|
||||
} else {
|
||||
stmt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Stmt::IfElse(expr, stmt1, None) => match *expr {
|
||||
Expr::False(pos) => {
|
||||
*changed = true;
|
||||
@ -22,7 +42,10 @@ fn optimize_stmt(stmt: Stmt, changed: &mut bool, preserve_result: bool) -> Stmt
|
||||
expr => Stmt::IfElse(
|
||||
Box::new(optimize_expr(expr, changed)),
|
||||
Box::new(optimize_stmt(*stmt1, changed, true)),
|
||||
Some(Box::new(optimize_stmt(*stmt2, changed, true))),
|
||||
match optimize_stmt(*stmt2, changed, true) {
|
||||
stmt if stmt.is_noop() => None,
|
||||
stmt => Some(Box::new(stmt)),
|
||||
},
|
||||
),
|
||||
},
|
||||
|
||||
@ -274,10 +297,14 @@ pub(crate) fn optimize(statements: Vec<Stmt>) -> Vec<Stmt> {
|
||||
}
|
||||
}
|
||||
|
||||
// Eliminate No-op's but always keep the last statement
|
||||
// Eliminate code that is pure but always keep the last statement
|
||||
let last_stmt = result.pop();
|
||||
|
||||
result.retain(Stmt::is_op); // Remove all No-op's
|
||||
// Remove all pure statements at top level
|
||||
result.retain(|stmt| match stmt {
|
||||
Stmt::Expr(expr) if expr.is_pure() => false,
|
||||
_ => true,
|
||||
});
|
||||
|
||||
if let Some(stmt) = last_stmt {
|
||||
result.push(stmt); // Add back the last statement
|
||||
|
@ -186,6 +186,13 @@ pub enum Stmt {
|
||||
}
|
||||
|
||||
impl Stmt {
|
||||
pub fn is_noop(&self) -> bool {
|
||||
match self {
|
||||
Stmt::Noop(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_op(&self) -> bool {
|
||||
match self {
|
||||
Stmt::Noop(_) => false,
|
||||
@ -265,6 +272,7 @@ impl Expr {
|
||||
pub fn is_pure(&self) -> bool {
|
||||
match self {
|
||||
Expr::Array(expressions, _) => expressions.iter().all(Expr::is_pure),
|
||||
Expr::And(x, y) | Expr::Or(x, y) | Expr::Index(x, y, _) => x.is_pure() && y.is_pure(),
|
||||
expr => expr.is_constant() || expr.is_identifier(),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user