From 1900dd21b615b1f85bbbd0ad0dc6a07daacaf5f3 Mon Sep 17 00:00:00 2001 From: Aaron Councilman <aaronjc4@illinois.edu> Date: Mon, 3 Mar 2025 18:29:43 -0600 Subject: [PATCH 1/2] Support else-if --- juno_scheduler/src/lang.y | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/juno_scheduler/src/lang.y b/juno_scheduler/src/lang.y index 55c82b9d..7d04bee1 100644 --- a/juno_scheduler/src/lang.y +++ b/juno_scheduler/src/lang.y @@ -27,14 +27,23 @@ Stmt -> Stmt { Stmt::ExprStmt { span: $span, exp: $1 } } | 'fixpoint' FixpointLimit '{' Schedule '}' { Stmt::Fixpoint { span: $span, limit: $2, body: Box::new($4) } } - | 'if' Expr '{' Schedule '}' - { Stmt::IfThenElse { span: $span, cond: $2, thn: Box::new($4), els: None } } - | 'if' Expr '{' Schedule '}' 'else' '{' Schedule '}' - { Stmt::IfThenElse { span: $span, cond: $2, thn: Box::new($4), els: Some(Box::new($8)) } } + | 'if' Expr '{' Schedule '}' ElseStmt + { Stmt::IfThenElse { span: $span, cond: $2, thn: Box::new($4), els: $6 } } | MacroDecl { Stmt::MacroDecl { span: $span, def: $1 } } ; +ElseStmt -> Option<Box<OperationList>> + : { None } + | 'else' '{' Schedule '}' + { Some(Box::new($3)) } + | 'else' 'if' Expr '{' Schedule '}' ElseStmt + { Some(Box::new(OperationList::ConsStmt( + Stmt::IfThenElse { span: $span, cond: $3, thn: Box::new($5), els: $7 }, + Box::new(OperationList::NilStmt()), + ))) } + ; + FixpointLimit -> FixpointLimit : { FixpointLimit::NoLimit { span: $span } } | 'stop_after' 'INT' -- GitLab From 31ed14d3674f883f5b39fc7facb8b58fb2f931ee Mon Sep 17 00:00:00 2001 From: Aaron Councilman <aaronjc4@illinois.edu> Date: Mon, 3 Mar 2025 18:43:31 -0600 Subject: [PATCH 2/2] Add boolean operations --- juno_scheduler/src/compile.rs | 11 +++- juno_scheduler/src/ir.rs | 10 +++- juno_scheduler/src/lang.l | 4 ++ juno_scheduler/src/lang.y | 27 +++++++-- juno_scheduler/src/pm.rs | 104 +++++++++++++++++++++++++--------- 5 files changed, 119 insertions(+), 37 deletions(-) diff --git a/juno_scheduler/src/compile.rs b/juno_scheduler/src/compile.rs index 81fc82cd..f1df7714 100644 --- a/juno_scheduler/src/compile.rs +++ b/juno_scheduler/src/compile.rs @@ -551,7 +551,14 @@ fn compile_expr( } Ok(ExprResult::Expr(ir::ScheduleExp::Record { fields: result })) } - parser::Expr::SetOp { + parser::Expr::UnaryOp { span: _, op, exp } => { + let exp = compile_exp_as_expr(*exp, lexer, macrostab, macros)?; + Ok(ExprResult::Expr(ir::ScheduleExp::UnaryOp { + op, + exp: Box::new(exp), + })) + } + parser::Expr::BinaryOp { span: _, op, lhs, @@ -559,7 +566,7 @@ fn compile_expr( } => { let lhs = compile_exp_as_expr(*lhs, lexer, macrostab, macros)?; let rhs = compile_exp_as_expr(*rhs, lexer, macrostab, macros)?; - Ok(ExprResult::Expr(ir::ScheduleExp::SetOp { + Ok(ExprResult::Expr(ir::ScheduleExp::BinaryOp { op, lhs: Box::new(lhs), rhs: Box::new(rhs), diff --git a/juno_scheduler/src/ir.rs b/juno_scheduler/src/ir.rs index 287cd21a..aa5926cb 100644 --- a/juno_scheduler/src/ir.rs +++ b/juno_scheduler/src/ir.rs @@ -18,7 +18,7 @@ pub enum Pass { ForkDimMerge, ForkExtend, ForkFissionBufferize, - ForkFission, + ForkFission, ForkFusion, ForkGuardElim, ForkInterchange, @@ -134,8 +134,12 @@ pub enum ScheduleExp { body: Vec<ScheduleStmt>, res: Box<ScheduleExp>, }, - SetOp { - op: parser::SetOp, + UnaryOp { + op: parser::UnaryOp, + exp: Box<ScheduleExp>, + }, + BinaryOp { + op: parser::BinaryOp, lhs: Box<ScheduleExp>, rhs: Box<ScheduleExp>, }, diff --git a/juno_scheduler/src/lang.l b/juno_scheduler/src/lang.l index 1f4f8723..726264a3 100644 --- a/juno_scheduler/src/lang.l +++ b/juno_scheduler/src/lang.l @@ -46,6 +46,10 @@ false "false" \| "|" & "&" +! "!" +\|\| "||" +&& "&&" + panic[\t \n\r]+after "panic_after" print[\t \n\r]+iter "print_iter" stop[\t \n\r]+after "stop_after" diff --git a/juno_scheduler/src/lang.y b/juno_scheduler/src/lang.y index 7d04bee1..4500f42f 100644 --- a/juno_scheduler/src/lang.y +++ b/juno_scheduler/src/lang.y @@ -6,6 +6,9 @@ %left '\\' %left '|' %left '&' +%left '||' +%left '&&' +%right '!' %left '.' '@' %% @@ -84,11 +87,17 @@ Expr -> Expr | '<' Fields '>' { Expr::Record { span: $span, fields: rev($2) } } | Expr '\\' Expr - { Expr::SetOp { span: $span, op: SetOp::Difference, lhs: Box::new($1), rhs: Box::new($3) } } + { Expr::BinaryOp { span: $span, op: BinaryOp::Difference, lhs: Box::new($1), rhs: Box::new($3) } } | Expr '|' Expr - { Expr::SetOp { span: $span, op: SetOp::Union, lhs: Box::new($1), rhs: Box::new($3) } } + { Expr::BinaryOp { span: $span, op: BinaryOp::Union, lhs: Box::new($1), rhs: Box::new($3) } } | Expr '&' Expr - { Expr::SetOp { span: $span, op: SetOp::Intersection, lhs: Box::new($1), rhs: Box::new($3) } } + { Expr::BinaryOp { span: $span, op: BinaryOp::Intersection, lhs: Box::new($1), rhs: Box::new($3) } } + | '!' Expr + { Expr::UnaryOp { span: $span, op: UnaryOp::Not, exp: Box::new($2) } } + | Expr '||' Expr + { Expr::BinaryOp { span: $span, op: BinaryOp::Or, lhs: Box::new($1), rhs: Box::new($3) } } + | Expr '&&' Expr + { Expr::BinaryOp { span: $span, op: BinaryOp::And, lhs: Box::new($1), rhs: Box::new($3) } } ; Args -> Vec<Expr> @@ -188,10 +197,17 @@ pub enum FixpointLimit { } #[derive(Copy, Clone, Debug)] -pub enum SetOp { +pub enum UnaryOp { + Not, +} + +#[derive(Copy, Clone, Debug)] +pub enum BinaryOp { Difference, Union, Intersection, + Or, + And, } pub enum Expr { @@ -204,7 +220,8 @@ pub enum Expr { Field { span: Span, lhs: Box<Expr>, field: Span }, BlockExpr { span: Span, body: Box<OperationList> }, Record { span: Span, fields: Vec<(Span, Expr)> }, - SetOp { span: Span, op: SetOp, lhs: Box<Expr>, rhs: Box<Expr> }, + UnaryOp { span: Span, op: UnaryOp, exp: Box<Expr> }, + BinaryOp { span: Span, op: BinaryOp, lhs: Box<Expr>, rhs: Box<Expr> }, Tuple { span: Span, exps: Vec<Expr> }, TupleField { span: Span, lhs: Box<Expr>, field: Span }, } diff --git a/juno_scheduler/src/pm.rs b/juno_scheduler/src/pm.rs index 97bec544..ce558d55 100644 --- a/juno_scheduler/src/pm.rs +++ b/juno_scheduler/src/pm.rs @@ -281,6 +281,13 @@ impl ModuleSelection { } } +#[derive(Debug, Clone)] +pub enum SetOp { + Difference, + Union, + Intersection, +} + #[derive(Debug, Clone)] pub enum Value { Label { @@ -303,7 +310,7 @@ pub enum Value { selection: Vec<Value>, }, SetOp { - op: parser::SetOp, + op: SetOp, lhs: Box<Value>, rhs: Box<Value>, }, @@ -364,9 +371,9 @@ impl Value { let lhs = lhs.as_selection(pm, funcs)?; let rhs = rhs.as_selection(pm, funcs)?; let res = match op { - parser::SetOp::Union => lhs.union(rhs), - parser::SetOp::Intersection => lhs.intersection(rhs), - parser::SetOp::Difference => lhs.difference(rhs), + SetOp::Union => lhs.union(rhs), + SetOp::Intersection => lhs.intersection(rhs), + SetOp::Difference => lhs.difference(rhs), }; selection.add(res); } @@ -1301,17 +1308,62 @@ fn interp_expr( ScheduleExp::Integer { val } => Ok((Value::Integer { val: *val }, false)), ScheduleExp::Boolean { val } => Ok((Value::Boolean { val: *val }, false)), ScheduleExp::String { val } => Ok((Value::String { val: val.clone() }, false)), - ScheduleExp::SetOp { op, lhs, rhs } => { + ScheduleExp::UnaryOp { op, exp } => { + let (exp, modified) = interp_expr(pm, exp, stringtab, env, functions)?; + match op { + parser::UnaryOp::Not => { + let Value::Boolean { val } = exp else { + return Err(SchedulerError::SemanticError( + "Not can only be applied to boolean values".to_string(), + )); + }; + Ok((Value::Boolean { val: !val }, modified)) + } + } + } + ScheduleExp::BinaryOp { op, lhs, rhs } => { let (lhs, lhs_mod) = interp_expr(pm, lhs, stringtab, env, functions)?; let (rhs, rhs_mod) = interp_expr(pm, rhs, stringtab, env, functions)?; - Ok(( - Value::SetOp { - op: *op, - lhs: Box::new(lhs), - rhs: Box::new(rhs), - }, - lhs_mod || rhs_mod, - )) + match op { + parser::BinaryOp::Difference + | parser::BinaryOp::Union + | parser::BinaryOp::Intersection => Ok(( + Value::SetOp { + op: match op { + parser::BinaryOp::Difference => SetOp::Difference, + parser::BinaryOp::Union => SetOp::Union, + parser::BinaryOp::Intersection => SetOp::Intersection, + _ => panic!(), + }, + lhs: Box::new(lhs), + rhs: Box::new(rhs), + }, + lhs_mod || rhs_mod, + )), + parser::BinaryOp::Or | parser::BinaryOp::And => { + let (Value::Boolean { val: lhs }, Value::Boolean { val: rhs }) = (lhs, rhs) + else { + return Err(SchedulerError::SemanticError(format!( + "{} can only be applied to boolean values", + match op { + parser::BinaryOp::Or => "or", + parser::BinaryOp::And => "and", + _ => panic!(), + }, + ))); + }; + Ok(( + Value::Boolean { + val: match op { + parser::BinaryOp::Or => lhs || rhs, + parser::BinaryOp::And => lhs && rhs, + _ => panic!(), + }, + }, + lhs_mod || rhs_mod, + )) + } + } } ScheduleExp::Field { collect, field } => { let (lhs, changed) = interp_expr(pm, collect, stringtab, env, functions)?; @@ -2780,7 +2832,7 @@ fn run_pass( } pm.delete_gravestones(); pm.clear_analyses(); - }, + } Pass::ForkFission => { assert!(args.len() == 1); @@ -2794,7 +2846,6 @@ fn run_pass( }); }; - pm.make_fork_join_maps(); pm.make_loops(); pm.make_reduce_cycles(); @@ -2817,18 +2868,18 @@ fn run_pass( let fork_label = fork_labels[0].label; - for ((((func, fork_join_map), loop_tree), reduce_cycles), nodes_in_fork_joins, - ) in build_selection(pm, selection, false) - .into_iter() - .zip(fork_join_maps.iter()) - .zip(loops.iter()) - .zip(reduce_cycles.iter()) - .zip(nodes_in_fork_joins.iter()) + for ((((func, fork_join_map), loop_tree), reduce_cycles), nodes_in_fork_joins) in + build_selection(pm, selection, false) + .into_iter() + .zip(fork_join_maps.iter()) + .zip(loops.iter()) + .zip(reduce_cycles.iter()) + .zip(nodes_in_fork_joins.iter()) { let Some(mut func) = func else { continue; }; - + let new_forks = fork_fission( &mut func, nodes_in_fork_joins, @@ -2837,12 +2888,12 @@ fn run_pass( fork_join_map, fork_label, ); - + let created_fork_joins = &mut created_fork_joins[func.func_id().idx()]; for f in new_forks { created_fork_joins.push(f); - }; + } changed |= func.modified(); } @@ -2899,8 +2950,7 @@ fn run_pass( result = Value::Record { fields: new_fork_joins, }; - - }, + } Pass::ForkFissionBufferize => { assert!(args.len() == 1 || args.len() == 2); let Some(Value::Label { -- GitLab