mirror of
https://github.com/AleoHQ/leo.git
synced 2024-09-21 12:07:56 +03:00
Use NodeBuilder in DCE
This commit is contained in:
parent
26fffd6746
commit
637e091abb
@ -15,14 +15,7 @@
|
|||||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Expression,
|
|
||||||
ExpressionReconstructor,
|
|
||||||
Identifier,
|
|
||||||
NodeID,
|
NodeID,
|
||||||
NodeReconstructor,
|
|
||||||
ProgramReconstructor,
|
|
||||||
Statement,
|
|
||||||
StatementReconstructor,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
@ -45,24 +38,6 @@ impl NodeBuilder {
|
|||||||
pub fn next_id(&self) -> NodeID {
|
pub fn next_id(&self) -> NodeID {
|
||||||
self.inner.borrow_mut().next_id()
|
self.inner.borrow_mut().next_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the identifier, modified to have a unique `NodeID`.
|
|
||||||
pub fn unique_identifier(&self, identifier: Identifier) -> Identifier {
|
|
||||||
match self.inner.borrow_mut().reconstruct_identifier(identifier).0 {
|
|
||||||
Expression::Identifier(identifier) => identifier,
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the expression, modified to have unique `NodeID`s.
|
|
||||||
pub fn unique_expression(&self, expression: Expression) -> Expression {
|
|
||||||
self.inner.borrow_mut().reconstruct_expression(expression).0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the statement, modified to have unique `NodeID`s.
|
|
||||||
pub fn unique_statement(&self, statement: Statement) -> Statement {
|
|
||||||
self.inner.borrow_mut().reconstruct_statement(statement).0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for NodeBuilder {
|
impl Default for NodeBuilder {
|
||||||
@ -92,17 +67,3 @@ impl NodeBuilderInner {
|
|||||||
next
|
next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeReconstructor for NodeBuilderInner {
|
|
||||||
fn reconstruct_node_id(&mut self, _: NodeID) -> NodeID {
|
|
||||||
self.next_id()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExpressionReconstructor for NodeBuilderInner {
|
|
||||||
type AdditionalOutput = ();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StatementReconstructor for NodeBuilderInner {}
|
|
||||||
|
|
||||||
impl ProgramReconstructor for NodeBuilderInner {}
|
|
||||||
|
@ -14,21 +14,23 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use leo_ast::NodeBuilder;
|
||||||
use leo_span::Symbol;
|
use leo_span::Symbol;
|
||||||
|
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
|
|
||||||
#[derive(Default)]
|
pub struct DeadCodeEliminator<'a> {
|
||||||
pub struct DeadCodeEliminator {
|
/// A counter to generate unique node IDs.
|
||||||
|
pub(crate) node_builder: &'a NodeBuilder,
|
||||||
/// The set of used variables in the current function body.
|
/// The set of used variables in the current function body.
|
||||||
pub(crate) used_variables: IndexSet<Symbol>,
|
pub(crate) used_variables: IndexSet<Symbol>,
|
||||||
/// Whether or not the variables are necessary.
|
/// Whether or not the variables are necessary.
|
||||||
pub(crate) is_necessary: bool,
|
pub(crate) is_necessary: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeadCodeEliminator {
|
impl<'a> DeadCodeEliminator<'a> {
|
||||||
/// Initializes a new `DeadCodeEliminator`.
|
/// Initializes a new `DeadCodeEliminator`.
|
||||||
pub fn new() -> Self {
|
pub fn new(node_builder: &'a NodeBuilder) -> Self {
|
||||||
Self { used_variables: Default::default(), is_necessary: false }
|
Self { node_builder, used_variables: Default::default(), is_necessary: false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ use leo_ast::{
|
|||||||
ExpressionReconstructor,
|
ExpressionReconstructor,
|
||||||
Identifier,
|
Identifier,
|
||||||
MemberAccess,
|
MemberAccess,
|
||||||
NodeID,
|
|
||||||
StructExpression,
|
StructExpression,
|
||||||
StructVariableInitializer,
|
StructVariableInitializer,
|
||||||
TupleAccess,
|
TupleAccess,
|
||||||
@ -31,7 +30,7 @@ use leo_ast::{
|
|||||||
};
|
};
|
||||||
use leo_span::sym;
|
use leo_span::sym;
|
||||||
|
|
||||||
impl ExpressionReconstructor for DeadCodeEliminator {
|
impl ExpressionReconstructor for DeadCodeEliminator<'_> {
|
||||||
type AdditionalOutput = ();
|
type AdditionalOutput = ();
|
||||||
|
|
||||||
/// Reconstructs the components of an access expression.
|
/// Reconstructs the components of an access expression.
|
||||||
@ -58,7 +57,7 @@ impl ExpressionReconstructor for DeadCodeEliminator {
|
|||||||
.map(|arg| self.reconstruct_expression(arg).0)
|
.map(|arg| self.reconstruct_expression(arg).0)
|
||||||
.collect(),
|
.collect(),
|
||||||
span: function.span,
|
span: function.span,
|
||||||
id: NodeID::default(),
|
id: function.id,
|
||||||
});
|
});
|
||||||
// Unset `self.is_necessary`.
|
// Unset `self.is_necessary`.
|
||||||
self.is_necessary = false;
|
self.is_necessary = false;
|
||||||
@ -68,13 +67,13 @@ impl ExpressionReconstructor for DeadCodeEliminator {
|
|||||||
inner: Box::new(self.reconstruct_expression(*member.inner).0),
|
inner: Box::new(self.reconstruct_expression(*member.inner).0),
|
||||||
name: member.name,
|
name: member.name,
|
||||||
span: member.span,
|
span: member.span,
|
||||||
id: NodeID::default(),
|
id: member.id
|
||||||
}),
|
}),
|
||||||
AccessExpression::Tuple(tuple) => AccessExpression::Tuple(TupleAccess {
|
AccessExpression::Tuple(tuple) => AccessExpression::Tuple(TupleAccess {
|
||||||
tuple: Box::new(self.reconstruct_expression(*tuple.tuple).0),
|
tuple: Box::new(self.reconstruct_expression(*tuple.tuple).0),
|
||||||
index: tuple.index,
|
index: tuple.index,
|
||||||
span: tuple.span,
|
span: tuple.span,
|
||||||
id: NodeID::default(),
|
id: tuple.id,
|
||||||
}),
|
}),
|
||||||
AccessExpression::AssociatedConstant(constant) => AccessExpression::AssociatedConstant(constant),
|
AccessExpression::AssociatedConstant(constant) => AccessExpression::AssociatedConstant(constant),
|
||||||
}),
|
}),
|
||||||
@ -99,11 +98,11 @@ impl ExpressionReconstructor for DeadCodeEliminator {
|
|||||||
None => unreachable!("Static single assignment ensures that the expression always exists."),
|
None => unreachable!("Static single assignment ensures that the expression always exists."),
|
||||||
},
|
},
|
||||||
span: member.span,
|
span: member.span,
|
||||||
id: NodeID::default(),
|
id: member.id,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
span: input.span,
|
span: input.span,
|
||||||
id: NodeID::default(),
|
id: input.id,
|
||||||
}),
|
}),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)
|
)
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
use crate::DeadCodeEliminator;
|
use crate::DeadCodeEliminator;
|
||||||
|
|
||||||
use leo_ast::{Finalize, Function, NodeID, ProgramReconstructor, StatementReconstructor};
|
use leo_ast::{Finalize, Function, ProgramReconstructor, StatementReconstructor};
|
||||||
|
|
||||||
impl ProgramReconstructor for DeadCodeEliminator {
|
impl ProgramReconstructor for DeadCodeEliminator<'_> {
|
||||||
fn reconstruct_function(&mut self, input: Function) -> Function {
|
fn reconstruct_function(&mut self, input: Function) -> Function {
|
||||||
// Reset the state of the dead code eliminator.
|
// Reset the state of the dead code eliminator.
|
||||||
self.used_variables.clear();
|
self.used_variables.clear();
|
||||||
@ -43,7 +43,7 @@ impl ProgramReconstructor for DeadCodeEliminator {
|
|||||||
output_type: finalize.output_type,
|
output_type: finalize.output_type,
|
||||||
block,
|
block,
|
||||||
span: finalize.span,
|
span: finalize.span,
|
||||||
id: NodeID::default(),
|
id: finalize.id,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ impl ProgramReconstructor for DeadCodeEliminator {
|
|||||||
block,
|
block,
|
||||||
finalize,
|
finalize,
|
||||||
span: input.span,
|
span: input.span,
|
||||||
id: NodeID::default(),
|
id: input.id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,13 +29,12 @@ use leo_ast::{
|
|||||||
ExpressionReconstructor,
|
ExpressionReconstructor,
|
||||||
ExpressionStatement,
|
ExpressionStatement,
|
||||||
IterationStatement,
|
IterationStatement,
|
||||||
NodeID,
|
|
||||||
ReturnStatement,
|
ReturnStatement,
|
||||||
Statement,
|
Statement,
|
||||||
StatementReconstructor,
|
StatementReconstructor,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl StatementReconstructor for DeadCodeEliminator {
|
impl StatementReconstructor for DeadCodeEliminator<'_> {
|
||||||
fn reconstruct_assert(&mut self, input: AssertStatement) -> (Statement, Self::AdditionalOutput) {
|
fn reconstruct_assert(&mut self, input: AssertStatement) -> (Statement, Self::AdditionalOutput) {
|
||||||
// Set the `is_necessary` flag.
|
// Set the `is_necessary` flag.
|
||||||
self.is_necessary = true;
|
self.is_necessary = true;
|
||||||
@ -52,7 +51,7 @@ impl StatementReconstructor for DeadCodeEliminator {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
span: input.span,
|
span: input.span,
|
||||||
id: NodeID::default(),
|
id: input.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Unset the `is_necessary` flag.
|
// Unset the `is_necessary` flag.
|
||||||
@ -92,7 +91,7 @@ impl StatementReconstructor for DeadCodeEliminator {
|
|||||||
place: input.place,
|
place: input.place,
|
||||||
value: self.reconstruct_expression(input.value).0,
|
value: self.reconstruct_expression(input.value).0,
|
||||||
span: input.span,
|
span: input.span,
|
||||||
id: NodeID::default(),
|
id: input.id,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Unset the `is_necessary` flag.
|
// Unset the `is_necessary` flag.
|
||||||
@ -101,7 +100,7 @@ impl StatementReconstructor for DeadCodeEliminator {
|
|||||||
(statement, Default::default())
|
(statement, Default::default())
|
||||||
}
|
}
|
||||||
// Otherwise, we can eliminate it.
|
// Otherwise, we can eliminate it.
|
||||||
false => (Statement::dummy(Default::default()), Default::default()),
|
false => (Statement::dummy(Default::default(), self.node_builder.next_id()), Default::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +113,7 @@ impl StatementReconstructor for DeadCodeEliminator {
|
|||||||
// Reverse the direction of `statements`.
|
// Reverse the direction of `statements`.
|
||||||
statements.reverse();
|
statements.reverse();
|
||||||
|
|
||||||
(Block { statements, span: block.span, id: NodeID::default() }, Default::default())
|
(Block { statements, span: block.span, id: block.id }, Default::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flattening removes conditional statements from the program.
|
/// Flattening removes conditional statements from the program.
|
||||||
@ -145,7 +144,7 @@ impl StatementReconstructor for DeadCodeEliminator {
|
|||||||
let statement = Statement::Expression(ExpressionStatement {
|
let statement = Statement::Expression(ExpressionStatement {
|
||||||
expression: self.reconstruct_call(expression).0,
|
expression: self.reconstruct_call(expression).0,
|
||||||
span: input.span,
|
span: input.span,
|
||||||
id: NodeID::default(),
|
id: input.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Unset the `is_necessary` flag.
|
// Unset the `is_necessary` flag.
|
||||||
@ -161,14 +160,14 @@ impl StatementReconstructor for DeadCodeEliminator {
|
|||||||
.reconstruct_access(AccessExpression::AssociatedFunction(associated_function))
|
.reconstruct_access(AccessExpression::AssociatedFunction(associated_function))
|
||||||
.0,
|
.0,
|
||||||
span: input.span,
|
span: input.span,
|
||||||
id: NodeID::default(),
|
id: input.id,
|
||||||
}),
|
}),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// Any other expression is dead code, since they do not have side effects.
|
// Any other expression is dead code, since they do not have side effects.
|
||||||
// Note: array access expressions will have side effects and need to be handled here.
|
// Note: array access expressions will have side effects and need to be handled here.
|
||||||
_ => (Statement::dummy(Default::default()), Default::default()),
|
_ => (Statement::dummy(Default::default(), self.node_builder.next_id()), Default::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +187,7 @@ impl StatementReconstructor for DeadCodeEliminator {
|
|||||||
arguments.into_iter().map(|argument| self.reconstruct_expression(argument).0).collect()
|
arguments.into_iter().map(|argument| self.reconstruct_expression(argument).0).collect()
|
||||||
}),
|
}),
|
||||||
span: input.span,
|
span: input.span,
|
||||||
id: NodeID::default(),
|
id: input.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Unset the `is_necessary` flag.
|
// Unset the `is_necessary` flag.
|
||||||
|
@ -60,15 +60,15 @@ pub use dead_code_eliminator::*;
|
|||||||
|
|
||||||
use crate::Pass;
|
use crate::Pass;
|
||||||
|
|
||||||
use leo_ast::{Ast, ProgramReconstructor};
|
use leo_ast::{Ast, NodeBuilder, ProgramReconstructor};
|
||||||
use leo_errors::Result;
|
use leo_errors::Result;
|
||||||
|
|
||||||
impl Pass for DeadCodeEliminator {
|
impl<'a> Pass for DeadCodeEliminator<'a> {
|
||||||
type Input = Ast;
|
type Input = (Ast, &'a NodeBuilder);
|
||||||
type Output = Result<Ast>;
|
type Output = Result<Ast>;
|
||||||
|
|
||||||
fn do_pass(ast: Self::Input) -> Self::Output {
|
fn do_pass((ast, node_builder): Self::Input) -> Self::Output {
|
||||||
let mut reconstructor = DeadCodeEliminator::new();
|
let mut reconstructor = DeadCodeEliminator::new(node_builder);
|
||||||
let program = reconstructor.reconstruct_program(ast.into_repr());
|
let program = reconstructor.reconstruct_program(ast.into_repr());
|
||||||
|
|
||||||
Ok(Ast::new(program))
|
Ok(Ast::new(program))
|
||||||
|
Loading…
Reference in New Issue
Block a user