From a1baea161e0114374de969618cec803a56e42ea0 Mon Sep 17 00:00:00 2001 From: Russel Arbore <russel.jma@gmail.com> Date: Wed, 12 Feb 2025 17:08:36 -0600 Subject: [PATCH] Loop unroll skeleton --- hercules_opt/src/lib.rs | 2 ++ hercules_opt/src/unroll.rs | 18 ++++++++++++++++++ juno_scheduler/src/compile.rs | 1 + juno_scheduler/src/ir.rs | 1 + juno_scheduler/src/pm.rs | 18 ++++++++++++++++++ 5 files changed, 40 insertions(+) create mode 100644 hercules_opt/src/unroll.rs diff --git a/hercules_opt/src/lib.rs b/hercules_opt/src/lib.rs index 7187508a..a810dfbf 100644 --- a/hercules_opt/src/lib.rs +++ b/hercules_opt/src/lib.rs @@ -23,6 +23,7 @@ pub mod simplify_cfg; pub mod slf; pub mod sroa; pub mod unforkify; +pub mod unroll; pub mod utils; pub use crate::ccp::*; @@ -48,4 +49,5 @@ pub use crate::simplify_cfg::*; pub use crate::slf::*; pub use crate::sroa::*; pub use crate::unforkify::*; +pub use crate::unroll::*; pub use crate::utils::*; diff --git a/hercules_opt/src/unroll.rs b/hercules_opt/src/unroll.rs new file mode 100644 index 00000000..f3c795ca --- /dev/null +++ b/hercules_opt/src/unroll.rs @@ -0,0 +1,18 @@ +use bitvec::prelude::*; + +use hercules_ir::*; + +use crate::*; + +/* + * Run loop unrolling on all loops that are mutable in an editor. + */ +pub fn loop_unroll_all_loops(editor: &mut FunctionEditor, loops: &LoopTree) { + for (header, contents) in loops.bottom_up_loops() { + if editor.is_mutable(header) { + loop_unroll(editor, header, contents); + } + } +} + +pub fn loop_unroll(editor: &mut FunctionEditor, header: NodeID, contents: &BitVec<u8, Lsb0>) {} diff --git a/juno_scheduler/src/compile.rs b/juno_scheduler/src/compile.rs index 1aaa10cd..9d5a86cc 100644 --- a/juno_scheduler/src/compile.rs +++ b/juno_scheduler/src/compile.rs @@ -114,6 +114,7 @@ impl FromStr for Appliable { "fork-interchange" => Ok(Appliable::Pass(ir::Pass::ForkInterchange)), "fork-chunk" | "fork-tile" => Ok(Appliable::Pass(ir::Pass::ForkChunk)), "lift-dc-math" => Ok(Appliable::Pass(ir::Pass::LiftDCMath)), + "loop-unroll" | "unroll" => Ok(Appliable::Pass(ir::Pass::LoopUnroll)), "outline" => Ok(Appliable::Pass(ir::Pass::Outline)), "phi-elim" => Ok(Appliable::Pass(ir::Pass::PhiElim)), "predication" => Ok(Appliable::Pass(ir::Pass::Predication)), diff --git a/juno_scheduler/src/ir.rs b/juno_scheduler/src/ir.rs index 0ecac39a..1bb6cf13 100644 --- a/juno_scheduler/src/ir.rs +++ b/juno_scheduler/src/ir.rs @@ -23,6 +23,7 @@ pub enum Pass { Inline, InterproceduralSROA, LiftDCMath, + LoopUnroll, Outline, PhiElim, Predication, diff --git a/juno_scheduler/src/pm.rs b/juno_scheduler/src/pm.rs index 9c7391ac..5c6aec5e 100644 --- a/juno_scheduler/src/pm.rs +++ b/juno_scheduler/src/pm.rs @@ -1665,6 +1665,24 @@ fn run_pass( pm.delete_gravestones(); pm.clear_analyses(); } + Pass::LoopUnroll => { + assert_eq!(args.len(), 0); + + pm.make_loops(); + let loops = pm.loops.take().unwrap(); + for (func, loops) in build_selection(pm, selection, false) + .into_iter() + .zip(loops.iter()) + { + let Some(mut func) = func else { + continue; + }; + loop_unroll_all_loops(&mut func, loops); + changed |= func.modified(); + } + pm.delete_gravestones(); + pm.clear_analyses(); + } Pass::Forkify => { assert!(args.is_empty()); loop { -- GitLab