From 4710ab4e512bcf0ce803325dba7f78f3cba106a8 Mon Sep 17 00:00:00 2001 From: Russel Arbore <russel.jma@gmail.com> Date: Wed, 12 Feb 2025 10:45:04 -0600 Subject: [PATCH] fix getting dc params, add graphs for paper --- .gitignore | 1 + hercules_opt/src/inline.rs | 35 +++++++--------- hercules_opt/src/interprocedural_sroa.rs | 26 ++++++------ juno_scheduler/src/default.rs | 1 + paper_resources/arr_sum_ir.dot | 49 +++++++++++++++++++++++ paper_resources/arr_sum_ir.pdf | Bin 0 -> 17654 bytes 6 files changed, 78 insertions(+), 34 deletions(-) create mode 100644 paper_resources/arr_sum_ir.dot create mode 100644 paper_resources/arr_sum_ir.pdf diff --git a/.gitignore b/.gitignore index 87af5349..516108dd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /target *.dot +!paper_resources/*.dot *.bc *.out *.ll diff --git a/hercules_opt/src/inline.rs b/hercules_opt/src/inline.rs index 848d957f..f01b2366 100644 --- a/hercules_opt/src/inline.rs +++ b/hercules_opt/src/inline.rs @@ -24,21 +24,19 @@ pub fn inline(editors: &mut [FunctionEditor], callgraph: &CallGraph) { .map(|editor| collapse_returns(editor)) .collect(); - // Step 3: verify that each possible dynamic constant parameter index has a - // single unique dynamic constant ID. If this isn't true, dynamic constant - // substitution won't work, and this should be true anyway! - let mut found_idxs = HashMap::new(); - for id in editors[0].dynamic_constant_ids() { - let dc = editors[0].get_dynamic_constant(id); - if let DynamicConstant::Parameter(idx) = *dc { - assert!(!found_idxs.contains_key(&idx)); - found_idxs.insert(idx, id); - } - } - let mut dc_param_idx_to_dc_id = vec![]; - for idx in 0..found_idxs.len() { - dc_param_idx_to_dc_id.push(found_idxs[&idx]); - } + // Step 3: get dynamic constant IDs for parameters. + let max_num_dc_params = editors + .iter() + .map(|editor| editor.func().num_dynamic_constants) + .max() + .unwrap(); + let mut dc_args = vec![]; + editors[0].edit(|mut edit| { + dc_args = (0..max_num_dc_params as usize) + .map(|i| edit.add_dynamic_constant(DynamicConstant::Parameter(i))) + .collect(); + Ok(edit) + }); // Step 4: run inlining on each function individually. Iterate the functions // in topological order. @@ -49,12 +47,7 @@ pub fn inline(editors: &mut [FunctionEditor], callgraph: &CallGraph) { // 2. Shared references to all of the functions called by that function. let callees = callgraph.get_callees(to_inline_id); let editor_refs = get_mut_and_immuts(editors, to_inline_id, callees); - inline_func( - editor_refs.0, - editor_refs.1, - &single_return_nodes, - &dc_param_idx_to_dc_id, - ); + inline_func(editor_refs.0, editor_refs.1, &single_return_nodes, &dc_args); } } diff --git a/hercules_opt/src/interprocedural_sroa.rs b/hercules_opt/src/interprocedural_sroa.rs index b345f9bc..944ef8fd 100644 --- a/hercules_opt/src/interprocedural_sroa.rs +++ b/hercules_opt/src/interprocedural_sroa.rs @@ -235,18 +235,18 @@ fn compress_return_products(editors: &mut Vec<FunctionEditor>, all_callsites_edi // dc_param_idx_to_dc_id to get the id of the dynamic constants in the function, // and then replace dc_param_idx_to_dc_id[i] with call.dynamic_constants[i], // for all i. - let mut found_idxs = HashMap::new(); - for id in editors[0].dynamic_constant_ids() { - let dc = editors[0].get_dynamic_constant(id); - if let DynamicConstant::Parameter(idx) = *dc { - assert!(!found_idxs.contains_key(&idx)); - found_idxs.insert(idx, id); - } - } - let mut dc_param_idx_to_dc_id = vec![]; - for idx in 0..found_idxs.len() { - dc_param_idx_to_dc_id.push(found_idxs[&idx]); - } + let max_num_dc_params = editors + .iter() + .map(|editor| editor.func().num_dynamic_constants) + .max() + .unwrap(); + let mut dc_args = vec![]; + editors[0].edit(|mut edit| { + dc_args = (0..max_num_dc_params as usize) + .map(|i| edit.add_dynamic_constant(DynamicConstant::Parameter(i))) + .collect(); + Ok(edit) + }); // Step 2. Modify the return type of all editors corresponding to a function // for which we can edit every callsite, and the return type is a product. @@ -314,7 +314,7 @@ fn compress_return_products(editors: &mut Vec<FunctionEditor>, all_callsites_edi // a better abstraction around bulk replacement. let new_dcs = (*dynamic_constants).to_vec(); - let old_dcs = dc_param_idx_to_dc_id[..new_dcs.len()].to_vec(); + let old_dcs = dc_args[..new_dcs.len()].to_vec(); assert_eq!(old_dcs.len(), new_dcs.len()); let substs = old_dcs .into_iter() diff --git a/juno_scheduler/src/default.rs b/juno_scheduler/src/default.rs index 3f4af107..8ef3d662 100644 --- a/juno_scheduler/src/default.rs +++ b/juno_scheduler/src/default.rs @@ -64,6 +64,7 @@ pub fn default_schedule() -> ScheduleStmt { DCE, GVN, DCE, + Xdot, LiftDCMath, DCE, GVN, diff --git a/paper_resources/arr_sum_ir.dot b/paper_resources/arr_sum_ir.dot new file mode 100644 index 00000000..7479b259 --- /dev/null +++ b/paper_resources/arr_sum_ir.dot @@ -0,0 +1,49 @@ +digraph "Module" { +margin=0; +subgraph sum { +label="sum<1>" +style=invis +cluster=true +ranksep=1; +nodesep=1; +start_0_0 [xlabel=0, label=<Start<BR /><FONT POINT-SIZE="8">Control</FONT>>, color=darkred]; +parameter_0_1 [xlabel=1, label=<Parameter (#0)<BR /><FONT POINT-SIZE="8">Array(Float32, #0)</FONT>>, color=darkblue]; +dynamic_constant_0_2 [xlabel=2, label=<DynamicConstant (#0)<BR /><FONT POINT-SIZE="8">UnsignedInteger64</FONT>>, color=darkblue]; +projection_0_3 [xlabel=3, label=<Projection<BR /><FONT POINT-SIZE="8">Control</FONT>>, color=darkred]; +add_0_4 [xlabel=4, label=<Add<BR /><FONT POINT-SIZE="8">UnsignedInteger64</FONT>>, color=darkblue]; +add_0_5 [xlabel=5, label=<Add<BR /><FONT POINT-SIZE="8">Float32</FONT>>, color=darkblue]; +read_0_6 [xlabel=6, label=<Read<BR /><FONT POINT-SIZE="8">Float32</FONT>>, color=darkblue]; +lt_0_7 [xlabel=7, label=<LT<BR /><FONT POINT-SIZE="8">Boolean</FONT>>, color=darkblue]; +if_0_8 [xlabel=8, label=<If<BR /><FONT POINT-SIZE="8">Control</FONT>>, color=darkred]; +projection_0_9 [xlabel=9, label=<Projection<BR /><FONT POINT-SIZE="8">Control</FONT>>, color=darkred]; +return_0_10 [xlabel=10, label=<Return>, color=darkred]; +constant_0_11 [xlabel=11, label=<Constant (0)<BR /><FONT POINT-SIZE="8">UnsignedInteger64</FONT>>, color=darkblue]; +constant_0_12 [xlabel=12, label=<Constant (1)<BR /><FONT POINT-SIZE="8">UnsignedInteger64</FONT>>, color=darkblue]; +constant_0_13 [xlabel=13, label=<Constant (0)<BR /><FONT POINT-SIZE="8">Float32</FONT>>, color=darkblue]; +phi_0_14 [xlabel=14, label=<Phi<BR /><FONT POINT-SIZE="8">UnsignedInteger64</FONT>>, color=darkblue]; +phi_0_15 [xlabel=15, label=<Phi<BR /><FONT POINT-SIZE="8">Float32</FONT>>, color=darkblue]; +region_0_16 [xlabel=16, label=<Region<BR /><FONT POINT-SIZE="8">Control</FONT>>, color=darkred]; +if_0_8 -> projection_0_3 [color=black, style="dashed"]; +phi_0_14 -> add_0_4 [color=black, style=""]; +constant_0_12 -> add_0_4 [color=black, style=""]; +phi_0_15 -> add_0_5 [color=black, style=""]; +read_0_6 -> add_0_5 [color=black, style=""]; +parameter_0_1 -> read_0_6 [color=black, style=""]; +phi_0_14 -> read_0_6 [color=black, style=""]; +add_0_4 -> lt_0_7 [color=black, style=""]; +dynamic_constant_0_2 -> lt_0_7 [color=black, style=""]; +if_0_8 -> region_0_16 [dir=back, color=black, style="dashed"]; +lt_0_7 -> if_0_8 [color=black, style="dotted"]; +if_0_8 -> projection_0_9 [color=black, style="dashed"]; +projection_0_9 -> return_0_10 [color=black, style="dashed"]; +add_0_5 -> return_0_10 [color=black, style="dotted"]; +constant_0_11 -> phi_0_14 [color=black, style=""]; +phi_0_14 -> add_0_4 [dir=back, color=black, style=""]; +region_0_16 -> phi_0_14 [color=black, style="dotted"]; +constant_0_13 -> phi_0_15 [color=black, style=""]; +add_0_5 -> phi_0_15 [color=black, style=""]; +region_0_16 -> phi_0_15 [color=black, style="dotted"]; +start_0_0 -> region_0_16 [color=black, style="dashed"]; +projection_0_3 -> region_0_16 [color=black, style="dashed"]; +} +} diff --git a/paper_resources/arr_sum_ir.pdf b/paper_resources/arr_sum_ir.pdf new file mode 100644 index 0000000000000000000000000000000000000000..61c5e4314dd3a4a61064e228fc6ec50acc17232c GIT binary patch literal 17654 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 b^m=hgVo^y&5ztqL<|YOvT&k+B{%%|V9i0^- literal 0 HcmV?d00001 -- GitLab