Refine optimizer.
This commit is contained in:
parent
feaad4e0da
commit
2d80ee2f18
@ -8,8 +8,8 @@ fn optimize_stmt(stmt: Stmt, changed: &mut bool) -> Stmt {
|
|||||||
Stmt::Noop(pos)
|
Stmt::Noop(pos)
|
||||||
}
|
}
|
||||||
Expr::True(_) => optimize_stmt(*stmt1, changed),
|
Expr::True(_) => optimize_stmt(*stmt1, changed),
|
||||||
_ => Stmt::IfElse(
|
expr => Stmt::IfElse(
|
||||||
Box::new(optimize_expr(*expr, changed)),
|
Box::new(optimize_expr(expr, changed)),
|
||||||
Box::new(optimize_stmt(*stmt1, changed)),
|
Box::new(optimize_stmt(*stmt1, changed)),
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
@ -18,8 +18,8 @@ fn optimize_stmt(stmt: Stmt, changed: &mut bool) -> Stmt {
|
|||||||
Stmt::IfElse(expr, stmt1, Some(stmt2)) => match *expr {
|
Stmt::IfElse(expr, stmt1, Some(stmt2)) => match *expr {
|
||||||
Expr::False(_) => optimize_stmt(*stmt2, changed),
|
Expr::False(_) => optimize_stmt(*stmt2, changed),
|
||||||
Expr::True(_) => optimize_stmt(*stmt1, changed),
|
Expr::True(_) => optimize_stmt(*stmt1, changed),
|
||||||
_ => Stmt::IfElse(
|
expr => Stmt::IfElse(
|
||||||
Box::new(optimize_expr(*expr, changed)),
|
Box::new(optimize_expr(expr, changed)),
|
||||||
Box::new(optimize_stmt(*stmt1, changed)),
|
Box::new(optimize_stmt(*stmt1, changed)),
|
||||||
Some(Box::new(optimize_stmt(*stmt2, changed))),
|
Some(Box::new(optimize_stmt(*stmt2, changed))),
|
||||||
),
|
),
|
||||||
@ -31,8 +31,8 @@ fn optimize_stmt(stmt: Stmt, changed: &mut bool) -> Stmt {
|
|||||||
Stmt::Noop(pos)
|
Stmt::Noop(pos)
|
||||||
}
|
}
|
||||||
Expr::True(_) => Stmt::Loop(Box::new(optimize_stmt(*stmt, changed))),
|
Expr::True(_) => Stmt::Loop(Box::new(optimize_stmt(*stmt, changed))),
|
||||||
_ => Stmt::While(
|
expr => Stmt::While(
|
||||||
Box::new(optimize_expr(*expr, changed)),
|
Box::new(optimize_expr(expr, changed)),
|
||||||
Box::new(optimize_stmt(*stmt, changed)),
|
Box::new(optimize_stmt(*stmt, changed)),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -57,6 +57,17 @@ fn optimize_stmt(stmt: Stmt, changed: &mut bool) -> Stmt {
|
|||||||
.filter(Stmt::is_op) // Remove no-op's
|
.filter(Stmt::is_op) // Remove no-op's
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
if let Some(last_stmt) = result.pop() {
|
||||||
|
// Remove all raw expression statements that evaluate to constants
|
||||||
|
// except for the very last statement
|
||||||
|
result.retain(|stmt| match stmt {
|
||||||
|
Stmt::Expr(expr) if expr.is_constant() => false,
|
||||||
|
_ => true,
|
||||||
|
});
|
||||||
|
|
||||||
|
result.push(last_stmt);
|
||||||
|
}
|
||||||
|
|
||||||
*changed = *changed || original_len != result.len();
|
*changed = *changed || original_len != result.len();
|
||||||
|
|
||||||
match result[..] {
|
match result[..] {
|
||||||
@ -65,14 +76,19 @@ fn optimize_stmt(stmt: Stmt, changed: &mut bool) -> Stmt {
|
|||||||
*changed = true;
|
*changed = true;
|
||||||
Stmt::Noop(pos)
|
Stmt::Noop(pos)
|
||||||
}
|
}
|
||||||
[Stmt::Let(_, _, _)] => {
|
[Stmt::Let(_, None, _)] => {
|
||||||
|
// Only one empty variable declaration - change to No-op
|
||||||
|
*changed = true;
|
||||||
|
Stmt::Noop(pos)
|
||||||
|
}
|
||||||
|
[Stmt::Let(_, Some(_), _)] => {
|
||||||
// Only one let statement, but cannot promote
|
// Only one let statement, but cannot promote
|
||||||
// (otherwise the variable gets declared in the scope above)
|
// (otherwise the variable gets declared in the scope above)
|
||||||
// and still need to run just in case there are side effects
|
// and still need to run just in case there are side effects
|
||||||
Stmt::Block(result, pos)
|
Stmt::Block(result, pos)
|
||||||
}
|
}
|
||||||
[_] => {
|
[_] => {
|
||||||
// No statements in block - change to No-op
|
// Only one statement - promote
|
||||||
*changed = true;
|
*changed = true;
|
||||||
result.remove(0)
|
result.remove(0)
|
||||||
}
|
}
|
||||||
@ -87,9 +103,9 @@ fn optimize_stmt(stmt: Stmt, changed: &mut bool) -> Stmt {
|
|||||||
is_return,
|
is_return,
|
||||||
pos,
|
pos,
|
||||||
),
|
),
|
||||||
Stmt::ReturnWithVal(None, _, _) => stmt,
|
stmt @ Stmt::ReturnWithVal(None, _, _) => stmt,
|
||||||
|
|
||||||
Stmt::Noop(_) | Stmt::Break(_) => stmt,
|
stmt @ Stmt::Noop(_) | stmt @ Stmt::Break(_) => stmt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,6 +198,21 @@ impl Expr {
|
|||||||
| Expr::Or(e, _) => e.position(),
|
| Expr::Or(e, _) => e.position(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_constant(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Expr::IntegerConstant(_, _)
|
||||||
|
| Expr::FloatConstant(_, _)
|
||||||
|
| Expr::Identifier(_, _)
|
||||||
|
| Expr::CharConstant(_, _)
|
||||||
|
| Expr::StringConstant(_, _)
|
||||||
|
| Expr::True(_)
|
||||||
|
| Expr::False(_)
|
||||||
|
| Expr::Unit(_) => true,
|
||||||
|
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
Loading…
Reference in New Issue
Block a user