diff --git a/hercules_opt/src/lib.rs b/hercules_opt/src/lib.rs index b25449e7bd143e82c6d8b2fb39f2d8e238bd5cfa..e9550cd4e143ae161a3dffed071d9a152e727f17 100644 --- a/hercules_opt/src/lib.rs +++ b/hercules_opt/src/lib.rs @@ -20,6 +20,7 @@ pub mod loop_bound_canon; pub mod outline; pub mod phi_elim; pub mod pred; +pub mod reassociate; pub mod reuse_products; pub mod rewrite_math_expressions; pub mod schedule; @@ -49,6 +50,7 @@ pub use crate::loop_bound_canon::*; pub use crate::outline::*; pub use crate::phi_elim::*; pub use crate::pred::*; +pub use crate::reassociate::*; pub use crate::reuse_products::*; pub use crate::rewrite_math_expressions::*; pub use crate::schedule::*; diff --git a/hercules_opt/src/reassociate.rs b/hercules_opt/src/reassociate.rs new file mode 100644 index 0000000000000000000000000000000000000000..f876c55a854d9d6ab1b183145e3f997f47be56d3 --- /dev/null +++ b/hercules_opt/src/reassociate.rs @@ -0,0 +1,37 @@ +use hercules_ir::def_use::*; +use hercules_ir::ir::*; + +use crate::*; + +/* + * Top level function to run dead code elimination. + */ +pub fn reassociate(editor: &mut FunctionEditor) { + panic!("Reassociate was called"); + // Create worklist (starts as all nodes). + let mut worklist: Vec<NodeID> = editor.node_ids().collect(); + + while let Some(work) = worklist.pop() { + // If a node on the worklist is a start node, it is either *the* start + // node (which we shouldn't delete), or is a gravestone for an already + // deleted node earlier in the worklist. If a node is a return node, it + // shouldn't be removed. + if editor.func().nodes[work.idx()].is_start() || editor.func().nodes[work.idx()].is_return() + { + continue; + } + + // If a node on the worklist has 0 users, delete it. Add its uses onto + // the worklist. + if editor.get_users(work).len() == 0 { + let uses = get_uses(&editor.func().nodes[work.idx()]); + let success = editor.edit(|edit| edit.delete_node(work)); + if success { + // If the edit was performed, then its uses may now be dead. + for u in uses.as_ref() { + worklist.push(*u); + } + } + } + } +} diff --git a/juno_samples/grape_reduction/src/grape.sch b/juno_samples/grape_reduction/src/grape.sch index 2f4aba679fbbc3471e69bf5918fa3748cefb93b6..3be751171c40343a0992bb4b7d01bf700261123d 100644 --- a/juno_samples/grape_reduction/src/grape.sch +++ b/juno_samples/grape_reduction/src/grape.sch @@ -10,10 +10,10 @@ delete-uncalled(*); forkify(*); fork-guard-elim(*); dce(*); -xdot[true](*); +// xdot[true](*); // fork-tile[8, 0, false, true](*); let a = fork-split(*); -xdot[true](*); +// xdot[true](*); fixpoint stop after 10 { @@ -28,12 +28,15 @@ fixpoint stop after 10 { dce(entry@inner); lift-dc-math(entry@inner); } -xdot[true](*); +// xdot[true](*); a2p(*); sroa(*); xdot[true](*); +// reassociate go brr +reassociate(*); + gvn(*); phi-elim(*); ccp(*); diff --git a/juno_scheduler/src/compile.rs b/juno_scheduler/src/compile.rs index 361f08a448780bd1c376fe3128ff704488734afc..2c941b795b02a8c2454432fc1e9725f9df81680a 100644 --- a/juno_scheduler/src/compile.rs +++ b/juno_scheduler/src/compile.rs @@ -152,6 +152,7 @@ impl FromStr for Appliable { "outline" => Ok(Appliable::Pass(ir::Pass::Outline)), "phi-elim" => Ok(Appliable::Pass(ir::Pass::PhiElim)), "predication" => Ok(Appliable::Pass(ir::Pass::Predication)), + "reassociate" => Ok(Appliable::Pass(ir::Pass::Reassociate)), "reduce-slf" => Ok(Appliable::Pass(ir::Pass::ReduceSLF)), "rename" => Ok(Appliable::Pass(ir::Pass::Rename)), "reuse-products" => Ok(Appliable::Pass(ir::Pass::ReuseProducts)), diff --git a/juno_scheduler/src/ir.rs b/juno_scheduler/src/ir.rs index aa5926cb93548684664a41bf48d1783597abe888..bee0cf0621939c96edfb4c109703f13d0c7c4527 100644 --- a/juno_scheduler/src/ir.rs +++ b/juno_scheduler/src/ir.rs @@ -37,6 +37,7 @@ pub enum Pass { PhiElim, Predication, Print, + Reassociate, ReduceSLF, Rename, ReuseProducts, diff --git a/juno_scheduler/src/pm.rs b/juno_scheduler/src/pm.rs index 204130573c1a91cb80b71dbf85e0cb596a785ac5..3627c0a02012f492ce7697e9360a03c116c7cb7f 100644 --- a/juno_scheduler/src/pm.rs +++ b/juno_scheduler/src/pm.rs @@ -2572,6 +2572,18 @@ fn run_pass( pm.delete_gravestones(); pm.clear_analyses(); } + Pass::Reassociate => { + assert!(args.is_empty()); + for func in build_selection(pm, selection, false) { + let Some(mut func) = func else { + continue; + }; + reassociate(&mut func); + changed |= func.modified(); + } + pm.delete_gravestones(); + pm.clear_analyses(); + } Pass::ReduceSLF => { assert!(args.is_empty()); pm.make_fork_join_maps();