mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-11 04:49:15 +03:00
Remove greedy inlining
This commit is contained in:
parent
79bf13ff8e
commit
d2381767e9
@ -19,7 +19,7 @@ use leo_errors::{
|
||||
emitter::{Buffer, Emitter, Handler},
|
||||
LeoError, LeoWarning,
|
||||
};
|
||||
use leo_passes::{CodeGenerator, Pass};
|
||||
use leo_passes::{Assigner, CodeGenerator, Pass};
|
||||
use leo_span::source_map::FileName;
|
||||
use leo_test_framework::Test;
|
||||
|
||||
@ -101,6 +101,7 @@ pub fn new_compiler(handler: &Handler, main_file_path: PathBuf) -> Compiler<'_>
|
||||
unrolled_ast: true,
|
||||
ssa_ast: true,
|
||||
flattened_ast: true,
|
||||
inlined_ast: true,
|
||||
}),
|
||||
)
|
||||
}
|
||||
@ -184,11 +185,18 @@ pub fn temp_dir() -> PathBuf {
|
||||
|
||||
pub fn compile_and_process<'a>(parsed: &'a mut Compiler<'a>) -> Result<String, LeoError> {
|
||||
let st = parsed.symbol_table_pass()?;
|
||||
let (st, struct_graph, call_graph) = parsed.type_checker_pass(st)?;
|
||||
let st = parsed.loop_unrolling_pass(st)?;
|
||||
let assigner = parsed.static_single_assignment_pass(&st)?;
|
||||
|
||||
parsed.flattening_pass(&st, assigner)?;
|
||||
let (st, struct_graph, call_graph) = parsed.type_checker_pass(st)?;
|
||||
|
||||
let st = parsed.loop_unrolling_pass(st)?;
|
||||
|
||||
let assigner = Assigner::default();
|
||||
|
||||
let assigner = parsed.static_single_assignment_pass(&st, assigner)?;
|
||||
|
||||
let assigner = parsed.flattening_pass(&st, assigner)?;
|
||||
|
||||
let _ = parsed.function_inlining_pass(&st, &call_graph, assigner)?;
|
||||
|
||||
// Compile Leo program to bytecode.
|
||||
let bytecode = CodeGenerator::do_pass((&parsed.ast, &st, &struct_graph, &call_graph))?;
|
||||
|
@ -214,7 +214,7 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_unconnected_graph() {
|
||||
let mut graph = DiGraph::<u32>::new(IndexSet::from([1, 2, 3, 4, 5]));
|
||||
let graph = DiGraph::<u32>::new(IndexSet::from([1, 2, 3, 4, 5]));
|
||||
|
||||
check_post_order(&graph, &[1, 2, 3, 4, 5]);
|
||||
}
|
||||
|
@ -16,10 +16,7 @@
|
||||
|
||||
use crate::{FunctionInliner, Replacer};
|
||||
|
||||
use leo_ast::{
|
||||
CallExpression, Expression, ExpressionReconstructor, Identifier, ReturnStatement, Statement, StatementConsumer,
|
||||
StatementReconstructor, UnitExpression,
|
||||
};
|
||||
use leo_ast::{CallExpression, Expression, ExpressionReconstructor, Identifier, ReturnStatement, Statement, StatementConsumer, StatementReconstructor, UnitExpression, Variant};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use itertools::Itertools;
|
||||
@ -35,41 +32,47 @@ impl ExpressionReconstructor for FunctionInliner<'_> {
|
||||
};
|
||||
|
||||
// Lookup the reconstructed callee function.
|
||||
// Since this pass processes functions in post-order, the callee function is guaranteed to exist in `self.reconstructed_function`
|
||||
// Since this pass processes functions in post-order, the callee function is guaranteed to exist in `self.reconstructed_functions`
|
||||
let callee = self.reconstructed_functions.get(&function_name).unwrap();
|
||||
|
||||
// Construct a mapping from input variables of the callee function to arguments passed to the callee.
|
||||
let parameter_to_argument = callee
|
||||
.input
|
||||
.iter()
|
||||
.map(|input| input.identifier())
|
||||
.zip_eq(input.arguments.into_iter())
|
||||
.collect::<IndexMap<_, _>>();
|
||||
// Inline the callee function, if required, otherwise, return the call expression.
|
||||
match callee.variant {
|
||||
Variant::Transition | Variant::Standard => (Expression::Call(input), Default::default()),
|
||||
Variant::Inline => {
|
||||
// Construct a mapping from input variables of the callee function to arguments passed to the callee.
|
||||
let parameter_to_argument = callee
|
||||
.input
|
||||
.iter()
|
||||
.map(|input| input.identifier())
|
||||
.zip_eq(input.arguments.into_iter())
|
||||
.collect::<IndexMap<_, _>>();
|
||||
|
||||
// Duplicate the body of the callee and replace each input variable with the appropriate parameter.
|
||||
let replace = |identifier: Identifier| match parameter_to_argument.get(&identifier) {
|
||||
Some(expression) => expression.clone(),
|
||||
None => Expression::Identifier(identifier),
|
||||
};
|
||||
let replaced_block = Replacer::new(replace).reconstruct_block(callee.block.clone()).0;
|
||||
// Duplicate the body of the callee and replace each input variable with the appropriate parameter.
|
||||
let replace = |identifier: Identifier| match parameter_to_argument.get(&identifier) {
|
||||
Some(expression) => expression.clone(),
|
||||
None => Expression::Identifier(identifier),
|
||||
};
|
||||
let replaced_block = Replacer::new(replace).reconstruct_block(callee.block.clone()).0;
|
||||
|
||||
// Ensure that each assignment in the `replaced_block` is a unique assignment statement.
|
||||
let mut inlined_statements = self.static_single_assigner.consume_block(replaced_block);
|
||||
// Ensure that each assignment in the `replaced_block` is a unique assignment statement.
|
||||
let mut inlined_statements = self.static_single_assigner.consume_block(replaced_block);
|
||||
|
||||
// If the inlined block returns a value, then use the value in place of the call expression, otherwise, use the unit expression.
|
||||
let result = match inlined_statements.last() {
|
||||
Some(Statement::Return(_)) => {
|
||||
// Note that this unwrap is safe since we know that the last statement is a return statement.
|
||||
match inlined_statements.pop().unwrap() {
|
||||
Statement::Return(ReturnStatement { expression, .. }) => expression,
|
||||
_ => unreachable!("This branch checks that the last statement is a return statement."),
|
||||
}
|
||||
// If the inlined block returns a value, then use the value in place of the call expression, otherwise, use the unit expression.
|
||||
let result = match inlined_statements.last() {
|
||||
Some(Statement::Return(_)) => {
|
||||
// Note that this unwrap is safe since we know that the last statement is a return statement.
|
||||
match inlined_statements.pop().unwrap() {
|
||||
Statement::Return(ReturnStatement { expression, .. }) => expression,
|
||||
_ => unreachable!("This branch checks that the last statement is a return statement."),
|
||||
}
|
||||
}
|
||||
_ => Expression::Unit(UnitExpression {
|
||||
span: Default::default(),
|
||||
}),
|
||||
};
|
||||
|
||||
(result, inlined_statements)
|
||||
}
|
||||
_ => Expression::Unit(UnitExpression {
|
||||
span: Default::default(),
|
||||
}),
|
||||
};
|
||||
|
||||
(result, inlined_statements)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user