diff --git a/hercules_opt/src/crc.rs b/hercules_opt/src/crc.rs new file mode 100644 index 0000000000000000000000000000000000000000..be80e61bea8d6522a40b35542bb6b3c39edeb4db --- /dev/null +++ b/hercules_opt/src/crc.rs @@ -0,0 +1,39 @@ +use hercules_ir::*; + +use crate::*; + +/* + * Top level function to collapse read chains in a function. + */ +pub fn crc(editor: &mut FunctionEditor) { + let mut changed = true; + while changed { + changed = false; + for id in editor.node_ids() { + if let Node::Read { + collect: lower_collect, + indices: ref lower_indices, + } = editor.func().nodes[id.idx()] + && let Node::Read { + collect: upper_collect, + indices: ref upper_indices, + } = editor.func().nodes[lower_collect.idx()] + { + let collapsed_read = Node::Read { + collect: upper_collect, + indices: upper_indices + .iter() + .chain(lower_indices.iter()) + .map(|idx| idx.clone()) + .collect(), + }; + let success = editor.edit(|mut edit| { + let new_id = edit.add_node(collapsed_read); + let edit = edit.replace_all_uses(id, new_id)?; + edit.delete_node(id) + }); + changed = changed || success; + } + } + } +} diff --git a/hercules_opt/src/lib.rs b/hercules_opt/src/lib.rs index 9935703e839b5a4dd705af03f40a456008fe0f12..e351deba58c9061fe19bba4932509177d83af626 100644 --- a/hercules_opt/src/lib.rs +++ b/hercules_opt/src/lib.rs @@ -1,6 +1,7 @@ #![feature(let_chains)] pub mod ccp; +pub mod crc; pub mod dce; pub mod delete_uncalled; pub mod editor; @@ -23,6 +24,7 @@ pub mod unforkify; pub mod utils; pub use crate::ccp::*; +pub use crate::crc::*; pub use crate::dce::*; pub use crate::delete_uncalled::*; pub use crate::editor::*; diff --git a/hercules_opt/src/pass.rs b/hercules_opt/src/pass.rs index 4f44d1d1a833b808a23ef3e56338097a1b874a02..e528b35de7a2e94fd94a8014008073c15548cbd7 100644 --- a/hercules_opt/src/pass.rs +++ b/hercules_opt/src/pass.rs @@ -25,6 +25,7 @@ pub enum Pass { PhiElim, Forkify, ForkGuardElim, + CRC, SLF, WritePredication, Predication, @@ -471,6 +472,33 @@ impl PassManager { } self.clear_analyses(); } + Pass::CRC => { + self.make_def_uses(); + let def_uses = self.def_uses.as_ref().unwrap(); + for idx in 0..self.module.functions.len() { + let constants_ref = + RefCell::new(std::mem::take(&mut self.module.constants)); + let dynamic_constants_ref = + RefCell::new(std::mem::take(&mut self.module.dynamic_constants)); + let types_ref = RefCell::new(std::mem::take(&mut self.module.types)); + let mut editor = FunctionEditor::new( + &mut self.module.functions[idx], + FunctionID::new(idx), + &constants_ref, + &dynamic_constants_ref, + &types_ref, + &def_uses[idx], + ); + crc(&mut editor); + + self.module.constants = constants_ref.take(); + self.module.dynamic_constants = dynamic_constants_ref.take(); + self.module.types = types_ref.take(); + + self.module.functions[idx].delete_gravestones(); + } + self.clear_analyses(); + } Pass::SLF => { self.make_def_uses(); self.make_reverse_postorders(); @@ -498,7 +526,6 @@ impl PassManager { self.module.dynamic_constants = dynamic_constants_ref.take(); self.module.types = types_ref.take(); - println!("{}", self.module.functions[idx].name); self.module.functions[idx].delete_gravestones(); } self.clear_analyses(); diff --git a/hercules_rt/src/lib.rs b/hercules_rt/src/lib.rs index eeb09eb6859fef91c10f2026bbb8553274195cae..60d3470edc8cf42dd105cb4a2835a2a86d00fe3f 100644 --- a/hercules_rt/src/lib.rs +++ b/hercules_rt/src/lib.rs @@ -199,7 +199,6 @@ impl<'b, 'a: 'b> HerculesBox<'a> { } pub unsafe fn __zeros(size: u64) -> Self { - assert_ne!(size, 0); let size = size as usize; let id = NUM_OBJECTS.fetch_add(1, Ordering::Relaxed); HerculesBox { diff --git a/juno_frontend/src/lib.rs b/juno_frontend/src/lib.rs index 8ca9d6792633e3e5bc4ea551763fe3f8bb8401cd..c06ebf34e293afc10ff84e45fa422c3c2dabad5d 100644 --- a/juno_frontend/src/lib.rs +++ b/juno_frontend/src/lib.rs @@ -182,6 +182,8 @@ pub fn compile_ir( add_pass!(pm, verify, WritePredication); add_pass!(pm, verify, PhiElim); add_pass!(pm, verify, DCE); + add_pass!(pm, verify, CRC); + add_pass!(pm, verify, DCE); add_pass!(pm, verify, SLF); add_pass!(pm, verify, DCE); add_pass!(pm, verify, Predication);