From b99128b7c54bf91e4dc71eff34967a7e0abb2595 Mon Sep 17 00:00:00 2001 From: Xavier Routh <xrouth2@illinois.edu> Date: Fri, 14 Feb 2025 10:37:54 -0600 Subject: [PATCH] forkify more aggressively --- hercules_opt/src/forkify.rs | 50 +++++++------------------------------ 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/hercules_opt/src/forkify.rs b/hercules_opt/src/forkify.rs index 774220df..0bfe152a 100644 --- a/hercules_opt/src/forkify.rs +++ b/hercules_opt/src/forkify.rs @@ -183,8 +183,7 @@ pub fn forkify_loop( let reductionable_phis: Vec<_> = analyze_phis(&editor, &l, &candidate_phis, &loop_nodes) .into_iter() .collect(); - // TODO: Handle multiple loop body lasts. - // If there are multiple candidates for loop body last, return false. + if editor .get_uses(loop_if) .filter(|id| l.control[id.idx()]) @@ -417,9 +416,9 @@ nest! { continue_latch: NodeID, is_associative: bool, }, - LoopDependant(NodeID), - ControlDependant(NodeID), // This phi is redcutionable, but its cycle might depend on internal control within the loop. - UsedByDependant(NodeID), + OutsideUse(NodeID), + NonCyclic(NodeID), + } } @@ -427,9 +426,8 @@ impl LoopPHI { pub fn get_phi(&self) -> NodeID { match self { LoopPHI::Reductionable { phi, .. } => *phi, - LoopPHI::LoopDependant(node_id) => *node_id, - LoopPHI::UsedByDependant(node_id) => *node_id, - LoopPHI::ControlDependant(node_id) => *node_id, + LoopPHI::OutsideUse(node_id) => *node_id, + LoopPHI::NonCyclic(node_id) => *node_id, } } } @@ -500,42 +498,12 @@ pub fn analyze_phis<'a>( let uses = walk_all_uses_stop_on(loop_continue_latch, editor, stop_on.clone()); let users = walk_all_users_stop_on(*phi, editor, stop_on.clone()); - let other_stop_on: HashSet<NodeID> = editor - .node_ids() - .filter(|node| { - let data = &editor.func().nodes[node.idx()]; - - // Phi, Reduce - if data.is_phi() { - return true; - } - - if data.is_reduce() { - return true; - } - - // External Control - if data.is_control() { - return true; - } - - return false; - }) - .collect(); - - let mut uses_for_dependance = - walk_all_users_stop_on(loop_continue_latch, editor, other_stop_on); - let set1: HashSet<_> = HashSet::from_iter(uses); let set2: HashSet<_> = HashSet::from_iter(users); let intersection: HashSet<_> = set1.intersection(&set2).cloned().collect(); - // If this phi uses any other phis the node is loop dependant, - // we use `phis` because this phi can actually contain the loop iv and its fine. - if uses_for_dependance.any(|node| phis.contains(&node) && node != *phi) { - LoopPHI::LoopDependant(*phi) - } else if intersection.clone().iter().next().is_some() { + if intersection.clone().iter().next().is_some() { // PHIs on the frontier of the uses by the candidate phi, i.e in uses_for_dependance need // to have headers that postdominate the loop continue latch. The value of the PHI used needs to be defined // by the time the reduce is triggered (at the end of the loop's internal control). @@ -555,7 +523,7 @@ pub fn analyze_phis<'a>( // 3) Split the cycle into two phis, add them or multiply them together at the end. // 4) Split the cycle into two reduces, add them or multiply them together at the end. // Somewhere else should handle this. - return LoopPHI::LoopDependant(*phi); + return LoopPHI::OutsideUse(*phi); } // FIXME: Do we want to calculate associativity here, there might be a case where this information is used in forkify @@ -571,7 +539,7 @@ pub fn analyze_phis<'a>( } } else { // No cycles exist, this isn't a reduction. - LoopPHI::LoopDependant(*phi) + LoopPHI::NonCyclic(*phi) } }) } -- GitLab