use super::*;
use crate::IR;
use crate::testlang::{TestInstructionSet, TestLang};
use crate::visualization::Hierarchy;
use crate::visualization::composition::{NoClass, StyleModifier, TextBox};
use zhc_utils::graphics::ColorScale;
use zhc_utils::svec;
const PREFIX: &'static str = "";
#[test]
fn test_flat_hierarchy() {
let mut ir: IR<TestLang> = IR::empty();
let (_, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (_, inc) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
ir.add_op(TestInstructionSet::Return, svec![inc[0]]);
let root = Hierarchy::new();
let op_annotations = ir.filled_opmap(root);
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test1.html"));
}
#[test]
fn test_nested_hierarchy() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inc1[0]]);
let (op3, _) = ir.add_op(TestInstructionSet::Return, svec![inc2[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_a.clone());
op_annotations.insert(op2, group_a.clone());
op_annotations.insert(op3, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test2.html"));
}
#[test]
fn test_sibling_groups() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp0) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inp1) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (op2, add) = ir.add_op(TestInstructionSet::Add, svec![inp0[0], inp1[0]]);
let (op3, inc) = ir.add_op(TestInstructionSet::Inc, svec![add[0]]);
let (op4, _) = ir.add_op(TestInstructionSet::Return, svec![inc[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut group_b = root.clone();
group_b.push("group_b");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, root.clone());
op_annotations.insert(op2, group_a.clone());
op_annotations.insert(op3, group_b.clone());
op_annotations.insert(op4, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test3.html"));
}
#[test]
fn test_deep_nesting() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inc1[0]]);
let (op3, _) = ir.add_op(TestInstructionSet::Return, svec![inc2[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut group_ab = group_a.clone();
group_ab.push("group_b");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_a.clone());
op_annotations.insert(op2, group_ab.clone());
op_annotations.insert(op3, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test4.html"));
}
#[test]
fn test_operations_along_group() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inc1[0]]);
let (op3, inc3) = ir.add_op(TestInstructionSet::Inc, svec![inc2[0]]);
let (op4, _) = ir.add_op(TestInstructionSet::Return, svec![inc3[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_a.clone());
op_annotations.insert(op2, root.clone());
op_annotations.insert(op3, group_a.clone());
op_annotations.insert(op4, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test5.html"));
}
#[test]
fn test_diamond_different_slacks() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inc1[0]]);
let (op3, inc3) = ir.add_op(TestInstructionSet::Inc, svec![inc2[0]]);
let (op4, inc4) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op5, add) = ir.add_op(TestInstructionSet::Add, svec![inc3[0], inc4[0]]);
let (op6, _) = ir.add_op(TestInstructionSet::Return, svec![add[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_a.clone());
op_annotations.insert(op2, group_a.clone());
op_annotations.insert(op3, group_a.clone());
op_annotations.insert(op4, root.clone());
op_annotations.insert(op5, root.clone());
op_annotations.insert(op6, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test6.html"));
}
#[test]
fn test_asymmetric_slack_nested() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inc1[0]]);
let (op3, inc3) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op4, add) = ir.add_op(TestInstructionSet::Add, svec![inc2[0], inc3[0]]);
let (op5, _) = ir.add_op(TestInstructionSet::Return, svec![add[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut group_ab = group_a.clone();
group_ab.push("group_b");
let mut group_c = root.clone();
group_c.push("group_c");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_ab.clone());
op_annotations.insert(op2, group_ab.clone());
op_annotations.insert(op3, group_c.clone());
op_annotations.insert(op4, root.clone());
op_annotations.insert(op5, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test7.html"));
}
#[test]
fn test_deep_entry_slow_exit() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inc1[0]]);
let (op3, inc3) = ir.add_op(TestInstructionSet::Inc, svec![inc2[0]]);
let (op4, _) = ir.add_op(TestInstructionSet::Return, svec![inc3[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("a");
let mut group_ab = group_a.clone();
group_ab.push("b");
let mut group_abc = group_ab.clone();
group_abc.push("c");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_abc.clone());
op_annotations.insert(op2, group_ab.clone());
op_annotations.insert(op3, group_a.clone());
op_annotations.insert(op4, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test8.html"));
}
#[test]
fn test_slow_entry_deep_exit() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inc1[0]]);
let (op3, inc3) = ir.add_op(TestInstructionSet::Inc, svec![inc2[0]]);
let (op4, _) = ir.add_op(TestInstructionSet::Return, svec![inc3[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("a");
let mut group_ab = group_a.clone();
group_ab.push("b");
let mut group_abc = group_ab.clone();
group_abc.push("c");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_a.clone());
op_annotations.insert(op2, group_ab.clone());
op_annotations.insert(op3, group_abc.clone());
op_annotations.insert(op4, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test9.html"));
}
#[test]
fn test_immediate_deep_entry_exit() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, _) = ir.add_op(TestInstructionSet::Return, svec![inc[0]]);
let root = Hierarchy::new();
let mut group_abc = root.clone();
group_abc.push("a");
group_abc.push("b");
group_abc.push("c");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_abc.clone());
op_annotations.insert(op2, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test10.html"));
}
#[test]
fn test_deep_oscillation() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inc1[0]]);
let (op3, inc3) = ir.add_op(TestInstructionSet::Inc, svec![inc2[0]]);
let (op4, _) = ir.add_op(TestInstructionSet::Return, svec![inc3[0]]);
let root = Hierarchy::new();
let mut group_abc = root.clone();
group_abc.push("a");
group_abc.push("b");
group_abc.push("c");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, group_abc.clone());
op_annotations.insert(op1, group_abc.clone());
op_annotations.insert(op2, root.clone());
op_annotations.insert(op3, group_abc.clone());
op_annotations.insert(op4, group_abc.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test11.html"));
}
#[test]
fn test_fanout_varied_depths() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op3, inc3) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op4, add1) = ir.add_op(TestInstructionSet::Add, svec![inc1[0], inc2[0]]);
let (op5, add2) = ir.add_op(TestInstructionSet::Add, svec![add1[0], inc3[0]]);
let (op6, _) = ir.add_op(TestInstructionSet::Return, svec![add2[0]]);
let root = Hierarchy::new();
let mut group_ab = root.clone();
group_ab.push("a");
group_ab.push("b");
let mut group_c = root.clone();
group_c.push("c");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_ab.clone());
op_annotations.insert(op2, group_c.clone());
op_annotations.insert(op3, root.clone());
op_annotations.insert(op4, root.clone());
op_annotations.insert(op5, root.clone());
op_annotations.insert(op6, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test12.html"));
}
#[test]
fn test_slack_gradient_0_to_5() {
let mut ir: IR<TestLang> = IR::empty();
let (inp_id, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (p6_1_id, p6_1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (p6_2_id, p6_2) = ir.add_op(TestInstructionSet::Inc, svec![p6_1[0]]);
let (p6_3_id, p6_3) = ir.add_op(TestInstructionSet::Inc, svec![p6_2[0]]);
let (p6_4_id, p6_4) = ir.add_op(TestInstructionSet::Inc, svec![p6_3[0]]);
let (p6_5_id, p6_5) = ir.add_op(TestInstructionSet::Inc, svec![p6_4[0]]);
let (p6_6_id, p6_6) = ir.add_op(TestInstructionSet::Inc, svec![p6_5[0]]);
let (p5_1_id, p5_1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (p5_2_id, p5_2) = ir.add_op(TestInstructionSet::Inc, svec![p5_1[0]]);
let (p5_3_id, p5_3) = ir.add_op(TestInstructionSet::Inc, svec![p5_2[0]]);
let (p5_4_id, p5_4) = ir.add_op(TestInstructionSet::Inc, svec![p5_3[0]]);
let (p5_5_id, p5_5) = ir.add_op(TestInstructionSet::Inc, svec![p5_4[0]]);
let (p4_1_id, p4_1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (p4_2_id, p4_2) = ir.add_op(TestInstructionSet::Inc, svec![p4_1[0]]);
let (p4_3_id, p4_3) = ir.add_op(TestInstructionSet::Inc, svec![p4_2[0]]);
let (p4_4_id, p4_4) = ir.add_op(TestInstructionSet::Inc, svec![p4_3[0]]);
let (p3_1_id, p3_1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (p3_2_id, p3_2) = ir.add_op(TestInstructionSet::Inc, svec![p3_1[0]]);
let (p3_3_id, p3_3) = ir.add_op(TestInstructionSet::Inc, svec![p3_2[0]]);
let (p2_1_id, p2_1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (p2_2_id, p2_2) = ir.add_op(TestInstructionSet::Inc, svec![p2_1[0]]);
let (p1_1_id, p1_1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (add1_id, add1) = ir.add_op(TestInstructionSet::Add, svec![p6_6[0], p5_5[0]]);
let (add2_id, add2) = ir.add_op(TestInstructionSet::Add, svec![add1[0], p4_4[0]]);
let (add3_id, add3) = ir.add_op(TestInstructionSet::Add, svec![add2[0], p3_3[0]]);
let (add4_id, add4) = ir.add_op(TestInstructionSet::Add, svec![add3[0], p2_2[0]]);
let (add5_id, add5) = ir.add_op(TestInstructionSet::Add, svec![add4[0], p1_1[0]]);
let (ret_id, _) = ir.add_op(TestInstructionSet::Return, svec![add5[0]]);
let root = Hierarchy::new();
let mut g6 = root.clone();
g6.push("p6");
let mut g5 = root.clone();
g5.push("p5");
let mut g4 = root.clone();
g4.push("p4");
let mut g3 = root.clone();
g3.push("p3");
let mut g2 = root.clone();
g2.push("p2");
let mut g1 = root.clone();
g1.push("p1");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(inp_id, root.clone());
op_annotations.insert(p6_1_id, g6.clone());
op_annotations.insert(p6_2_id, g6.clone());
op_annotations.insert(p6_3_id, g6.clone());
op_annotations.insert(p6_4_id, g6.clone());
op_annotations.insert(p6_5_id, g6.clone());
op_annotations.insert(p6_6_id, g6.clone());
op_annotations.insert(p5_1_id, g5.clone());
op_annotations.insert(p5_2_id, g5.clone());
op_annotations.insert(p5_3_id, g5.clone());
op_annotations.insert(p5_4_id, g5.clone());
op_annotations.insert(p5_5_id, g5.clone());
op_annotations.insert(p4_1_id, g4.clone());
op_annotations.insert(p4_2_id, g4.clone());
op_annotations.insert(p4_3_id, g4.clone());
op_annotations.insert(p4_4_id, g4.clone());
op_annotations.insert(p3_1_id, g3.clone());
op_annotations.insert(p3_2_id, g3.clone());
op_annotations.insert(p3_3_id, g3.clone());
op_annotations.insert(p2_1_id, g2.clone());
op_annotations.insert(p2_2_id, g2.clone());
op_annotations.insert(p1_1_id, g1.clone());
op_annotations.insert(add1_id, root.clone());
op_annotations.insert(add2_id, root.clone());
op_annotations.insert(add3_id, root.clone());
op_annotations.insert(add4_id, root.clone());
op_annotations.insert(add5_id, root.clone());
op_annotations.insert(ret_id, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test13.html"));
}
#[test]
fn test_multireturn_different_depths() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp0) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inp1) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (op2, divrem) = ir.add_op(TestInstructionSet::DivRem, svec![inp0[0], inp1[0]]);
let (op3, inc1) = ir.add_op(TestInstructionSet::Inc, svec![divrem[0]]); let (op4, inc2) = ir.add_op(TestInstructionSet::Inc, svec![divrem[1]]); let (op5, add) = ir.add_op(TestInstructionSet::Add, svec![inc1[0], inc2[0]]);
let (op6, _) = ir.add_op(TestInstructionSet::Return, svec![add[0]]);
let root = Hierarchy::new();
let mut group_ab = root.clone();
group_ab.push("a");
group_ab.push("b");
let mut group_c = root.clone();
group_c.push("c");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, root.clone());
op_annotations.insert(op2, root.clone());
op_annotations.insert(op3, group_ab.clone()); op_annotations.insert(op4, group_c.clone()); op_annotations.insert(op5, root.clone());
op_annotations.insert(op6, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test14.html"));
}
#[test]
fn test_multi_input_to_group() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp0) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inp1) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (op2, inp2) = ir.add_op(TestInstructionSet::IntInput { pos: 2 }, svec![]);
let (op3, add1) = ir.add_op(TestInstructionSet::Add, svec![inp0[0], inp1[0]]);
let (op4, add2) = ir.add_op(TestInstructionSet::Add, svec![add1[0], inp2[0]]);
let (op5, _) = ir.add_op(TestInstructionSet::Return, svec![add2[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, root.clone());
op_annotations.insert(op2, root.clone());
op_annotations.insert(op3, group_a.clone());
op_annotations.insert(op4, group_a.clone());
op_annotations.insert(op5, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test15.html"));
}
#[test]
fn test_multi_output_from_group() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op3, inc3) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op4, add1) = ir.add_op(TestInstructionSet::Add, svec![inc1[0], inc2[0]]);
let (op5, add2) = ir.add_op(TestInstructionSet::Add, svec![add1[0], inc3[0]]);
let (op6, _) = ir.add_op(TestInstructionSet::Return, svec![add2[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_a.clone());
op_annotations.insert(op2, group_a.clone());
op_annotations.insert(op3, group_a.clone());
op_annotations.insert(op4, root.clone());
op_annotations.insert(op5, root.clone());
op_annotations.insert(op6, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test16.html"));
}
#[test]
fn test_multi_io_group() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp0) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inp1) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (op2, add) = ir.add_op(TestInstructionSet::Add, svec![inp0[0], inp1[0]]);
let (op3, inc) = ir.add_op(TestInstructionSet::Inc, svec![inp0[0]]);
let (op4, add2) = ir.add_op(TestInstructionSet::Add, svec![add[0], inc[0]]);
let (op5, inc2) = ir.add_op(TestInstructionSet::Inc, svec![add[0]]);
let (op6, add3) = ir.add_op(TestInstructionSet::Add, svec![add2[0], inc2[0]]);
let (op7, _) = ir.add_op(TestInstructionSet::Return, svec![add3[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, root.clone());
op_annotations.insert(op2, group_a.clone());
op_annotations.insert(op3, group_a.clone());
op_annotations.insert(op4, root.clone());
op_annotations.insert(op5, root.clone());
op_annotations.insert(op6, root.clone());
op_annotations.insert(op7, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test17.html"));
}
#[test]
fn test_big_subgraph_diamond() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inc1[0]]);
let (op3, inc3) = ir.add_op(TestInstructionSet::Inc, svec![inc2[0]]);
let (op4, inc4) = ir.add_op(TestInstructionSet::Inc, svec![inc1[0]]);
let (op5, inc5) = ir.add_op(TestInstructionSet::Inc, svec![inc4[0]]);
let (op6, add) = ir.add_op(TestInstructionSet::Add, svec![inc3[0], inc5[0]]);
let (op7, _) = ir.add_op(TestInstructionSet::Return, svec![add[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_a.clone());
op_annotations.insert(op2, group_a.clone());
op_annotations.insert(op3, group_a.clone());
op_annotations.insert(op4, group_a.clone());
op_annotations.insert(op5, group_a.clone());
op_annotations.insert(op6, group_a.clone());
op_annotations.insert(op7, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test18.html"));
}
#[test]
fn test_long_chain_in_nested_group() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, v1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, v2) = ir.add_op(TestInstructionSet::Inc, svec![v1[0]]);
let (op3, v3) = ir.add_op(TestInstructionSet::Inc, svec![v2[0]]);
let (op4, v4) = ir.add_op(TestInstructionSet::Inc, svec![v3[0]]);
let (op5, v5) = ir.add_op(TestInstructionSet::Inc, svec![v4[0]]);
let (op6, v6) = ir.add_op(TestInstructionSet::Inc, svec![v5[0]]);
let (op7, v7) = ir.add_op(TestInstructionSet::Inc, svec![v6[0]]);
let (op8, v8) = ir.add_op(TestInstructionSet::Inc, svec![v7[0]]);
let (op9, _) = ir.add_op(TestInstructionSet::Return, svec![v8[0]]);
let root = Hierarchy::new();
let mut group_ab = root.clone();
group_ab.push("a");
group_ab.push("b");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_ab.clone());
op_annotations.insert(op2, group_ab.clone());
op_annotations.insert(op3, group_ab.clone());
op_annotations.insert(op4, group_ab.clone());
op_annotations.insert(op5, group_ab.clone());
op_annotations.insert(op6, group_ab.clone());
op_annotations.insert(op7, group_ab.clone());
op_annotations.insert(op8, group_ab.clone());
op_annotations.insert(op9, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test19.html"));
}
#[test]
fn test_cross_group_multi_edge() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp0) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inp1) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (op2, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp0[0]]);
let (op3, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inp1[0]]);
let (op4, add1) = ir.add_op(TestInstructionSet::Add, svec![inc1[0], inc2[0]]);
let (op5, add2) = ir.add_op(TestInstructionSet::Add, svec![inc1[0], inc2[0]]);
let (op6, add3) = ir.add_op(TestInstructionSet::Add, svec![add1[0], add2[0]]);
let (op7, _) = ir.add_op(TestInstructionSet::Return, svec![add3[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut group_b = root.clone();
group_b.push("group_b");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, root.clone());
op_annotations.insert(op2, group_a.clone());
op_annotations.insert(op3, group_b.clone());
op_annotations.insert(op4, group_b.clone());
op_annotations.insert(op5, group_a.clone());
op_annotations.insert(op6, root.clone());
op_annotations.insert(op7, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test20.html"));
}
#[test]
fn test_multi_input_nested_depths() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp0) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inp1) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (op2, inp2) = ir.add_op(TestInstructionSet::IntInput { pos: 2 }, svec![]);
let (op3, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp0[0]]);
let (op4, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inp1[0]]);
let (op5, add1) = ir.add_op(TestInstructionSet::Add, svec![inc1[0], inc2[0]]);
let (op6, add2) = ir.add_op(TestInstructionSet::Add, svec![add1[0], inp2[0]]);
let (op7, _) = ir.add_op(TestInstructionSet::Return, svec![add2[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("a");
let mut group_ab = group_a.clone();
group_ab.push("b");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, root.clone());
op_annotations.insert(op2, root.clone());
op_annotations.insert(op3, group_a.clone());
op_annotations.insert(op4, group_ab.clone());
op_annotations.insert(op5, group_ab.clone());
op_annotations.insert(op6, group_ab.clone());
op_annotations.insert(op7, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test21.html"));
}
#[test]
fn test_group_internal_fanout() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inc1[0]]);
let (op3, inc3) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op4, inc4) = ir.add_op(TestInstructionSet::Inc, svec![inc3[0]]);
let (op5, inc5) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op6, inc6) = ir.add_op(TestInstructionSet::Inc, svec![inc5[0]]);
let (op7, add1) = ir.add_op(TestInstructionSet::Add, svec![inc2[0], inc4[0]]);
let (op8, add2) = ir.add_op(TestInstructionSet::Add, svec![add1[0], inc6[0]]);
let (op9, _) = ir.add_op(TestInstructionSet::Return, svec![add2[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_a.clone());
op_annotations.insert(op2, group_a.clone());
op_annotations.insert(op3, group_a.clone());
op_annotations.insert(op4, group_a.clone());
op_annotations.insert(op5, group_a.clone());
op_annotations.insert(op6, group_a.clone());
op_annotations.insert(op7, root.clone());
op_annotations.insert(op8, root.clone());
op_annotations.insert(op9, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test22.html"));
}
#[test]
fn test_sequential_diamonds_in_groups() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, a1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, a2) = ir.add_op(TestInstructionSet::Inc, svec![a1[0]]);
let (op3, a3) = ir.add_op(TestInstructionSet::Inc, svec![a1[0]]);
let (op4, a4) = ir.add_op(TestInstructionSet::Add, svec![a2[0], a3[0]]);
let (op5, b1) = ir.add_op(TestInstructionSet::Inc, svec![a4[0]]);
let (op6, b2) = ir.add_op(TestInstructionSet::Inc, svec![b1[0]]);
let (op7, b3) = ir.add_op(TestInstructionSet::Inc, svec![b1[0]]);
let (op8, b4) = ir.add_op(TestInstructionSet::Add, svec![b2[0], b3[0]]);
let (op9, _) = ir.add_op(TestInstructionSet::Return, svec![b4[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut group_b = root.clone();
group_b.push("group_b");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_a.clone());
op_annotations.insert(op2, group_a.clone());
op_annotations.insert(op3, group_a.clone());
op_annotations.insert(op4, group_a.clone());
op_annotations.insert(op5, group_b.clone());
op_annotations.insert(op6, group_b.clone());
op_annotations.insert(op7, group_b.clone());
op_annotations.insert(op8, group_b.clone());
op_annotations.insert(op9, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test23.html"));
}
#[test]
fn test_wide_io_deep_group() {
let mut ir: IR<TestLang> = IR::empty();
let (i0, inp0) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (i1, inp1) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (i2, inp2) = ir.add_op(TestInstructionSet::IntInput { pos: 2 }, svec![]);
let (i3, inp3) = ir.add_op(TestInstructionSet::IntInput { pos: 3 }, svec![]);
let (i4, inp4) = ir.add_op(TestInstructionSet::IntInput { pos: 4 }, svec![]);
let (g0, v0) = ir.add_op(TestInstructionSet::Inc, svec![inp0[0]]);
let (g1, v1) = ir.add_op(TestInstructionSet::Inc, svec![inp1[0]]);
let (g2, v2) = ir.add_op(TestInstructionSet::Inc, svec![inp2[0]]);
let (g3, v3) = ir.add_op(TestInstructionSet::Inc, svec![inp3[0]]);
let (g4, v4) = ir.add_op(TestInstructionSet::Inc, svec![inp4[0]]);
let (c0, w0) = ir.add_op(TestInstructionSet::Add, svec![v0[0], v1[0]]);
let (c1, w1) = ir.add_op(TestInstructionSet::Add, svec![w0[0], v2[0]]);
let (c2, w2) = ir.add_op(TestInstructionSet::Add, svec![w1[0], v3[0]]);
let (c3, w3) = ir.add_op(TestInstructionSet::Add, svec![w2[0], v4[0]]);
let (r, _) = ir.add_op(TestInstructionSet::Return, svec![w3[0]]);
let root = Hierarchy::new();
let mut group_abc = root.clone();
group_abc.push("a");
group_abc.push("b");
group_abc.push("c");
let mut op_annotations = ir.empty_opmap();
for id in [i0, i1, i2, i3, i4] {
op_annotations.insert(id, root.clone());
}
for id in [g0, g1, g2, g3, g4] {
op_annotations.insert(id, group_abc.clone());
}
for id in [c0, c1, c2, c3, r] {
op_annotations.insert(id, root.clone());
}
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test24.html"));
}
#[test]
fn test_crossing_two_parallel() {
let mut ir: IR<TestLang> = IR::empty();
let (b, vb) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (a, va) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (d, vd) = ir.add_op(TestInstructionSet::Inc, svec![vb[0]]);
let (c, vc) = ir.add_op(TestInstructionSet::Inc, svec![va[0]]);
let (e, ve) = ir.add_op(TestInstructionSet::Add, svec![vc[0], vd[0]]);
let (r, _) = ir.add_op(TestInstructionSet::Return, svec![ve[0]]);
let root = Hierarchy::new();
let mut op_annotations = ir.empty_opmap();
for id in [a, b, c, d, e, r] {
op_annotations.insert(id, root.clone());
}
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test25.html"));
}
#[test]
fn test_bipartite_k33() {
let mut ir: IR<TestLang> = IR::empty();
let (a, va) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (b, vb) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (c, vc) = ir.add_op(TestInstructionSet::IntInput { pos: 2 }, svec![]);
let (d, vd) = ir.add_op(TestInstructionSet::Add, svec![va[0], vb[0]]);
let (d2, vd2) = ir.add_op(TestInstructionSet::Add, svec![vd[0], vc[0]]);
let (e, ve) = ir.add_op(TestInstructionSet::Add, svec![vb[0], vc[0]]);
let (e2, ve2) = ir.add_op(TestInstructionSet::Add, svec![ve[0], va[0]]);
let (f, vf) = ir.add_op(TestInstructionSet::Add, svec![vc[0], va[0]]);
let (f2, vf2) = ir.add_op(TestInstructionSet::Add, svec![vf[0], vb[0]]);
let (g, vg) = ir.add_op(TestInstructionSet::Add, svec![vd2[0], ve2[0]]);
let (h, vh) = ir.add_op(TestInstructionSet::Add, svec![vg[0], vf2[0]]);
let (r, _) = ir.add_op(TestInstructionSet::Return, svec![vh[0]]);
let root = Hierarchy::new();
let mut op_annotations = ir.empty_opmap();
for id in [a, b, c, d, d2, e, e2, f, f2, g, h, r] {
op_annotations.insert(id, root.clone());
}
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test26.html"));
}
#[test]
fn test_fanout_reversed_fanin() {
let mut ir: IR<TestLang> = IR::empty();
let (inp, v) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (a, va) = ir.add_op(TestInstructionSet::Inc, svec![v[0]]);
let (b, vb) = ir.add_op(TestInstructionSet::Inc, svec![v[0]]);
let (c, vc) = ir.add_op(TestInstructionSet::Inc, svec![v[0]]);
let (d, vd) = ir.add_op(TestInstructionSet::Inc, svec![v[0]]);
let (w, vw) = ir.add_op(TestInstructionSet::Inc, svec![vd[0]]);
let (x, vx) = ir.add_op(TestInstructionSet::Inc, svec![vc[0]]);
let (y, vy) = ir.add_op(TestInstructionSet::Inc, svec![vb[0]]);
let (z, vz) = ir.add_op(TestInstructionSet::Inc, svec![va[0]]);
let (m1, vm1) = ir.add_op(TestInstructionSet::Add, svec![vw[0], vx[0]]);
let (m2, vm2) = ir.add_op(TestInstructionSet::Add, svec![vy[0], vz[0]]);
let (m3, vm3) = ir.add_op(TestInstructionSet::Add, svec![vm1[0], vm2[0]]);
let (r, _) = ir.add_op(TestInstructionSet::Return, svec![vm3[0]]);
let root = Hierarchy::new();
let mut op_annotations = ir.empty_opmap();
for id in [inp, a, b, c, d, w, x, y, z, m1, m2, m3, r] {
op_annotations.insert(id, root.clone());
}
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test27.html"));
}
#[test]
fn test_ladder_alternating() {
let mut ir: IR<TestLang> = IR::empty();
let (a0, va0) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (b0, vb0) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (a1, va1) = ir.add_op(TestInstructionSet::Inc, svec![vb0[0]]);
let (b1, vb1) = ir.add_op(TestInstructionSet::Inc, svec![va0[0]]);
let (a2, va2) = ir.add_op(TestInstructionSet::Inc, svec![vb1[0]]);
let (b2, vb2) = ir.add_op(TestInstructionSet::Inc, svec![va1[0]]);
let (a3, va3) = ir.add_op(TestInstructionSet::Inc, svec![vb2[0]]);
let (b3, vb3) = ir.add_op(TestInstructionSet::Inc, svec![va2[0]]);
let (m, vm) = ir.add_op(TestInstructionSet::Add, svec![va3[0], vb3[0]]);
let (r, _) = ir.add_op(TestInstructionSet::Return, svec![vm[0]]);
let root = Hierarchy::new();
let mut op_annotations = ir.empty_opmap();
for id in [a0, b0, a1, b1, a2, b2, a3, b3, m, r] {
op_annotations.insert(id, root.clone());
}
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test28.html"));
}
#[test]
fn test_permuted_chains() {
let mut ir: IR<TestLang> = IR::empty();
let (i0, v0) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (i1, v1) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (i2, v2) = ir.add_op(TestInstructionSet::IntInput { pos: 2 }, svec![]);
let (i3, v3) = ir.add_op(TestInstructionSet::IntInput { pos: 3 }, svec![]);
let (a2, va2) = ir.add_op(TestInstructionSet::Inc, svec![v2[0]]);
let (a0, va0) = ir.add_op(TestInstructionSet::Inc, svec![v0[0]]);
let (a3, va3) = ir.add_op(TestInstructionSet::Inc, svec![v3[0]]);
let (a1, va1) = ir.add_op(TestInstructionSet::Inc, svec![v1[0]]);
let (b1, vb1) = ir.add_op(TestInstructionSet::Inc, svec![va1[0]]);
let (b3, vb3) = ir.add_op(TestInstructionSet::Inc, svec![va3[0]]);
let (b0, vb0) = ir.add_op(TestInstructionSet::Inc, svec![va0[0]]);
let (b2, vb2) = ir.add_op(TestInstructionSet::Inc, svec![va2[0]]);
let (m1, vm1) = ir.add_op(TestInstructionSet::Add, svec![vb0[0], vb1[0]]);
let (m2, vm2) = ir.add_op(TestInstructionSet::Add, svec![vb2[0], vb3[0]]);
let (m3, vm3) = ir.add_op(TestInstructionSet::Add, svec![vm1[0], vm2[0]]);
let (r, _) = ir.add_op(TestInstructionSet::Return, svec![vm3[0]]);
let root = Hierarchy::new();
let mut op_annotations = ir.empty_opmap();
for id in [
i0, i1, i2, i3, a0, a1, a2, a3, b0, b1, b2, b3, m1, m2, m3, r,
] {
op_annotations.insert(id, root.clone());
}
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test29.html"));
}
#[test]
fn test_shared_intermediate_multi_sink() {
let mut ir: IR<TestLang> = IR::empty();
let (inp, v) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (mid, vm) = ir.add_op(TestInstructionSet::Inc, svec![v[0]]);
let (s2, vs2) = ir.add_op(TestInstructionSet::Inc, svec![vm[0]]);
let (s0, vs0) = ir.add_op(TestInstructionSet::Inc, svec![vm[0]]);
let (s1, vs1) = ir.add_op(TestInstructionSet::Inc, svec![vm[0]]);
let (t0, vt0) = ir.add_op(TestInstructionSet::Add, svec![v[0], vs0[0]]);
let (t1, vt1) = ir.add_op(TestInstructionSet::Add, svec![v[0], vs1[0]]);
let (t2, vt2) = ir.add_op(TestInstructionSet::Add, svec![v[0], vs2[0]]);
let (c1, vc1) = ir.add_op(TestInstructionSet::Add, svec![vt0[0], vt1[0]]);
let (c2, vc2) = ir.add_op(TestInstructionSet::Add, svec![vc1[0], vt2[0]]);
let (r, _) = ir.add_op(TestInstructionSet::Return, svec![vc2[0]]);
let root = Hierarchy::new();
let mut op_annotations = ir.empty_opmap();
for id in [inp, mid, s0, s1, s2, t0, t1, t2, c1, c2, r] {
op_annotations.insert(id, root.clone());
}
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test30.html"));
}
#[test]
fn test_butterfly_wide() {
let mut ir: IR<TestLang> = IR::empty();
let (i0, v0) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (i1, v1) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (i2, v2) = ir.add_op(TestInstructionSet::IntInput { pos: 2 }, svec![]);
let (i3, v3) = ir.add_op(TestInstructionSet::IntInput { pos: 3 }, svec![]);
let (i4, v4) = ir.add_op(TestInstructionSet::IntInput { pos: 4 }, svec![]);
let (i5, v5) = ir.add_op(TestInstructionSet::IntInput { pos: 5 }, svec![]);
let (i6, v6) = ir.add_op(TestInstructionSet::IntInput { pos: 6 }, svec![]);
let (i7, v7) = ir.add_op(TestInstructionSet::IntInput { pos: 7 }, svec![]);
let (a0, va0) = ir.add_op(TestInstructionSet::Add, svec![v0[0], v1[0]]);
let (a1, va1) = ir.add_op(TestInstructionSet::Add, svec![v1[0], v0[0]]);
let (a2, va2) = ir.add_op(TestInstructionSet::Add, svec![v2[0], v3[0]]);
let (a3, va3) = ir.add_op(TestInstructionSet::Add, svec![v3[0], v2[0]]);
let (a4, va4) = ir.add_op(TestInstructionSet::Add, svec![v4[0], v5[0]]);
let (a5, va5) = ir.add_op(TestInstructionSet::Add, svec![v5[0], v4[0]]);
let (a6, va6) = ir.add_op(TestInstructionSet::Add, svec![v6[0], v7[0]]);
let (a7, va7) = ir.add_op(TestInstructionSet::Add, svec![v7[0], v6[0]]);
let (b0, vb0) = ir.add_op(TestInstructionSet::Add, svec![va0[0], va2[0]]);
let (b1, vb1) = ir.add_op(TestInstructionSet::Add, svec![va1[0], va3[0]]);
let (b2, vb2) = ir.add_op(TestInstructionSet::Add, svec![va2[0], va0[0]]);
let (b3, vb3) = ir.add_op(TestInstructionSet::Add, svec![va3[0], va1[0]]);
let (b4, vb4) = ir.add_op(TestInstructionSet::Add, svec![va4[0], va6[0]]);
let (b5, vb5) = ir.add_op(TestInstructionSet::Add, svec![va5[0], va7[0]]);
let (b6, vb6) = ir.add_op(TestInstructionSet::Add, svec![va6[0], va4[0]]);
let (b7, vb7) = ir.add_op(TestInstructionSet::Add, svec![va7[0], va5[0]]);
let (c0, vc0) = ir.add_op(TestInstructionSet::Add, svec![vb0[0], vb1[0]]);
let (c1, vc1) = ir.add_op(TestInstructionSet::Add, svec![vb2[0], vb3[0]]);
let (c2, vc2) = ir.add_op(TestInstructionSet::Add, svec![vb4[0], vb5[0]]);
let (c3, vc3) = ir.add_op(TestInstructionSet::Add, svec![vb6[0], vb7[0]]);
let (d0, vd0) = ir.add_op(TestInstructionSet::Add, svec![vc0[0], vc1[0]]);
let (d1, vd1) = ir.add_op(TestInstructionSet::Add, svec![vc2[0], vc3[0]]);
let (e, ve) = ir.add_op(TestInstructionSet::Add, svec![vd0[0], vd1[0]]);
let (r, _) = ir.add_op(TestInstructionSet::Return, svec![ve[0]]);
let root = Hierarchy::new();
let mut op_annotations = ir.empty_opmap();
for id in [i0, i1, i2, i3, i4, i5, i6, i7] {
op_annotations.insert(id, root.clone());
}
for id in [a0, a1, a2, a3, a4, a5, a6, a7] {
op_annotations.insert(id, root.clone());
}
for id in [b0, b1, b2, b3, b4, b5, b6, b7] {
op_annotations.insert(id, root.clone());
}
for id in [c0, c1, c2, c3, d0, d1, e, r] {
op_annotations.insert(id, root.clone());
}
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test31.html"));
}
#[test]
fn test_crossing_in_group() {
let mut ir: IR<TestLang> = IR::empty();
let (i0, v0) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (i1, v1) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (a, va) = ir.add_op(TestInstructionSet::Inc, svec![v1[0]]);
let (b, vb) = ir.add_op(TestInstructionSet::Inc, svec![v0[0]]);
let (c, vc) = ir.add_op(TestInstructionSet::Inc, svec![vb[0]]);
let (d, vd) = ir.add_op(TestInstructionSet::Inc, svec![va[0]]);
let (m, vm) = ir.add_op(TestInstructionSet::Add, svec![vc[0], vd[0]]);
let (r, _) = ir.add_op(TestInstructionSet::Return, svec![vm[0]]);
let root = Hierarchy::new();
let mut group = root.clone();
group.push("inner");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(i0, root.clone());
op_annotations.insert(i1, root.clone());
for id in [a, b, c, d] {
op_annotations.insert(id, group.clone());
}
op_annotations.insert(m, root.clone());
op_annotations.insert(r, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test32.html"));
}
#[test]
fn test_cross_group_reorder() {
let mut ir: IR<TestLang> = IR::empty();
let (i0, v0) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (i1, v1) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (a, va) = ir.add_op(TestInstructionSet::Inc, svec![v1[0]]);
let (b, vb) = ir.add_op(TestInstructionSet::Inc, svec![v0[0]]);
let (m, vm) = ir.add_op(TestInstructionSet::Add, svec![va[0], vb[0]]);
let (r, _) = ir.add_op(TestInstructionSet::Return, svec![vm[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut group_b = root.clone();
group_b.push("group_b");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(i0, root.clone());
op_annotations.insert(i1, root.clone());
op_annotations.insert(a, group_a);
op_annotations.insert(b, group_b);
op_annotations.insert(m, root.clone());
op_annotations.insert(r, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test33.html"));
}
#[test]
fn test_mixed_first_layer_in_group() {
let mut ir: IR<TestLang> = IR::empty();
let (op_a, a) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op_b, b) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (op_c, c) = ir.add_op(TestInstructionSet::IntInput { pos: 2 }, svec![]); let (op_add1, add1) = ir.add_op(TestInstructionSet::Add, svec![c[0], b[0]]); let (op_add2, add2) = ir.add_op(TestInstructionSet::Add, svec![add1[0], a[0]]); let (op_ret, _) = ir.add_op(TestInstructionSet::Return, svec![add2[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op_a, root.clone());
op_annotations.insert(op_b, root.clone());
op_annotations.insert(op_c, group_a.clone()); op_annotations.insert(op_add1, group_a.clone());
op_annotations.insert(op_add2, group_a.clone());
op_annotations.insert(op_ret, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test34.html"));
}
#[test]
fn test_mixed_last_layer_in_group() {
let mut ir: IR<TestLang> = IR::empty();
let (op_inp0, inp0) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op_inp1, inp1) = ir.add_op(TestInstructionSet::IntInput { pos: 1 }, svec![]);
let (op_inc1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp0[0]]);
let (op_inc2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inp1[0]]);
let (op_internal_ret, _) = ir.add_op(TestInstructionSet::Return, svec![inc1[0]]);
let (op_ret, _) = ir.add_op(TestInstructionSet::Return, svec![inc2[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("group_a");
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op_inp0, root.clone());
op_annotations.insert(op_inp1, root.clone());
op_annotations.insert(op_inc1, group_a.clone());
op_annotations.insert(op_inc2, group_a.clone());
op_annotations.insert(op_internal_ret, group_a.clone());
op_annotations.insert(op_ret, root.clone());
draw_ir_to_html(&ir, Some(op_annotations), &format!("{PREFIX}test35.html"));
}
#[test]
fn test_ann_style_modifier() {
let mut ir: IR<TestLang> = IR::empty();
let (op0, inp) = ir.add_op(TestInstructionSet::IntInput { pos: 0 }, svec![]);
let (op1, inc1) = ir.add_op(TestInstructionSet::Inc, svec![inp[0]]);
let (op2, inc2) = ir.add_op(TestInstructionSet::Inc, svec![inc1[0]]);
let (op3, inc3) = ir.add_op(TestInstructionSet::Inc, svec![inc2[0]]);
let (op4, _) = ir.add_op(TestInstructionSet::Return, svec![inc3[0]]);
let root = Hierarchy::new();
let mut group_a = root.clone();
group_a.push("a");
let mut group_ab = group_a.clone();
group_ab.push("b");
let mut group_abc = group_ab.clone();
group_abc.push("c");
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
struct OpAnn(usize);
impl VisualAnnotation for OpAnn {
fn style_modifier(&self) -> Option<composition::StyleModifier> {
Some(StyleModifier {
fill_color: Some(ColorScale::TRAFFIC_LIGHT.interpolate(self.0 as f64 / 5.)),
..Default::default()
})
}
fn widget(&self) -> Option<Box<dyn composition::DynamicElement>> {
Some(Box::new(TextBox::<NoClass>::new(
None,
format!("{:?}", self),
)))
}
}
let mut op_annotations = ir.empty_opmap();
op_annotations.insert(op0, root.clone());
op_annotations.insert(op1, group_abc.clone());
op_annotations.insert(op2, group_ab.clone());
op_annotations.insert(op3, group_a.clone());
op_annotations.insert(op4, root.clone());
let ann_ir = ir.backward_dataflow_analysis(|op| {
if op.is_effect() {
(OpAnn(0), svec![(); op.get_return_arity()])
} else {
let max = op
.get_users_iter()
.map(|a| a.get_annotation().clone().unwrap_analyzed())
.max()
.unwrap();
(OpAnn(max.0 + 1), svec![(); op.get_return_arity()])
}
});
draw_ann_ir_to_html(
&ann_ir,
Some(op_annotations),
&format!("{PREFIX}test36.html"),
);
}