diff --git a/hercules_ir/src/dot.rs b/hercules_ir/src/dot.rs index 8efabd7a99157b9bb8b40e5abe76d2d42513bb79..5ccda9dc6bf39c016ba44b6eb1085679288d5c54 100644 --- a/hercules_ir/src/dot.rs +++ b/hercules_ir/src/dot.rs @@ -16,6 +16,7 @@ use crate::*; pub fn xdot_module( module: &ir::Module, reverse_postorders: &Vec<Vec<NodeID>>, + typing: Option<&ModuleTyping>, doms: Option<&Vec<DomTree>>, fork_join_maps: Option<&Vec<HashMap<NodeID, NodeID>>>, devices: Option<&Vec<Device>>, @@ -30,6 +31,7 @@ pub fn xdot_module( write_dot( &module, &reverse_postorders, + typing, doms, fork_join_maps, devices, @@ -53,6 +55,7 @@ pub fn xdot_module( pub fn write_dot<W: Write>( module: &ir::Module, reverse_postorders: &Vec<Vec<NodeID>>, + typing: Option<&ModuleTyping>, doms: Option<&Vec<DomTree>>, fork_join_maps: Option<&Vec<HashMap<NodeID, NodeID>>>, devices: Option<&Vec<Device>>, @@ -89,6 +92,7 @@ pub fn write_dot<W: Write>( function_id, color, module, + typing, &function.schedules[node_id.idx()], w, )?; @@ -249,6 +253,7 @@ fn write_node<W: Write>( function_id: FunctionID, color: &str, module: &Module, + typing: Option<&ModuleTyping>, schedules: &Vec<Schedule>, w: &mut W, ) -> std::fmt::Result { @@ -331,30 +336,37 @@ fn write_node<W: Write>( } else { format!("{} ({})", node.upper_case_name(), suffix) }; + let xlabel = format!("{}", node_id.idx()); + let mut tylabel = String::new(); + if let Some(ty) = typing.map(|typing| typing[function_id.idx()][node_id.idx()]) { + module.write_type(ty, &mut tylabel)?; + } let mut iter = schedules.into_iter(); if let Some(first) = iter.next() { - let subtitle = iter.fold(format!("{:?}", first), |b, i| format!("{}, {:?}", b, i)); + let schedules = iter.fold(format!("{:?}", first), |b, i| format!("{}, {:?}", b, i)); write!( w, - "{}_{}_{} [xlabel={}, label=<{}<BR /><FONT POINT-SIZE=\"8\">{}</FONT>>, color={}];\n", + "{}_{}_{} [xlabel={}, label=<{}<BR /><FONT POINT-SIZE=\"8\">{}</FONT><BR /><FONT POINT-SIZE=\"8\">{}</FONT>>, color={}];\n", node.lower_case_name(), function_id.idx(), node_id.idx(), - node_id.idx(), + xlabel, label, - subtitle, + tylabel, + schedules, color )?; } else { write!( w, - "{}_{}_{} [xlabel={}, label=\"{}\", color={}];\n", + "{}_{}_{} [xlabel={}, label=<{}<BR /><FONT POINT-SIZE=\"8\">{}</FONT>>, color={}];\n", node.lower_case_name(), function_id.idx(), node_id.idx(), - node_id.idx(), + xlabel, label, + tylabel, color )?; } diff --git a/hercules_ir/src/ir.rs b/hercules_ir/src/ir.rs index d8a124e2cfefde8ea10c3ecbe67b6a6b9a93c690..0b271e857df2269cbdfc51e223424141435558c6 100644 --- a/hercules_ir/src/ir.rs +++ b/hercules_ir/src/ir.rs @@ -628,6 +628,7 @@ pub fn dynamic_constants_bottom_up( dynamic_constants: &Vec<DynamicConstant>, ) -> impl Iterator<Item = DynamicConstantID> + '_ { let mut visited = bitvec![u8, Lsb0; 0; dynamic_constants.len()]; + let mut invalid = bitvec![u8, Lsb0; 0; dynamic_constants.len()]; let mut stack = (0..dynamic_constants.len()) .map(DynamicConstantID::new) .collect::<Vec<DynamicConstantID>>(); @@ -647,13 +648,16 @@ pub fn dynamic_constants_bottom_up( // We have to yield the children of this node before // this node itself. We keep track of which nodes have // yielded using visited. - if left.idx() >= visited.len() || right.idx() >= visited.len() { + if left.idx() >= visited.len() + || right.idx() >= visited.len() + || invalid[left.idx()] + || invalid[right.idx()] + { // This is an invalid dynamic constant and should be // skipped. + invalid.set(id.idx(), true); continue; - } - let can_yield = visited[left.idx()] && visited[right.idx()]; - if can_yield { + } else if visited[left.idx()] && visited[right.idx()] { visited.set(id.idx(), true); yield id; } else { diff --git a/hercules_opt/src/gcm.rs b/hercules_opt/src/gcm.rs index 0c7665bfe153dec310369575885074314eebad96..b5822a519a5ca204db3a80d581493ea37ded511b 100644 --- a/hercules_opt/src/gcm.rs +++ b/hercules_opt/src/gcm.rs @@ -1163,11 +1163,12 @@ fn object_allocation( Node::Call { control: _, function: callee, - dynamic_constants: _, + ref dynamic_constants, args: _, } => { + let dynamic_constants = dynamic_constants.clone(); for device in BACKED_DEVICES { - if let Some(callee_backing_size) = backing_allocations[&callee] + if let Some(mut callee_backing_size) = backing_allocations[&callee] .get(&device) .map(|(callee_total, _)| *callee_total) { @@ -1177,6 +1178,27 @@ fn object_allocation( // in the callee, so just assume the largest alignment. *total = align(&mut edit, *total, LARGEST_ALIGNMENT); offsets.insert(id, *total); + // Substitute the dynamic constant parameters in the + // callee's backing size. + let first_dc = edit.num_dynamic_constants() + 10000; + for (p_idx, dc_n) in zip(0..dynamic_constants.len(), first_dc..) { + let dc_a = + edit.add_dynamic_constant(DynamicConstant::Parameter(p_idx)); + callee_backing_size = substitute_dynamic_constants( + dc_a, + DynamicConstantID::new(dc_n), + callee_backing_size, + &mut edit, + ); + } + for (dc_n, dc_b) in zip(first_dc.., dynamic_constants.iter()) { + callee_backing_size = substitute_dynamic_constants( + DynamicConstantID::new(dc_n), + *dc_b, + callee_backing_size, + &mut edit, + ); + } *total = edit.add_dynamic_constant(DynamicConstant::Add( *total, callee_backing_size, diff --git a/hercules_opt/src/inline.rs b/hercules_opt/src/inline.rs index 064e3d73a1d9604ca5b284fe52b8c2e8c5a0339e..1d2bac97d848ace910d614a42743c6ea5fe3aa9e 100644 --- a/hercules_opt/src/inline.rs +++ b/hercules_opt/src/inline.rs @@ -179,7 +179,7 @@ fn inline_func( // as the new references we just made in the first step. We // actually want to institute all the updates // *simultaneously*, hence the two step maneuver. - let first_dc = edit.num_dynamic_constants() + 100; + let first_dc = edit.num_dynamic_constants() + 10000; for (dc_a, dc_n) in zip(dcs_a, first_dc..) { substitute_dynamic_constants_in_node( *dc_a, diff --git a/hercules_opt/src/interprocedural_sroa.rs b/hercules_opt/src/interprocedural_sroa.rs index 49fbcbbd712fad2977c64fd2ca1d9643bd95d74c..f597cd80347d94a7c927d6fe085d80f843e280eb 100644 --- a/hercules_opt/src/interprocedural_sroa.rs +++ b/hercules_opt/src/interprocedural_sroa.rs @@ -320,7 +320,7 @@ fn compress_return_products(editors: &mut Vec<FunctionEditor>, all_callsites_edi let mut substituted = old_return_type_ids[function_id.idx()]; assert_eq!(old_dcs.len(), new_dcs.len()); - let first_dc = edit.num_dynamic_constants() + 100; + let first_dc = edit.num_dynamic_constants() + 10000; for (dc_a, dc_n) in zip(old_dcs, first_dc..) { substituted = substitute_dynamic_constants_in_type( dc_a, @@ -424,7 +424,7 @@ fn remove_return_singletons(editors: &mut Vec<FunctionEditor>, all_callsites_edi if singleton_removed[function.idx()] { let edit_successful = editor.edit(|mut edit| { let mut substituted = old_return_type_ids[function.idx()]; - let first_dc = edit.num_dynamic_constants() + 100; + let first_dc = edit.num_dynamic_constants() + 10000; let dc_params: Vec<_> = (0..dc_args.len()) .map(|param_idx| { edit.add_dynamic_constant(DynamicConstant::Parameter(param_idx)) diff --git a/juno_scheduler/src/pm.rs b/juno_scheduler/src/pm.rs index e62bc78dc4a6e4bb2e1c369fcd2fffc67255ea52..c388833ca6efbc5d1c4f9f7ec346980cbfc1b918 100644 --- a/juno_scheduler/src/pm.rs +++ b/juno_scheduler/src/pm.rs @@ -1636,12 +1636,14 @@ fn run_pass( pm.make_reverse_postorders(); if force_analyses { + pm.make_typing(); pm.make_doms(); pm.make_fork_join_maps(); pm.make_devices(); } let reverse_postorders = pm.reverse_postorders.take().unwrap(); + let typing = pm.typing.take(); let doms = pm.doms.take(); let fork_join_maps = pm.fork_join_maps.take(); let devices = pm.devices.take(); @@ -1650,6 +1652,7 @@ fn run_pass( xdot_module( module, &reverse_postorders, + typing.as_ref(), doms.as_ref(), fork_join_maps.as_ref(), devices.as_ref(),