diff --git a/hercules_opt/src/unforkify.rs b/hercules_opt/src/unforkify.rs index 7d158d1a0378cac55c24533a96ccd36610c8bfeb..a08d1667929e8e08fa476ae0c2f706d77f808ec7 100644 --- a/hercules_opt/src/unforkify.rs +++ b/hercules_opt/src/unforkify.rs @@ -118,7 +118,7 @@ pub fn unforkify( // control insides of the fork-join should become the successor of the true // projection node, and what was the use of the join should become a use of // the new region. - for l in loop_tree.bottom_up_loops().into_iter().rev() { + for l in loop_tree.bottom_up_loops().iter().rev() { if !editor.node(l.0).is_fork() { continue; } @@ -133,7 +133,8 @@ pub fn unforkify( if factors.len() > 1 { // For now, don't convert multi-dimensional fork-joins. Rely on pass // that splits fork-joins. - break; // Because we have to unforkify top down, we can't unforkify forks that are contained + // We can't unforkify, because then the outer forks reduce will depend on non-fork control. + break; } let join_control = nodes[join.idx()].try_join().unwrap(); let tids: Vec<_> = editor @@ -293,5 +294,6 @@ pub fn unforkify( Ok(edit) }); + break; } } diff --git a/juno_scheduler/src/pm.rs b/juno_scheduler/src/pm.rs index d2772c71971638205613dc4c92eb7ac835b02983..378d873069466541daa4767db7678467791459a9 100644 --- a/juno_scheduler/src/pm.rs +++ b/juno_scheduler/src/pm.rs @@ -1815,25 +1815,35 @@ fn run_pass( } Pass::Unforkify => { assert!(args.is_empty()); - pm.make_fork_join_maps(); - pm.make_loops(); + loop { + let mut inner_changed = false; - let fork_join_maps = pm.fork_join_maps.take().unwrap(); - let loops = pm.loops.take().unwrap(); + pm.make_fork_join_maps(); + pm.make_loops(); - for ((func, fork_join_map), loop_tree) in build_selection(pm, selection) - .into_iter() - .zip(fork_join_maps.iter()) - .zip(loops.iter()) - { - let Some(mut func) = func else { - continue; - }; - unforkify(&mut func, fork_join_map, loop_tree); - changed |= func.modified(); + let fork_join_maps = pm.fork_join_maps.take().unwrap(); + let loops = pm.loops.take().unwrap(); + + for ((func, fork_join_map), loop_tree) in build_selection(pm, selection.clone()) + .into_iter() + .zip(fork_join_maps.iter()) + .zip(loops.iter()) + { + let Some(mut func) = func else { + continue; + }; + unforkify(&mut func, fork_join_map, loop_tree); + changed |= func.modified(); + inner_changed |= func.modified(); + } + pm.delete_gravestones(); + pm.clear_analyses(); + + if !inner_changed { + break; + } + break; } - pm.delete_gravestones(); - pm.clear_analyses(); } Pass::ForkCoalesce => { assert!(args.is_empty());