diff --git a/juno_samples/fork_join_tests/src/cpu.sch b/juno_samples/fork_join_tests/src/cpu.sch index abc2fde0fc3888d033dd2d2dc082aa8a9680f76a..7c416e904ad5d43a5297496b6de40037f5b9b553 100644 --- a/juno_samples/fork_join_tests/src/cpu.sch +++ b/juno_samples/fork_join_tests/src/cpu.sch @@ -14,6 +14,8 @@ cpu(auto.test5); cpu(auto.test7); cpu(auto.test8); +let test1_cpu = auto.test1; +rename["test1_cpu"](test1_cpu); ip-sroa(*); sroa(*); @@ -39,7 +41,10 @@ dce(*); fixpoint panic after 20 { infer-schedules(*); } -fork-split(auto.test1); + +let out = fork-split(test1_cpu); +let first_fork = out.test1_cpu.fj1; + fixpoint panic after 20 { unroll(auto.test1); } diff --git a/juno_scheduler/src/compile.rs b/juno_scheduler/src/compile.rs index e0e08e95899b73d50385b7ab47e73ccdf3480de0..0652f8f260929d3fd27147806520f02af28a0bd6 100644 --- a/juno_scheduler/src/compile.rs +++ b/juno_scheduler/src/compile.rs @@ -134,6 +134,7 @@ impl FromStr for Appliable { "phi-elim" => Ok(Appliable::Pass(ir::Pass::PhiElim)), "predication" => Ok(Appliable::Pass(ir::Pass::Predication)), "reduce-slf" => Ok(Appliable::Pass(ir::Pass::ReduceSLF)), + "rename" => Ok(Appliable::Pass(ir::Pass::Rename)), "reuse-products" => Ok(Appliable::Pass(ir::Pass::ReuseProducts)), "simplify-cfg" => Ok(Appliable::Pass(ir::Pass::SimplifyCFG)), "slf" | "store-load-forward" => Ok(Appliable::Pass(ir::Pass::SLF)), @@ -433,6 +434,11 @@ fn compile_expr( parser::Expr::Boolean { span: _, val } => { Ok(ExprResult::Expr(ir::ScheduleExp::Boolean { val })) } + parser::Expr::String { span } => { + let string = lexer.span_str(span); + let val = string[1..string.len() - 1].to_string(); + Ok(ExprResult::Expr(ir::ScheduleExp::String { val })) + } parser::Expr::Field { span: _, lhs, diff --git a/juno_scheduler/src/ir.rs b/juno_scheduler/src/ir.rs index 480fee643a7dbe4eafe4cfd317062fb74370edd7..e92f1d374705a72f090208a3073155507df5915c 100644 --- a/juno_scheduler/src/ir.rs +++ b/juno_scheduler/src/ir.rs @@ -28,6 +28,7 @@ pub enum Pass { PhiElim, Predication, ReduceSLF, + Rename, ReuseProducts, SLF, SROA, @@ -43,6 +44,7 @@ impl Pass { pub fn is_valid_num_args(&self, num: usize) -> bool { match self { Pass::ArrayToProduct => num == 0 || num == 1, + Pass::Rename => num == 1, Pass::Xdot => num == 0 || num == 1, Pass::ForkChunk => num == 4, Pass::ForkFissionBufferize => num == 2, @@ -54,6 +56,7 @@ impl Pass { pub fn valid_arg_nums(&self) -> &'static str { match self { Pass::ArrayToProduct => "0 or 1", + Pass::Rename => "1", Pass::Xdot => "0 or 1", Pass::ForkChunk => "4", Pass::ForkFissionBufferize => "2", @@ -80,6 +83,9 @@ pub enum ScheduleExp { Boolean { val: bool, }, + String { + val: String, + }, Field { collect: Box<ScheduleExp>, field: String, diff --git a/juno_scheduler/src/lang.l b/juno_scheduler/src/lang.l index 9d4c34bf8f7e50aaef048c7eba1a22c6f5872a96..afe596b2f3a90fcfb9e8fd1d8c6f5224afc7131f 100644 --- a/juno_scheduler/src/lang.l +++ b/juno_scheduler/src/lang.l @@ -46,5 +46,6 @@ stop[\t \n\r]+after "stop_after" [a-zA-Z][a-zA-Z0-9_\-]*! "MACRO" [a-zA-Z][a-zA-Z0-9_\-]* "ID" [0-9]+ "INT" +\"[a-zA-Z0-9_\-\s\.]*\" "STRING" . "UNMATCHED" diff --git a/juno_scheduler/src/lang.y b/juno_scheduler/src/lang.y index 9cb728428e08b0f77b77be526e2f3e0aa9c86a37..584bf2a4ef1a476669f10de115a5dda38213a695 100644 --- a/juno_scheduler/src/lang.y +++ b/juno_scheduler/src/lang.y @@ -1,6 +1,6 @@ %start Schedule -%avoid_insert "ID" "INT" +%avoid_insert "ID" "INT" "STRING" %expect-unused Unmatched 'UNMATCHED' %% @@ -47,6 +47,8 @@ Expr -> Expr { Expr::Boolean { span: $span, val: true } } | 'false' { Expr::Boolean { span: $span, val: false } } + | 'STRING' + { Expr::String { span: $span } } | Expr '.' 'ID' { Expr::Field { span: $span, lhs: Box::new($1), field: span_of_tok($3) } } | Expr '@' 'ID' @@ -155,6 +157,7 @@ pub enum Expr { Variable { span: Span }, Integer { span: Span }, Boolean { span: Span, val: bool }, + String { span: Span }, Field { span: Span, lhs: Box<Expr>, field: Span }, BlockExpr { span: Span, body: Box<OperationList> }, Record { span: Span, fields: Vec<(Span, Expr)> }, diff --git a/juno_scheduler/src/lib.rs b/juno_scheduler/src/lib.rs index d4ab432aa9bbd75f67e8e3d07d74a43f03f0967f..03ad0111069673bec3f5e081e6d6e1e15eb5d749 100644 --- a/juno_scheduler/src/lib.rs +++ b/juno_scheduler/src/lib.rs @@ -1,6 +1,6 @@ #![feature(exact_size_is_empty)] +#![feature(let_chains)] -use std::collections::{HashMap, HashSet}; use std::fs::File; use std::io::Read; diff --git a/juno_scheduler/src/pm.rs b/juno_scheduler/src/pm.rs index 0e052026cb82c75277de17d663f89444f938abe7..9c51276b82aa52fde5aa8dd13295b69aea7fb064 100644 --- a/juno_scheduler/src/pm.rs +++ b/juno_scheduler/src/pm.rs @@ -29,6 +29,7 @@ pub enum Value { Selection { selection: Vec<Value> }, Integer { val: usize }, Boolean { val: bool }, + String { val: String }, } #[derive(Debug, Copy, Clone)] @@ -70,6 +71,9 @@ impl Value { Value::Boolean { .. } => Err(SchedulerError::SemanticError( "Expected labels, found boolean".to_string(), )), + Value::String { .. } => Err(SchedulerError::SemanticError( + "Expected labels, found string".to_string(), + )), } } @@ -99,6 +103,9 @@ impl Value { Value::Boolean { .. } => Err(SchedulerError::SemanticError( "Expected functions, found boolean".to_string(), )), + Value::String { .. } => Err(SchedulerError::SemanticError( + "Expected functions, found string".to_string(), + )), } } @@ -130,6 +137,9 @@ impl Value { Value::Boolean { .. } => Err(SchedulerError::SemanticError( "Expected code locations, found boolean".to_string(), )), + Value::String { .. } => Err(SchedulerError::SemanticError( + "Expected code locations, found string".to_string(), + )), } } } @@ -998,6 +1008,7 @@ 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::Field { collect, field } => { let (lhs, changed) = interp_expr(pm, collect, stringtab, env, functions)?; match lhs { @@ -1005,7 +1016,8 @@ fn interp_expr( | Value::Selection { .. } | Value::Everything { .. } | Value::Integer { .. } - | Value::Boolean { .. } => Err(SchedulerError::UndefinedField(field.clone())), + | Value::Boolean { .. } + | Value::String { .. } => Err(SchedulerError::UndefinedField(field.clone())), Value::JunoFunction { func } => { match pm.labels.borrow().iter().position(|s| s == field) { None => Err(SchedulerError::UndefinedLabel(field.clone())), @@ -1260,6 +1272,7 @@ fn update_value( Value::Everything {} => Some(Value::Everything {}), Value::Integer { val } => Some(Value::Integer { val }), Value::Boolean { val } => Some(Value::Boolean { val }), + Value::String { val } => Some(Value::String { val }), } } @@ -2191,6 +2204,36 @@ fn run_pass( changed |= func.modified(); } } + Pass::Rename => { + assert!(args.len() == 1); + let new_name = match args[0] { + Value::String { ref val } => val.clone(), + _ => { + return Err(SchedulerError::PassError { + pass: "rename".to_string(), + error: "expected string argument".to_string(), + }); + } + }; + if pm.functions.iter().any(|f| f.name == new_name) { + return Err(SchedulerError::PassError { + pass: "rename".to_string(), + error: format!("function with name {} already exists", new_name), + }); + } + + if let Some(funcs) = selection_of_functions(pm, selection) + && funcs.len() == 1 + { + let func = funcs[0]; + pm.functions[func.idx()].name = new_name; + } else { + return Err(SchedulerError::PassError { + pass: "rename".to_string(), + error: "must be applied to the entirety of a single function".to_string(), + }); + }; + } Pass::ReuseProducts => { assert!(args.is_empty()); pm.make_reverse_postorders(); @@ -2334,7 +2377,13 @@ fn run_pass( let Some(mut func) = func else { continue; }; - chunk_all_forks_unguarded(&mut func, fork_join_map, *dim_idx, *tile_size, *tile_order); + chunk_all_forks_unguarded( + &mut func, + fork_join_map, + *dim_idx, + *tile_size, + *tile_order, + ); changed |= func.modified(); } pm.delete_gravestones();