diff --git a/juno_samples/schedule_test/src/sched.sch b/juno_samples/schedule_test/src/sched.sch index 155240248986ea07e32b21b54c209b9782367b33..960dca22481e06f7aaf3875477bc6ed5595159e7 100644 --- a/juno_samples/schedule_test/src/sched.sch +++ b/juno_samples/schedule_test/src/sched.sch @@ -40,5 +40,8 @@ fixpoint panic after 2 { phi-elim(*); } +host(*); +cpu(first, second); + codegen-prep!(*); //xdot[true](*); diff --git a/juno_scheduler/src/pm.rs b/juno_scheduler/src/pm.rs index beaf73e3da5691239a9c36dde45a2d4f593e253f..452c1995ee313e77d787ba7b769788c6e67b1271 100644 --- a/juno_scheduler/src/pm.rs +++ b/juno_scheduler/src/pm.rs @@ -668,9 +668,12 @@ fn schedule_interpret( } }, ScheduleStmt::AddDevice { device, on } => match on { - Selector::Everything() => Err(SchedulerError::SemanticError( - "Cannot apply device to everything".to_string(), - )), + Selector::Everything() => { + for func in pm.functions.iter_mut() { + func.device = Some(device.clone()); + } + Ok(false) + } Selector::Selection(selection) => { let mut changed = false; for func in selection { @@ -899,6 +902,39 @@ fn construct_selection(pm: &PassManager, selection: Vec<CodeLocation>) -> Vec<Fu selected } +// Given a selection, constructs the set of functions which are selected (and each must be selected +// fully) +fn selection_of_functions( + pm: &PassManager, + selection: Option<Vec<CodeLocation>>, +) -> Option<Vec<FunctionID>> { + if let Some(selection) = selection { + let selection = construct_selection(pm, selection); + + let mut result = vec![]; + + for (idx, selected) in selection.into_iter().enumerate() { + match selected { + FunctionSelection::Nothing() => {} + FunctionSelection::Everything() => result.push(FunctionID::new(idx)), + FunctionSelection::Labels(_) => { + return None; + } + } + } + + Some(result) + } else { + Some( + pm.functions + .iter() + .enumerate() + .map(|(i, _)| FunctionID::new(i)) + .collect(), + ) + } +} + // Given a selection, constructs the set of the nodes selected for a single function, returning the // function's id fn selection_as_set( @@ -1006,35 +1042,29 @@ fn run_pass( match pass { Pass::AutoOutline => { - if let Some(_) = selection { + let Some(funcs) = selection_of_functions(pm, selection) else { return Err(SchedulerError::PassError { pass: "autoOutline".to_string(), - error: "must be applied to the entire module".to_string(), + error: "must be applied to whole functions".to_string(), }); - } + }; pm.make_def_uses(); let def_uses = pm.def_uses.take().unwrap(); - let mut editors: Vec<_> = pm - .functions - .iter_mut() - .zip(def_uses.iter()) - .enumerate() - .map(|(idx, (func, def_use))| { - FunctionEditor::new( - func, - FunctionID::new(idx), - &pm.constants, - &pm.dynamic_constants, - &pm.types, - &pm.labels, - def_use, - ) - }) - .collect(); - for editor in editors.iter_mut() { - collapse_returns(editor); - ensure_between_control_flow(editor); + + for func in funcs.iter() { + let mut editor = FunctionEditor::new( + &mut pm.functions[func.idx()], + *func, + &pm.constants, + &pm.dynamic_constants, + &pm.types, + &pm.labels, + &def_uses[func.idx()], + ); + collapse_returns(&mut editor); + ensure_between_control_flow(&mut editor); + changed |= editor.modified(); } pm.clear_analyses(); @@ -1049,51 +1079,49 @@ fn run_pass( let doms = pm.doms.take().unwrap(); let old_num_funcs = pm.functions.len(); - let mut editors: Vec<_> = pm - .functions - .iter_mut() - .zip(def_uses.iter()) - .enumerate() - .map(|(idx, (func, def_use))| { - FunctionEditor::new( - func, - FunctionID::new(idx), - &pm.constants, - &pm.dynamic_constants, - &pm.types, - &pm.labels, - def_use, - ) - }) - .collect(); - let mut new_funcs = vec![]; - for (idx, editor) in editors.iter_mut().enumerate() { + // Track the names of the old functions and the new function IDs for returning + let mut new_func_ids = HashMap::new(); + + for func in funcs { + let mut editor = FunctionEditor::new( + &mut pm.functions[func.idx()], + func, + &pm.constants, + &pm.dynamic_constants, + &pm.types, + &pm.labels, + &def_uses[func.idx()], + ); + let new_func_id = FunctionID::new(old_num_funcs + new_funcs.len()); + let new_func = dumb_outline( - editor, - &typing[idx], - &control_subgraphs[idx], - &doms[idx], + &mut editor, + &typing[func.idx()], + &control_subgraphs[func.idx()], + &doms[func.idx()], new_func_id, ); + changed |= editor.modified(); + if let Some(new_func) = new_func { - let Value::Record { ref mut fields } = result else { - panic!("AutoOutline produces a record"); - }; - fields.insert( - new_func.name.clone(), + new_func_ids.insert( + editor.func().name.clone(), Value::HerculesFunction { func: new_func_id }, ); new_funcs.push(new_func); } - } - for func in pm.functions.iter_mut() { - func.delete_gravestones(); + pm.functions[func.idx()].delete_gravestones(); } + pm.functions.extend(new_funcs); pm.clear_analyses(); + + result = Value::Record { + fields: new_func_ids, + }; } Pass::CCP => { assert!(args.is_empty());