diff --git a/hercules_opt/src/editor.rs b/hercules_opt/src/editor.rs index 1981b1297be06a4bf91a59fd870697aeafff4a91..2d342a88846dc334484d4ab58efd27652eeb20c5 100644 --- a/hercules_opt/src/editor.rs +++ b/hercules_opt/src/editor.rs @@ -462,7 +462,7 @@ impl<'a, 'b> FunctionEdit<'a, 'b> { Constant::Product(id, dummy_elems.into_boxed_slice()) } Type::Summation(tys) => Constant::Summation(id, 0, self.add_zero_constant(tys[0])), - Type::Array(tid, _) => Constant::Array(tid), + Type::Array(_, _) => Constant::Array(id), }; self.add_constant(constant_to_construct) } diff --git a/hercules_opt/src/pass.rs b/hercules_opt/src/pass.rs index 33d7bfb3f7d476b262cac094c6b5bfbbebda925e..f69958e2f2dd51b1f2a2c26f07a281031927bbb5 100644 --- a/hercules_opt/src/pass.rs +++ b/hercules_opt/src/pass.rs @@ -675,7 +675,6 @@ impl PassManager { self.make_doms(); self.make_fork_join_maps(); self.make_bbs(); - self.make_plans(); } xdot_module( &self.module, diff --git a/hercules_opt/src/sroa.rs b/hercules_opt/src/sroa.rs index 59ee4a8ad54cea9627ae85185fe5fe04198e72cc..67c904ffbc566b373f4b7f13f68b5cb5a77d08af 100644 --- a/hercules_opt/src/sroa.rs +++ b/hercules_opt/src/sroa.rs @@ -1,8 +1,7 @@ extern crate hercules_ir; -use std::collections::{BTreeMap, HashMap, LinkedList, VecDeque}; +use std::collections::{BTreeMap, HashMap, VecDeque}; -use self::hercules_ir::dataflow::*; use self::hercules_ir::ir::*; use crate::*; @@ -41,6 +40,12 @@ use crate::*; * replaced by a direct def of the field value */ pub fn sroa(editor: &mut FunctionEditor, reverse_postorder: &Vec<NodeID>, types: &Vec<TypeID>) { + let mut types: HashMap<NodeID, TypeID> = types + .iter() + .enumerate() + .map(|(i, t)| (NodeID::new(i), *t)) + .collect(); + // This map stores a map from NodeID to an index tree which can be used to lookup the NodeID // that contains the corresponding fields of the original value let mut field_map: HashMap<NodeID, IndexTree<NodeID>> = HashMap::new(); @@ -65,17 +70,15 @@ pub fn sroa(editor: &mut FunctionEditor, reverse_postorder: &Vec<NodeID>, types: second: _, third: _, op: TernaryOperator::Select, - } if editor.get_type(types[node.idx()]).is_product() => product_nodes.push(*node), + } if editor.get_type(types[&node]).is_product() => product_nodes.push(*node), - Node::Read { collect, .. } if editor.get_type(types[collect.idx()]).is_product() => { + Node::Read { collect, .. } if editor.get_type(types[&collect]).is_product() => { product_nodes.push(*node) } // We add all calls to the call/return list and check their arguments later Node::Call { .. } => call_return_nodes.push(*node), - Node::Return { control: _, data } - if editor.get_type(types[data.idx()]).is_product() => - { + Node::Return { control: _, data } if editor.get_type(types[&data]).is_product() => { call_return_nodes.push(*node) } @@ -93,10 +96,9 @@ pub fn sroa(editor: &mut FunctionEditor, reverse_postorder: &Vec<NodeID>, types: for node in call_return_nodes { match &editor.func().nodes[node.idx()] { Node::Return { control, data } => { - assert!(editor.get_type(types[data.idx()]).is_product()); + assert!(editor.get_type(types[&data]).is_product()); let control = *control; - let new_data = - reconstruct_product(editor, types[data.idx()], *data, &mut product_nodes); + let new_data = reconstruct_product(editor, types[&data], *data, &mut product_nodes); editor.edit(|mut edit| { edit.add_node(Node::Return { control, @@ -117,18 +119,18 @@ pub fn sroa(editor: &mut FunctionEditor, reverse_postorder: &Vec<NodeID>, types: let args = args.clone(); // If the call returns a product, we generate reads for each field - let fields = if editor.get_type(types[node.idx()]).is_product() { - Some(generate_reads(editor, types[node.idx()], node)) + let fields = if editor.get_type(types[&node]).is_product() { + Some(generate_reads(editor, types[&node], node)) } else { None }; let mut new_args = vec![]; for arg in args { - if editor.get_type(types[arg.idx()]).is_product() { + if editor.get_type(types[&arg]).is_product() { new_args.push(reconstruct_product( editor, - types[arg.idx()], + types[&arg], arg, &mut product_nodes, )); @@ -146,6 +148,13 @@ pub fn sroa(editor: &mut FunctionEditor, reverse_postorder: &Vec<NodeID>, types: let edit = edit.replace_all_uses(node, new_call)?; let edit = edit.delete_node(node)?; + // Since we've replaced uses of calls with the new node, we update the type + // information so that we can retrieve the type of the new call if needed + // Because the other nodes we've created so far are only used in very + // particular ways (i.e. are not used by arbitrary nodes) we don't need their + // type information but do for the new calls + types.insert(new_call, types[&node]); + match fields { None => {} Some(fields) => { @@ -195,7 +204,7 @@ pub fn sroa(editor: &mut FunctionEditor, reverse_postorder: &Vec<NodeID>, types: for node in product_nodes { match editor.func().nodes[node.idx()] { Node::Parameter { .. } => { - field_map.insert(node, generate_reads(editor, types[node.idx()], node)); + field_map.insert(node, generate_reads(editor, types[&node], node)); } Node::Constant { id } => { field_map.insert(node, generate_constant_fields(editor, id)); @@ -222,7 +231,7 @@ pub fn sroa(editor: &mut FunctionEditor, reverse_postorder: &Vec<NodeID>, types: Node::Phi { control, data } => { let control = *control; let data = data.clone(); - let fields = allocate_fields(editor, types[node.idx()], &mut next_id); + let fields = allocate_fields(editor, types[&node], &mut next_id); field_map.insert(node, fields.clone()); item = WorkItem::AllocatedPhi { @@ -240,7 +249,7 @@ pub fn sroa(editor: &mut FunctionEditor, reverse_postorder: &Vec<NodeID>, types: let control = *control; let init = *init; let reduct = *reduct; - let fields = allocate_fields(editor, types[node.idx()], &mut next_id); + let fields = allocate_fields(editor, types[&node], &mut next_id); field_map.insert(node, fields.clone()); item = WorkItem::AllocatedReduce { @@ -260,7 +269,7 @@ pub fn sroa(editor: &mut FunctionEditor, reverse_postorder: &Vec<NodeID>, types: let first = *first; let second = *second; let third = *third; - let fields = allocate_fields(editor, types[node.idx()], &mut next_id); + let fields = allocate_fields(editor, types[&node], &mut next_id); field_map.insert(node, fields.clone()); item = WorkItem::AllocatedTernary { @@ -278,7 +287,7 @@ pub fn sroa(editor: &mut FunctionEditor, reverse_postorder: &Vec<NodeID>, types: indices, } => { if let Some(index_map) = field_map.get(collect) { - if editor.get_type(types[data.idx()]).is_product() { + if editor.get_type(types[&data]).is_product() { if let Some(data_idx) = field_map.get(data) { field_map.insert( node, @@ -768,7 +777,7 @@ fn generate_constant(editor: &mut FunctionEditor, typ: TypeID) -> ConstantID { let const_id = generate_constant(editor, ts[0]); add_const!(editor, Constant::Summation(typ, 0, const_id)) } - Type::Array(elem, _) => { + Type::Array(_, _) => { add_const!(editor, Constant::Array(typ)) } Type::Control => panic!("Cannot create constant of control type"), diff --git a/juno_frontend/src/lib.rs b/juno_frontend/src/lib.rs index b5ce14565393217189887fe4805939ef3c4e48fb..b2af338157ac01181b4815f2add9019b27e27cab 100644 --- a/juno_frontend/src/lib.rs +++ b/juno_frontend/src/lib.rs @@ -147,7 +147,9 @@ pub fn compile_ir( if verify.verify() || verify.verify_all() { pm.add_pass(hercules_opt::pass::Pass::Verify); } + add_verified_pass!(pm, verify, GVN); add_verified_pass!(pm, verify, PhiElim); + add_pass!(pm, verify, DCE); if x_dot { pm.add_pass(hercules_opt::pass::Pass::Xdot(true)); } @@ -159,6 +161,7 @@ pub fn compile_ir( // We run phi-elim again because SROA can introduce new phis that might be able to be // simplified add_verified_pass!(pm, verify, PhiElim); + add_pass!(pm, verify, DCE); if x_dot { pm.add_pass(hercules_opt::pass::Pass::Xdot(true)); }