|
| 1 | +use std::cmp::{max_by, min_by}; |
| 2 | + |
1 | 3 | use zhc_utils::{ |
2 | | - FastMap, |
3 | | - graphics::{Frame, Height, Position}, |
4 | | - iter::CollectInSmallVec, |
5 | | - svec, |
| 4 | + FastMap, graphics::{Frame, Height, Position}, iter::{CollectInSmallVec, Interleave, Slide, SliderExt}, svec |
6 | 5 | }; |
7 | 6 |
|
8 | 7 | use crate::{ |
@@ -48,17 +47,49 @@ fn gen_layers<'ir, 'ann>( |
48 | 47 | order.sort_unstable_by_key(|(place, _)| *place); |
49 | 48 | let (variable, assocs) = gen_layer(ir.walk_ops_with(order.into_iter().map(|(_, id)| id))); |
50 | 49 | variables.push(LayerMemberLayer(variable)); |
51 | | - let links_out = ir |
52 | | - .walk_ops_with(layer.walker()) |
53 | | - .flat_map(|op| op.get_returns_iter().flat_map(|v| v.get_uses_iter())) |
54 | | - .count(); |
55 | | - let sep_height = Height::new(10. * links_out as f64); |
56 | | - variables.push(LayerMemberSeparator(LayerSeparator::vertical(sep_height))); |
57 | 50 | assocs.into_iter().for_each(|(k, v)| { |
58 | 51 | opmap.insert(k, v); |
59 | 52 | }); |
60 | 53 | } |
61 | | - variables.pop(); |
| 54 | + let variables = variables |
| 55 | + .into_iter() |
| 56 | + .interleave_with( |
| 57 | + layers_map |
| 58 | + .iter_layers() |
| 59 | + .slide::<2>() |
| 60 | + .skip_noncompletes() |
| 61 | + .map(|layers| { |
| 62 | + let [layer_before, layer_after] = layers.unwrap_complete().into_array(); |
| 63 | + let is_group_input_sep = ir.walk_ops_with(layer_before.walker()).all(|op| { |
| 64 | + matches!( |
| 65 | + op.get_instruction(), |
| 66 | + LayoutInstructionSet::GroupInput { .. } |
| 67 | + ) |
| 68 | + }); |
| 69 | + let is_group_output_sep = ir.walk_ops_with(layer_after.walker()).all(|op| { |
| 70 | + matches!( |
| 71 | + op.get_instruction(), |
| 72 | + LayoutInstructionSet::GroupOutput { .. } |
| 73 | + ) |
| 74 | + }); |
| 75 | + let width_before = layer_before.walker().count() as f64; |
| 76 | + let width_after = layer_after.walker().count() as f64; |
| 77 | + let traffic = ir |
| 78 | + .walk_ops_with(layer_after.walker()) |
| 79 | + .map(|op| op.get_args_arity()) |
| 80 | + .sum::<usize>() as f64; |
| 81 | + let width_min = min_by(width_before, width_after, |a, b| a.partial_cmp(b).unwrap()); |
| 82 | + let width_max = max_by(width_before, width_after, |a, b| a.partial_cmp(b).unwrap()); |
| 83 | + let spread = (width_max/width_min.max(1.)).max(1.).sqrt(); |
| 84 | + let sep_height = if is_group_input_sep | is_group_output_sep { |
| 85 | + Height::new(0.) |
| 86 | + } else { |
| 87 | + Height::new(20.0 + 10.0 * traffic * spread ) |
| 88 | + }; |
| 89 | + LayerMemberSeparator(LayerSeparator::vertical(sep_height)) |
| 90 | + }), |
| 91 | + ) |
| 92 | + .collect(); |
62 | 93 | ( |
63 | 94 | Layers::new(variables), |
64 | 95 | AnnIR::new(ir.ir, opmap, ir.filled_valmap(())), |
@@ -222,10 +253,16 @@ fn gen_group_node<'ir, 'ann>( |
222 | 253 |
|
223 | 254 | for op in ir.walk_ops_linear() { |
224 | 255 | match (op.get_instruction(), op.get_annotation()) { |
225 | | - (LayoutInstructionSet::GroupInput { .. }, PlacementSolution::NonGroup { op: lp }) => { |
| 256 | + ( |
| 257 | + LayoutInstructionSet::GroupInput { .. }, |
| 258 | + PlacementSolution::NonGroup { op: lp, .. }, |
| 259 | + ) => { |
226 | 260 | group_inputs.push((*lp, op.get_id())); |
227 | 261 | } |
228 | | - (LayoutInstructionSet::GroupOutput { .. }, PlacementSolution::NonGroup { op: lp }) => { |
| 262 | + ( |
| 263 | + LayoutInstructionSet::GroupOutput { .. }, |
| 264 | + PlacementSolution::NonGroup { op: lp, .. }, |
| 265 | + ) => { |
229 | 266 | group_outputs.push((*lp, op.get_id())); |
230 | 267 | } |
231 | 268 | _ => {} |
|
0 commit comments