diff --git a/hercules_ir/src/dot.rs b/hercules_ir/src/dot.rs index 7ad8c6dfa0dbdafc2bc1a9a765a847932cfeadf3..9c6c5f174a4c3b1c4a19ce15597e5385ddae7aa4 100644 --- a/hercules_ir/src/dot.rs +++ b/hercules_ir/src/dot.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::env::temp_dir; use std::fmt::Write; use std::fs::File; @@ -15,6 +15,7 @@ use crate::*; */ pub fn xdot_module( module: &ir::Module, + func_selection: &Vec<bool>, reverse_postorders: &Vec<Vec<NodeID>>, typing: Option<&ModuleTyping>, doms: Option<&Vec<DomTree>>, @@ -30,6 +31,7 @@ pub fn xdot_module( let mut contents = String::new(); write_dot( &module, + func_selection, &reverse_postorders, typing, doms, @@ -54,6 +56,7 @@ pub fn xdot_module( */ pub fn write_dot<W: Write>( module: &ir::Module, + func_selection: &Vec<bool>, reverse_postorders: &Vec<Vec<NodeID>>, typing: Option<&ModuleTyping>, doms: Option<&Vec<DomTree>>, @@ -64,7 +67,10 @@ pub fn write_dot<W: Write>( ) -> std::fmt::Result { write_digraph_header(w)?; - for function_id in (0..module.functions.len()).map(FunctionID::new) { + for function_id in (0..module.functions.len()) + .filter(|idx| func_selection[*idx]) + .map(FunctionID::new) + { let function = &module.functions[function_id.idx()]; let reverse_postorder = &reverse_postorders[function_id.idx()]; let mut reverse_postorder_node_numbers = vec![0; function.nodes.len()]; @@ -93,7 +99,9 @@ pub fn write_dot<W: Write>( color, module, typing, + &function.labels[node_id.idx()], &function.schedules[node_id.idx()], + &module.labels, w, )?; } @@ -254,7 +262,9 @@ fn write_node<W: Write>( color: &str, module: &Module, typing: Option<&ModuleTyping>, + label_set: &HashSet<LabelID>, schedules: &Vec<Schedule>, + labels: &Vec<String>, w: &mut W, ) -> std::fmt::Result { let node = &module.functions[function_id.idx()].nodes[node_id.idx()]; @@ -341,62 +351,39 @@ fn write_node<W: Write>( if let Some(ty) = typing.map(|typing| typing[function_id.idx()][node_id.idx()]) { module.write_type(ty, &mut tylabel)?; } - + let mut iter = label_set.into_iter(); + let label_set = if let Some(first) = iter.next() { + iter.fold(format!("{}", labels[first.idx()]), |b, i| { + format!("{}, {}", b, labels[i.idx()]) + }) + } else { + String::new() + }; let mut iter = schedules.into_iter(); let schedules = if let Some(first) = iter.next() { iter.fold(format!("{:?}", first), |b, i| format!("{}, {:?}", b, i)) } else { String::new() }; - if tylabel.is_empty() && schedules.is_empty() { - write!( - w, - "{}_{}_{} [xlabel={}, label=<{}>, color={}];\n", - node.lower_case_name(), - function_id.idx(), - node_id.idx(), - xlabel, - label, - color - )?; - } else if schedules.is_empty() { - write!( - w, - "{}_{}_{} [xlabel={}, label=<{}<BR /><FONT POINT-SIZE=\"8\">{}</FONT>>, color={}];\n", - node.lower_case_name(), - function_id.idx(), - node_id.idx(), - xlabel, - label, - tylabel, - color - )?; - } else if tylabel.is_empty() { - write!( - w, - "{}_{}_{} [xlabel={}, label=<{}<BR /><FONT POINT-SIZE=\"8\">{}</FONT>>, color={}];\n", - node.lower_case_name(), - function_id.idx(), - node_id.idx(), - xlabel, - label, - schedules, - color - )?; - } else { - write!( - w, - "{}_{}_{} [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(), - xlabel, - label, - tylabel, - schedules, - color - )?; + write!( + w, + "{}_{}_{} [xlabel={}, label=<{}", + node.lower_case_name(), + function_id.idx(), + node_id.idx(), + xlabel, + label, + )?; + if !tylabel.is_empty() { + write!(w, "<BR /><FONT POINT-SIZE=\"8\">{}</FONT>", tylabel,)?; + } + if !label_set.is_empty() { + write!(w, "<BR /><FONT POINT-SIZE=\"8\">{}</FONT>", label_set,)?; + } + if !schedules.is_empty() { + write!(w, "<BR /><FONT POINT-SIZE=\"8\">{}</FONT>", schedules,)?; } + write!(w, ">, color={}];\n", color)?; Ok(()) } diff --git a/juno_scheduler/src/pm.rs b/juno_scheduler/src/pm.rs index e9c681cd1239fca6cc1946c55032837eff7c2f00..9c7391acd5686d95461ed562f61b3dbc9774651a 100644 --- a/juno_scheduler/src/pm.rs +++ b/juno_scheduler/src/pm.rs @@ -2328,6 +2328,22 @@ fn run_pass( None => true, }; + let mut bool_selection = vec![]; + if let Some(selection) = selection { + bool_selection = vec![false; pm.functions.len()]; + for loc in selection { + let CodeLocation::Function(id) = loc else { + return Err(SchedulerError::PassError { + pass: "xdot".to_string(), + error: "expected coarse-grained selection (can't partially xdot a function)".to_string(), + }); + }; + bool_selection[id.idx()] = true; + } + } else { + bool_selection = vec![true; pm.functions.len()]; + } + pm.make_reverse_postorders(); if force_analyses { pm.make_typing(); @@ -2345,6 +2361,7 @@ fn run_pass( pm.with_mod(|module| { xdot_module( module, + &bool_selection, &reverse_postorders, typing.as_ref(), doms.as_ref(),