Use NodeBuilder in DCE

This commit is contained in:
Pranav Gaddamadugu 2023-08-16 13:33:43 -04:00
parent 26fffd6746
commit 637e091abb
6 changed files with 31 additions and 70 deletions

View File

@ -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 {}

View File

@ -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 }
} }
} }

View File

@ -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(),
) )

View File

@ -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,
} }
} }
} }

View File

@ -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.

View File

@ -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))