From ae3a1a9d9986839b39416ab4e1cb4ed4b12bd7a0 Mon Sep 17 00:00:00 2001 From: oflatt Date: Mon, 28 Oct 2024 17:00:04 -0700 Subject: [PATCH 01/11] better direct jump optimizer that is id-aware --- src/rvsdg/optimize_direct_jumps.rs | 127 +++++++++++++++++++++++++---- 1 file changed, 113 insertions(+), 14 deletions(-) diff --git a/src/rvsdg/optimize_direct_jumps.rs b/src/rvsdg/optimize_direct_jumps.rs index caeb493e..8cafe713 100644 --- a/src/rvsdg/optimize_direct_jumps.rs +++ b/src/rvsdg/optimize_direct_jumps.rs @@ -4,25 +4,113 @@ //! This is used by `to_cfg` to clean up //! the output. +use bril_rs::{Instruction, ValueOps}; use indexmap::IndexMap; use petgraph::{ graph::EdgeIndex, stable_graph::{NodeIndex, StableDiGraph, StableGraph}, - visit::{DfsPostOrder, EdgeRef}, + visit::{Bfs, DfsPostOrder, EdgeRef, IntoEdgeReferences}, Direction, }; -use crate::cfg::{BasicBlock, Branch, Simple, SimpleCfgFunction, SimpleCfgProgram}; +use crate::cfg::{Annotation, BasicBlock, Branch, Simple, SimpleCfgFunction, SimpleCfgProgram}; #[cfg(test)] use crate::Optimizer; impl SimpleCfgFunction { pub fn optimize_jumps(&self) -> Self { - self.fuse_down().collapse_empty_blocks() + // fusing down only needs to happen once + // fuze up may need to run until fixed point + // collapse empty blocks only need to happen once + self.fuse_down().fuze_up().fuze_up().collapse_empty_blocks() } - /// Find cases where a block jumps directly to another block A -> B where B + /// Finds blocks with only id instructions and fuses them with their parents + /// The parent must jump directly to the block + fn fuze_up(&self) -> SimpleCfgFunction { + let mut resulting_graph: StableGraph = StableDiGraph::new(); + + // maps nodes in the old graph to nodes in the new graph + // this is 1 to 1 for this optimization + let mut node_mapping: IndexMap = IndexMap::new(); + + let mut bfs = Bfs::new(&self.graph, self.entry); + + while let Some(node) = bfs.next(&self.graph) { + let incoming_to_node = self + .graph + .edges_directed(node, Direction::Incoming) + .collect::>(); + + // check if the optimization is applicable + let should_apply = self.graph[node].instrs.iter().all(|instr| { + matches!( + instr, + Instruction::Value { + op: ValueOps::Id, + .. + } + ) + }) && incoming_to_node.iter().all(|edge| { + let source = edge.source(); + let outgoing_from_source = self + .graph + .edges_directed(source, Direction::Outgoing) + .count(); + outgoing_from_source == 1 + }); + + if should_apply { + for parent_edge in incoming_to_node { + let parent = &node_mapping[&parent_edge.source()]; + if !resulting_graph[*parent] + .footer + .iter() + .any(|annotation| matches!(annotation, Annotation::AssignRet { .. })) + { + resulting_graph[*parent] + .instrs + .extend(self.graph[node].instrs.to_vec()); + } + resulting_graph[*parent] + .footer + .extend(self.graph[node].footer.to_vec()); + } + + // add a new node, but empty + let new_node = resulting_graph.add_node(BasicBlock { + name: self.graph[node].name.clone(), + instrs: vec![], + footer: vec![], + pos: None, + }); + node_mapping.insert(node, new_node); + } else { + // add the new node + let new_node = resulting_graph.add_node(self.graph[node].clone()); + node_mapping.insert(node, new_node); + }; + } + + for edge in self.graph.edge_references() { + let source = &node_mapping[&edge.source()]; + let target = &node_mapping[&edge.target()]; + resulting_graph.add_edge(*source, *target, edge.weight().clone()); + } + + SimpleCfgFunction { + name: self.name.clone(), + args: self.args.clone(), + graph: resulting_graph, + entry: node_mapping[&self.entry], + exit: node_mapping[&self.exit], + _phantom: Simple, + return_ty: self.return_ty.clone(), + } + } + + /// Find cases where a block jumps directly to another block A -> B where /// A has only one outgoing edge and B has one incoming edge /// Turn it into one block AB fn fuse_down(&self) -> SimpleCfgFunction { @@ -109,20 +197,31 @@ impl SimpleCfgFunction { // (where there is only one target edge and the empty node has no instructions) // and changes the source edge to point to the target node fn collapse_empty_blocks(mut self) -> SimpleCfgFunction { - // loop over every non-empty block, and look at its parents - for block in self.graph.node_indices().collect::>() { - // find parents - let parents: Vec = self - .graph - .edges_directed(block, Direction::Incoming) - .map(|edge| edge.source()) - .collect(); + let mut to_replace = vec![]; + // loop over every edge in the graph + for edge in self.graph.edge_references() { + // if this edge is a source -> empty -> target + // and target has only one incoming edge - for parent in &parents { - self.collapse_empty_block(*parent); + let target_node = edge.target(); + let target_outgoing = self.graph.edges_directed(target_node, Direction::Outgoing); + if self.graph[target_node].instrs.is_empty() + && self.graph[target_node].footer.is_empty() + { + if let &[target_out] = target_outgoing.collect::>().as_slice() { + // point to new_target instead + let source_node = edge.source(); + let source_edge = edge.id(); + let source_weight = edge.weight().clone(); + to_replace.push((source_edge, source_node, target_out.target(), source_weight)); + } } } + for (source_edge, source_node, target_node, source_weight) in to_replace { + self.graph.remove_edge(source_edge); + self.graph.add_edge(source_node, target_node, source_weight); + } self } From 38a1fa29b1ba5db4f308f0ac7081591e58a02bc4 Mon Sep 17 00:00:00 2001 From: oflatt Date: Mon, 28 Oct 2024 17:00:30 -0700 Subject: [PATCH 02/11] better comment --- src/rvsdg/optimize_direct_jumps.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/rvsdg/optimize_direct_jumps.rs b/src/rvsdg/optimize_direct_jumps.rs index 8cafe713..8c843cf1 100644 --- a/src/rvsdg/optimize_direct_jumps.rs +++ b/src/rvsdg/optimize_direct_jumps.rs @@ -22,8 +22,12 @@ impl SimpleCfgFunction { pub fn optimize_jumps(&self) -> Self { // fusing down only needs to happen once // fuze up may need to run until fixed point - // collapse empty blocks only need to happen once - self.fuse_down().fuze_up().fuze_up().collapse_empty_blocks() + // collapse empty blocks may also need to run until fixed point + self.fuse_down() + .fuze_up() + .fuze_up() + .collapse_empty_blocks() + .collapse_empty_blocks() } /// Finds blocks with only id instructions and fuses them with their parents From 8eb7e4f39936a703b856b7116522f379fd9fc79e Mon Sep 17 00:00:00 2001 From: oflatt Date: Mon, 28 Oct 2024 17:15:39 -0700 Subject: [PATCH 03/11] much simpler fuze up --- src/rvsdg/optimize_direct_jumps.rs | 120 +++++------------------------ 1 file changed, 19 insertions(+), 101 deletions(-) diff --git a/src/rvsdg/optimize_direct_jumps.rs b/src/rvsdg/optimize_direct_jumps.rs index 8c843cf1..e3911bed 100644 --- a/src/rvsdg/optimize_direct_jumps.rs +++ b/src/rvsdg/optimize_direct_jumps.rs @@ -7,13 +7,12 @@ use bril_rs::{Instruction, ValueOps}; use indexmap::IndexMap; use petgraph::{ - graph::EdgeIndex, stable_graph::{NodeIndex, StableDiGraph, StableGraph}, - visit::{Bfs, DfsPostOrder, EdgeRef, IntoEdgeReferences}, + visit::{DfsPostOrder, EdgeRef, IntoEdgeReferences}, Direction, }; -use crate::cfg::{Annotation, BasicBlock, Branch, Simple, SimpleCfgFunction, SimpleCfgProgram}; +use crate::cfg::{BasicBlock, Branch, Simple, SimpleCfgFunction, SimpleCfgProgram}; #[cfg(test)] use crate::Optimizer; @@ -32,22 +31,13 @@ impl SimpleCfgFunction { /// Finds blocks with only id instructions and fuses them with their parents /// The parent must jump directly to the block - fn fuze_up(&self) -> SimpleCfgFunction { - let mut resulting_graph: StableGraph = StableDiGraph::new(); - - // maps nodes in the old graph to nodes in the new graph - // this is 1 to 1 for this optimization - let mut node_mapping: IndexMap = IndexMap::new(); - - let mut bfs = Bfs::new(&self.graph, self.entry); - - while let Some(node) = bfs.next(&self.graph) { - let incoming_to_node = self + fn fuze_up(mut self) -> SimpleCfgFunction { + for node in self.graph.node_indices().collect::>() { + let parents = self .graph .edges_directed(node, Direction::Incoming) + .map(|edge| edge.source()) .collect::>(); - - // check if the optimization is applicable let should_apply = self.graph[node].instrs.iter().all(|instr| { matches!( instr, @@ -56,62 +46,28 @@ impl SimpleCfgFunction { .. } ) - }) && incoming_to_node.iter().all(|edge| { - let source = edge.source(); - let outgoing_from_source = self + }) && parents.iter().all(|parent| { + let parent_outgoing = self .graph - .edges_directed(source, Direction::Outgoing) + .edges_directed(*parent, Direction::Outgoing) .count(); - outgoing_from_source == 1 + parent_outgoing == 1 }); + let new_instrs = self.graph[node].instrs.clone(); + let new_footer = self.graph[node].footer.clone(); + // move instructions from node up to parents if should_apply { - for parent_edge in incoming_to_node { - let parent = &node_mapping[&parent_edge.source()]; - if !resulting_graph[*parent] - .footer - .iter() - .any(|annotation| matches!(annotation, Annotation::AssignRet { .. })) - { - resulting_graph[*parent] - .instrs - .extend(self.graph[node].instrs.to_vec()); + for parent in parents { + if self.graph[parent].footer.is_empty() { + self.graph[parent].instrs.extend(new_instrs.clone()); } - resulting_graph[*parent] - .footer - .extend(self.graph[node].footer.to_vec()); + self.graph[parent].footer.extend(new_footer.clone()); } - - // add a new node, but empty - let new_node = resulting_graph.add_node(BasicBlock { - name: self.graph[node].name.clone(), - instrs: vec![], - footer: vec![], - pos: None, - }); - node_mapping.insert(node, new_node); - } else { - // add the new node - let new_node = resulting_graph.add_node(self.graph[node].clone()); - node_mapping.insert(node, new_node); - }; - } - - for edge in self.graph.edge_references() { - let source = &node_mapping[&edge.source()]; - let target = &node_mapping[&edge.target()]; - resulting_graph.add_edge(*source, *target, edge.weight().clone()); + } } - SimpleCfgFunction { - name: self.name.clone(), - args: self.args.clone(), - graph: resulting_graph, - entry: node_mapping[&self.entry], - exit: node_mapping[&self.exit], - _phantom: Simple, - return_ty: self.return_ty.clone(), - } + self } /// Find cases where a block jumps directly to another block A -> B where @@ -228,44 +184,6 @@ impl SimpleCfgFunction { } self } - - /// Detect the case where source -> empty -> target - /// The empty block should have a single incoming and single outgoing edge - fn get_single_in_single_out(&self, parent_block: NodeIndex) -> Option<(EdgeIndex, EdgeIndex)> { - if !self.graph[parent_block].instrs.is_empty() - || !self.graph[parent_block].footer.is_empty() - { - return None; - } - - let outgoing = self - .graph - .edges_directed(parent_block, Direction::Outgoing) - .collect::>(); - let incoming = self - .graph - .edges_directed(parent_block, Direction::Incoming) - .collect::>(); - if let ([source_edge], [outgoing]) = (incoming.as_slice(), outgoing.as_slice()) { - Some((source_edge.id(), outgoing.id())) - } else { - None - } - } - - /// Detect the case when source -> empty -> target - /// and collapse it to source -> target - fn collapse_empty_block(&mut self, parent_block: NodeIndex) { - if let Some((source_edge, outgoing)) = self.get_single_in_single_out(parent_block) { - let weight = self.graph.edge_weight(source_edge).unwrap().clone(); - let (source, empty) = self.graph.edge_endpoints(source_edge).unwrap(); - let (empty_, target) = self.graph.edge_endpoints(outgoing).unwrap(); - assert_eq!(empty, empty_); - - self.graph.remove_edge(source_edge); - self.graph.add_edge(source, target, weight); - } - } } impl SimpleCfgProgram { From 5792e84d89743033baba6b7f80947f63420c1958 Mon Sep 17 00:00:00 2001 From: oflatt Date: Mon, 28 Oct 2024 17:29:22 -0700 Subject: [PATCH 04/11] oops, forgot to clear --- src/rvsdg/optimize_direct_jumps.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/rvsdg/optimize_direct_jumps.rs b/src/rvsdg/optimize_direct_jumps.rs index e3911bed..951b3e52 100644 --- a/src/rvsdg/optimize_direct_jumps.rs +++ b/src/rvsdg/optimize_direct_jumps.rs @@ -38,6 +38,9 @@ impl SimpleCfgFunction { .edges_directed(node, Direction::Incoming) .map(|edge| edge.source()) .collect::>(); + + // check if fusing up is possible- instructions are all id + // and parents directly jump to this block let should_apply = self.graph[node].instrs.iter().all(|instr| { matches!( instr, @@ -64,6 +67,10 @@ impl SimpleCfgFunction { } self.graph[parent].footer.extend(new_footer.clone()); } + + // delete instructions from node + self.graph[node].instrs.clear(); + self.graph[node].footer.clear(); } } From cb434a88f8193c8a6e4604e9423ed3dbf61baef2 Mon Sep 17 00:00:00 2001 From: oflatt Date: Mon, 28 Oct 2024 17:41:23 -0700 Subject: [PATCH 05/11] fix a bug with footers, unclear why it happens --- src/rvsdg/optimize_direct_jumps.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/rvsdg/optimize_direct_jumps.rs b/src/rvsdg/optimize_direct_jumps.rs index 951b3e52..030e2142 100644 --- a/src/rvsdg/optimize_direct_jumps.rs +++ b/src/rvsdg/optimize_direct_jumps.rs @@ -41,6 +41,7 @@ impl SimpleCfgFunction { // check if fusing up is possible- instructions are all id // and parents directly jump to this block + // and the footer is empty let should_apply = self.graph[node].instrs.iter().all(|instr| { matches!( instr, @@ -55,22 +56,19 @@ impl SimpleCfgFunction { .edges_directed(*parent, Direction::Outgoing) .count(); parent_outgoing == 1 - }); + }) && self.graph[node].footer.is_empty(); let new_instrs = self.graph[node].instrs.clone(); - let new_footer = self.graph[node].footer.clone(); // move instructions from node up to parents if should_apply { for parent in parents { if self.graph[parent].footer.is_empty() { self.graph[parent].instrs.extend(new_instrs.clone()); } - self.graph[parent].footer.extend(new_footer.clone()); } // delete instructions from node self.graph[node].instrs.clear(); - self.graph[node].footer.clear(); } } From f1621b1b30c70805123fe859f6513e026d34172e Mon Sep 17 00:00:00 2001 From: oflatt Date: Tue, 29 Oct 2024 14:14:40 -0700 Subject: [PATCH 06/11] snapshots --- ...ollatz_redundant_computation-optimize.snap | 9 +- .../files__fib_recursive-optimize.snap | 596 ++++++++++-------- .../files__gamma_condition_and-optimize.snap | 3 + .../files__if_dead_code_nested-optimize.snap | 21 + ...s__mem_loop_store_forwarding-optimize.snap | 22 +- .../files__recurse_once-optimize.snap | 5 + .../files__simple_recursive-optimize.snap | 5 + .../files__small-collatz-optimize.snap | 25 +- 8 files changed, 396 insertions(+), 290 deletions(-) diff --git a/tests/snapshots/files__collatz_redundant_computation-optimize.snap b/tests/snapshots/files__collatz_redundant_computation-optimize.snap index 7340d95a..fb459901 100644 --- a/tests/snapshots/files__collatz_redundant_computation-optimize.snap +++ b/tests/snapshots/files__collatz_redundant_computation-optimize.snap @@ -49,7 +49,6 @@ expression: visualization.result v33_: int = id v9_; v34_: int = id v10_; v35_: int = id v11_; -.b37_: v14_: int = id v6_; v15_: int = id v31_; v16_: int = id v8_; @@ -65,6 +64,14 @@ expression: visualization.result v10_: int = id v18_; v11_: int = id v19_; br v39_ .b12_ .b40_; +.b37_: + v14_: int = id v6_; + v15_: int = id v31_; + v16_: int = id v8_; + v17_: int = id v9_; + v18_: int = id v10_; + v19_: int = id v11_; + jmp .b20_; .b40_: print v0; } diff --git a/tests/snapshots/files__fib_recursive-optimize.snap b/tests/snapshots/files__fib_recursive-optimize.snap index 9be0217f..a5c5e9f6 100644 --- a/tests/snapshots/files__fib_recursive-optimize.snap +++ b/tests/snapshots/files__fib_recursive-optimize.snap @@ -16,244 +16,286 @@ expression: visualization.result v11_: bool = eq c2_ c2_; v12_: int = id v0; br v11_ .b13_ .b14_; +.b13_: + v15_: int = id v0; + v5_: int = id v15_; + ret v5_; .b14_: - v15_: bool = eq c2_ v0; - br v15_ .b16_ .b17_; -.b16_: - v18_: bool = eq c2_ c2_; - v19_: int = id c2_; - br v18_ .b20_ .b21_; + v16_: bool = eq c2_ v0; + br v16_ .b17_ .b18_; +.b17_: + v19_: bool = eq c2_ c2_; + v20_: int = id c2_; + br v19_ .b21_ .b22_; .b21_: - v22_: bool = eq c2_ c2_; - br v22_ .b23_ .b24_; -.b23_: - v25_: int = call @fac c2_; - v26_: int = id c2_; -.b27_: - v19_: int = id v26_; -.b20_: + v23_: int = id c2_; + v12_: int = id v23_; + v15_: int = id v0; + v5_: int = id v15_; + ret v5_; +.b22_: + v24_: bool = eq c2_ c2_; + br v24_ .b25_ .b26_; +.b25_: + v27_: int = call @fac c2_; v28_: int = id c2_; -.b29_: - v12_: int = id v28_; -.b13_: - v30_: int = id v0; -.b31_: - v5_: int = id v30_; + v20_: int = id v28_; + v23_: int = id c2_; + v12_: int = id v23_; + v15_: int = id v0; + v5_: int = id v15_; ret v5_; -.b24_: - c32_: int = const -1; - v33_: int = sub c32_ c2_; - v34_: int = call @fac c32_; - v35_: int = call @fac v33_; - v36_: int = add v34_ v35_; - v26_: int = id v36_; - jmp .b27_; -.b17_: - c37_: int = const -2; - v38_: bool = eq c2_ c37_; - c39_: int = const -1; - v40_: bool = eq c2_ c39_; +.b26_: + c29_: int = const -1; + v30_: int = sub c29_ c2_; + v31_: int = call @fac c29_; + v32_: int = call @fac v30_; + v33_: int = add v31_ v32_; + v28_: int = id v33_; + v20_: int = id v28_; + v23_: int = id c2_; + v12_: int = id v23_; + v15_: int = id v0; + v5_: int = id v15_; + ret v5_; +.b18_: + c34_: int = const -2; + v35_: bool = eq c2_ c34_; + c36_: int = const -1; + v37_: bool = eq c2_ c36_; + v38_: int = id v0; + br v37_ .b39_ .b40_; +.b39_: v41_: int = id v0; - br v40_ .b42_ .b43_; -.b43_: - v44_: bool = eq c39_ v0; - br v44_ .b45_ .b46_; -.b45_: - v47_: int = call @fac c2_; - v48_: int = id c39_; -.b49_: - v41_: int = id v48_; .b42_: - v50_: int = id v0; - br v38_ .b51_ .b52_; -.b52_: - v53_: bool = eq c37_ v0; - br v53_ .b54_ .b55_; -.b54_: - v56_: int = call @fac c2_; - v57_: int = id v0; + br v35_ .b43_ .b44_; +.b44_: + v45_: bool = eq c34_ v0; + br v45_ .b46_ .b47_; +.b46_: + v48_: int = call @fac c2_; + v49_: int = id v0; + v41_: int = id v49_; +.b43_: + v50_: int = add v38_ v41_; + v23_: int = id v50_; + v12_: int = id v23_; + v15_: int = id v0; + v5_: int = id v15_; + ret v5_; +.b47_: + c51_: int = const -4; + c52_: int = const -3; + v53_: int = call @fac c52_; + v54_: int = call @fac c51_; + v55_: int = add v53_ v54_; + v49_: int = id v55_; + v41_: int = id v49_; + jmp .b43_; +.b40_: + v56_: bool = eq c36_ v0; + br v56_ .b57_ .b58_; +.b57_: + v59_: int = call @fac c2_; + v60_: int = id c36_; + v38_: int = id v60_; + v41_: int = id v0; + jmp .b42_; .b58_: - v50_: int = id v57_; -.b51_: - v59_: int = add v41_ v50_; - v28_: int = id v59_; - jmp .b29_; -.b55_: - c60_: int = const -4; c61_: int = const -3; - v62_: int = call @fac c61_; - v63_: int = call @fac c60_; - v64_: int = add v62_ v63_; - v57_: int = id v64_; - jmp .b58_; -.b46_: - c65_: int = const -3; - c66_: int = const -2; - v67_: int = call @fac c66_; - v68_: int = call @fac c65_; - v69_: int = add v67_ v68_; - v48_: int = id v69_; - jmp .b49_; + c62_: int = const -2; + v63_: int = call @fac c62_; + v64_: int = call @fac c61_; + v65_: int = add v63_ v64_; + v60_: int = id v65_; + v38_: int = id v60_; + v41_: int = id v0; + jmp .b42_; .b10_: - v70_: int = sub v0 c4_; - v71_: int = sub v70_ c4_; - v72_: bool = eq c2_ v71_; - v73_: bool = eq c2_ v70_; - v74_: int = id c4_; - br v73_ .b75_ .b76_; + v66_: int = sub v0 c4_; + v67_: int = sub v66_ c4_; + v68_: bool = eq c2_ v67_; + v69_: bool = eq c2_ v66_; + v70_: int = id c4_; + br v69_ .b71_ .b72_; +.b71_: + v73_: int = id c4_; +.b74_: + br v68_ .b75_ .b76_; .b76_: - v77_: bool = eq c4_ v70_; + v77_: bool = eq c4_ v67_; br v77_ .b78_ .b79_; .b78_: v80_: bool = eq c2_ c2_; - v81_: int = id v70_; + v81_: int = id c4_; br v80_ .b82_ .b83_; -.b83_: - v84_: bool = eq c2_ v70_; - br v84_ .b85_ .b86_; -.b85_: - v87_: int = call @fac c2_; - v88_: int = id c2_; -.b89_: - v81_: int = id v88_; .b82_: - v90_: int = id v70_; -.b91_: - v74_: int = id v90_; + v84_: int = id c4_; + v73_: int = id v84_; .b75_: - v92_: int = id c4_; - br v72_ .b93_ .b94_; -.b94_: - v95_: bool = eq c4_ v71_; - br v95_ .b96_ .b97_; -.b96_: - v98_: bool = eq c2_ c2_; - v99_: int = id c4_; - br v98_ .b100_ .b101_; + v85_: int = add v70_ v73_; + v15_: int = id v85_; + v5_: int = id v15_; + ret v5_; +.b83_: + v86_: bool = eq c2_ c4_; + br v86_ .b87_ .b88_; +.b87_: + v89_: int = call @fac c2_; + v90_: int = id c4_; + v81_: int = id v90_; + v84_: int = id c4_; + v73_: int = id v84_; + jmp .b75_; +.b88_: + c91_: int = const -2; + c92_: int = const -1; + v93_: int = call @fac c92_; + v94_: int = call @fac c91_; + v95_: int = add v93_ v94_; + v90_: int = id v95_; + v81_: int = id v90_; + v84_: int = id c4_; + v73_: int = id v84_; + jmp .b75_; +.b79_: + v96_: int = sub v67_ c4_; + v97_: int = sub v96_ c4_; + v98_: bool = eq c2_ v97_; + v99_: bool = eq c2_ v96_; + v100_: int = id c4_; + br v99_ .b101_ .b102_; .b101_: - v102_: bool = eq c2_ c4_; - br v102_ .b103_ .b104_; -.b103_: - v105_: int = call @fac c2_; - v106_: int = id c4_; -.b107_: - v99_: int = id v106_; -.b100_: - v108_: int = id c4_; -.b109_: - v92_: int = id v108_; -.b93_: - v110_: int = add v74_ v92_; - v30_: int = id v110_; - jmp .b31_; + v103_: int = id c4_; .b104_: - c111_: int = const -2; - c112_: int = const -1; - v113_: int = call @fac c112_; - v114_: int = call @fac c111_; - v115_: int = add v113_ v114_; - v106_: int = id v115_; - jmp .b107_; -.b97_: - v116_: int = sub v71_ c4_; - v117_: int = sub v116_ c4_; - v118_: bool = eq c2_ v117_; - v119_: bool = eq c2_ v116_; - v120_: int = id c4_; - br v119_ .b121_ .b122_; -.b122_: - v123_: bool = eq c4_ v116_; - br v123_ .b124_ .b125_; -.b124_: - v126_: int = call @fac c2_; - v127_: int = id c4_; -.b128_: - v120_: int = id v127_; -.b121_: - v129_: int = id c4_; - br v118_ .b130_ .b131_; -.b131_: - v132_: bool = eq c4_ v117_; - br v132_ .b133_ .b134_; + br v98_ .b105_ .b106_; +.b106_: + v107_: bool = eq c4_ v97_; + br v107_ .b108_ .b109_; +.b108_: + v110_: int = call @fac c2_; + v111_: int = id c4_; + v103_: int = id v111_; +.b105_: + v112_: int = add v100_ v103_; + v84_: int = id v112_; + v73_: int = id v84_; + jmp .b75_; +.b109_: + v113_: int = sub v97_ c4_; + v114_: int = sub v113_ c4_; + v115_: int = call @fac v113_; + v116_: int = call @fac v114_; + v117_: int = add v115_ v116_; + v111_: int = id v117_; + v103_: int = id v111_; + jmp .b105_; +.b102_: + v118_: bool = eq c4_ v96_; + br v118_ .b119_ .b120_; +.b119_: + v121_: int = call @fac c2_; + v122_: int = id c4_; + v100_: int = id v122_; + v103_: int = id c4_; + jmp .b104_; +.b120_: + v123_: int = sub v96_ c4_; + v124_: int = sub v123_ c4_; + v125_: int = call @fac v123_; + v126_: int = call @fac v124_; + v127_: int = add v125_ v126_; + v122_: int = id v127_; + v100_: int = id v122_; + v103_: int = id c4_; + jmp .b104_; +.b72_: + v128_: bool = eq c4_ v66_; + br v128_ .b129_ .b130_; +.b129_: + v131_: bool = eq c2_ c2_; + v132_: int = id v66_; + br v131_ .b133_ .b134_; .b133_: - v135_: int = call @fac c2_; - v136_: int = id c4_; + v135_: int = id v66_; + v70_: int = id v135_; + v73_: int = id c4_; + jmp .b74_; +.b134_: + v136_: bool = eq c2_ v66_; + br v136_ .b137_ .b138_; .b137_: - v129_: int = id v136_; + v139_: int = call @fac c2_; + v140_: int = id c2_; + v132_: int = id v140_; + v135_: int = id v66_; + v70_: int = id v135_; + v73_: int = id c4_; + jmp .b74_; +.b138_: + c141_: int = const -2; + c142_: int = const -1; + v143_: int = call @fac c142_; + v144_: int = call @fac c141_; + v145_: int = add v143_ v144_; + v140_: int = id v145_; + v132_: int = id v140_; + v135_: int = id v66_; + v70_: int = id v135_; + v73_: int = id c4_; + jmp .b74_; .b130_: - v138_: int = add v120_ v129_; - v108_: int = id v138_; - jmp .b109_; -.b134_: - v139_: int = sub v117_ c4_; - v140_: int = sub v139_ c4_; - v141_: int = call @fac v139_; - v142_: int = call @fac v140_; - v143_: int = add v141_ v142_; - v136_: int = id v143_; - jmp .b137_; -.b125_: - v144_: int = sub v116_ c4_; - v145_: int = sub v144_ c4_; - v146_: int = call @fac v144_; - v147_: int = call @fac v145_; - v148_: int = add v146_ v147_; - v127_: int = id v148_; - jmp .b128_; -.b86_: - c149_: int = const -2; - c150_: int = const -1; - v151_: int = call @fac c150_; - v152_: int = call @fac c149_; - v153_: int = add v151_ v152_; - v88_: int = id v153_; - jmp .b89_; -.b79_: - v154_: int = sub v70_ c4_; - v155_: int = sub v154_ c4_; - v156_: bool = eq c2_ v155_; - v157_: bool = eq c2_ v154_; - v158_: int = id c4_; - br v157_ .b159_ .b160_; -.b160_: - v161_: bool = eq c4_ v154_; - br v161_ .b162_ .b163_; -.b162_: - v164_: int = call @fac c2_; - v165_: int = id v154_; -.b166_: - v158_: int = id v165_; + v146_: int = sub v66_ c4_; + v147_: int = sub v146_ c4_; + v148_: bool = eq c2_ v147_; + v149_: bool = eq c2_ v146_; + v150_: int = id c4_; + br v149_ .b151_ .b152_; +.b151_: + v153_: int = id c4_; +.b154_: + br v148_ .b155_ .b156_; +.b156_: + v157_: bool = eq c4_ v147_; + br v157_ .b158_ .b159_; +.b158_: + v160_: int = call @fac c2_; + v161_: int = id c4_; + v153_: int = id v161_; +.b155_: + v162_: int = add v150_ v153_; + v135_: int = id v162_; + v70_: int = id v135_; + v73_: int = id c4_; + jmp .b74_; .b159_: - v167_: int = id c4_; - br v156_ .b168_ .b169_; + v163_: int = sub v147_ c4_; + v164_: int = sub v163_ c4_; + v165_: int = call @fac v163_; + v166_: int = call @fac v164_; + v167_: int = add v165_ v166_; + v161_: int = id v167_; + v153_: int = id v161_; + jmp .b155_; +.b152_: + v168_: bool = eq c4_ v146_; + br v168_ .b169_ .b170_; .b169_: - v170_: bool = eq c4_ v155_; - br v170_ .b171_ .b172_; -.b171_: - v173_: int = call @fac c2_; - v174_: int = id c4_; -.b175_: - v167_: int = id v174_; -.b168_: - v176_: int = add v158_ v167_; - v90_: int = id v176_; - jmp .b91_; -.b172_: - v177_: int = sub v155_ c4_; - v178_: int = sub v177_ c4_; - v179_: int = call @fac v177_; - v180_: int = call @fac v178_; - v181_: int = add v179_ v180_; - v174_: int = id v181_; - jmp .b175_; -.b163_: - v182_: int = sub v154_ c4_; - v183_: int = sub v182_ c4_; - v184_: int = call @fac v182_; - v185_: int = call @fac v183_; - v186_: int = add v184_ v185_; - v165_: int = id v186_; - jmp .b166_; + v171_: int = call @fac c2_; + v172_: int = id v146_; + v150_: int = id v172_; + v153_: int = id c4_; + jmp .b154_; +.b170_: + v173_: int = sub v146_ c4_; + v174_: int = sub v173_ c4_; + v175_: int = call @fac v173_; + v176_: int = call @fac v174_; + v177_: int = add v175_ v176_; + v172_: int = id v177_; + v150_: int = id v172_; + v153_: int = id c4_; + jmp .b154_; .b6_: ret v5_; } @@ -272,71 +314,83 @@ expression: visualization.result v11_: bool = eq c2_ c2_; v12_: int = id c1_; br v11_ .b13_ .b14_; -.b14_: - v15_: bool = eq c1_ c2_; - br v15_ .b16_ .b17_; -.b16_: - v18_: int = call @fac c2_; - v19_: int = id c2_; -.b20_: - v12_: int = id v19_; .b13_: - v21_: int = id c1_; -.b22_: - v5_: int = id v21_; + v15_: int = id c1_; + v5_: int = id v15_; print v5_; ret; +.b14_: + v16_: bool = eq c1_ c2_; + br v16_ .b17_ .b18_; .b17_: - c23_: int = const -1; - v24_: int = sub c23_ c1_; - v25_: int = call @fac c23_; - v26_: int = call @fac v24_; - v27_: int = add v25_ v26_; - v19_: int = id v27_; - jmp .b20_; + v19_: int = call @fac c2_; + v20_: int = id c2_; + v12_: int = id v20_; + v15_: int = id c1_; + v5_: int = id v15_; + print v5_; + ret; +.b18_: + c21_: int = const -1; + v22_: int = sub c21_ c1_; + v23_: int = call @fac c21_; + v24_: int = call @fac v22_; + v25_: int = add v23_ v24_; + v20_: int = id v25_; + v12_: int = id v20_; + v15_: int = id c1_; + v5_: int = id v15_; + print v5_; + ret; .b10_: - v28_: bool = eq c2_ c2_; - v29_: bool = eq c2_ c4_; - v30_: int = id c4_; - br v29_ .b31_ .b32_; + v26_: bool = eq c2_ c2_; + v27_: bool = eq c2_ c4_; + v28_: int = id c4_; + br v27_ .b29_ .b30_; +.b29_: + v31_: int = id c4_; .b32_: - v33_: bool = eq c4_ c4_; - br v33_ .b34_ .b35_; + br v26_ .b33_ .b34_; .b34_: - v36_: int = call @fac c2_; - v37_: int = id c4_; -.b38_: - v30_: int = id v37_; -.b31_: + v35_: bool = eq c2_ c4_; + br v35_ .b36_ .b37_; +.b36_: + v38_: int = call @fac c2_; v39_: int = id c4_; - br v28_ .b40_ .b41_; -.b41_: - v42_: bool = eq c2_ c4_; - br v42_ .b43_ .b44_; -.b43_: - v45_: int = call @fac c2_; - v46_: int = id c4_; + v31_: int = id v39_; +.b33_: + v40_: int = add v28_ v31_; + v15_: int = id v40_; + v5_: int = id v15_; + print v5_; + ret; +.b37_: + c41_: int = const -2; + c42_: int = const -1; + v43_: int = call @fac c42_; + v44_: int = call @fac c41_; + v45_: int = add v43_ v44_; + v39_: int = id v45_; + v31_: int = id v39_; + jmp .b33_; +.b30_: + v46_: bool = eq c4_ c4_; + br v46_ .b47_ .b48_; .b47_: - v39_: int = id v46_; -.b40_: - v48_: int = add v30_ v39_; - v21_: int = id v48_; - jmp .b22_; -.b44_: - c49_: int = const -2; - c50_: int = const -1; - v51_: int = call @fac c50_; - v52_: int = call @fac c49_; - v53_: int = add v51_ v52_; - v46_: int = id v53_; - jmp .b47_; -.b35_: - c54_: int = const -1; - v55_: int = call @fac c2_; - v56_: int = call @fac c54_; - v57_: int = add v55_ v56_; - v37_: int = id v57_; - jmp .b38_; + v49_: int = call @fac c2_; + v50_: int = id c4_; + v28_: int = id v50_; + v31_: int = id c4_; + jmp .b32_; +.b48_: + c51_: int = const -1; + v52_: int = call @fac c2_; + v53_: int = call @fac c51_; + v54_: int = add v52_ v53_; + v50_: int = id v54_; + v28_: int = id v50_; + v31_: int = id c4_; + jmp .b32_; .b6_: print v5_; } diff --git a/tests/snapshots/files__gamma_condition_and-optimize.snap b/tests/snapshots/files__gamma_condition_and-optimize.snap index e55e8d25..1a664fca 100644 --- a/tests/snapshots/files__gamma_condition_and-optimize.snap +++ b/tests/snapshots/files__gamma_condition_and-optimize.snap @@ -17,6 +17,9 @@ expression: visualization.result br v4_ .b12_ .b13_; .b12_: v11_: int = id c5_; + v7_: int = id v11_; + print v7_; + ret; .b13_: v7_: int = id v11_; .b9_: diff --git a/tests/snapshots/files__if_dead_code_nested-optimize.snap b/tests/snapshots/files__if_dead_code_nested-optimize.snap index 10c37378..179e93fa 100644 --- a/tests/snapshots/files__if_dead_code_nested-optimize.snap +++ b/tests/snapshots/files__if_dead_code_nested-optimize.snap @@ -22,6 +22,12 @@ expression: visualization.result v12_: int = id c10_; v13_: bool = id c9_; v14_: int = id c10_; + v17_: int = id v12_; + v18_: int = id c10_; + print v18_; + print v3_; + print v17_; + ret; .b16_: v17_: int = id v12_; v18_: int = id c10_; @@ -49,10 +55,25 @@ expression: visualization.result v29_: int = id c34_; v30_: bool = id c20_; v31_: int = id c2_; + v22_: int = id v29_; + v23_: bool = id v30_; + v24_: int = id v31_; + v17_: int = id v22_; + v18_: int = id c2_; + print v18_; + print v3_; + print v17_; + ret; .b33_: v22_: int = id v29_; v23_: bool = id v30_; v24_: int = id v31_; + v17_: int = id v22_; + v18_: int = id c2_; + print v18_; + print v3_; + print v17_; + ret; .b26_: v17_: int = id v22_; v18_: int = id c2_; diff --git a/tests/snapshots/files__mem_loop_store_forwarding-optimize.snap b/tests/snapshots/files__mem_loop_store_forwarding-optimize.snap index 3607aca2..aa5140ae 100644 --- a/tests/snapshots/files__mem_loop_store_forwarding-optimize.snap +++ b/tests/snapshots/files__mem_loop_store_forwarding-optimize.snap @@ -14,18 +14,24 @@ expression: visualization.result v9_: ptr = id v3_; v10_: ptr = id v7_; v11_: bool = id v0; -.b12_: v8_: ptr = id v9_; v9_: ptr = id v8_; v10_: ptr = id v10_; v11_: bool = id v11_; - br v11_ .b12_ .b13_; +.b12_: + br v11_ .b13_ .b14_; .b13_: - c14_: int = const 10; - c15_: int = const 20; - store v9_ c14_; - store v10_ c15_; - v16_: int = load v9_; - print c14_; + v8_: ptr = id v9_; + v9_: ptr = id v8_; + v10_: ptr = id v10_; + v11_: bool = id v11_; + jmp .b12_; +.b14_: + c15_: int = const 10; + c16_: int = const 20; + store v9_ c15_; + store v10_ c16_; + v17_: int = load v9_; + print c15_; free v8_; } diff --git a/tests/snapshots/files__recurse_once-optimize.snap b/tests/snapshots/files__recurse_once-optimize.snap index 095b6cb8..d001635f 100644 --- a/tests/snapshots/files__recurse_once-optimize.snap +++ b/tests/snapshots/files__recurse_once-optimize.snap @@ -27,8 +27,13 @@ expression: visualization.result v22_: int = sub v16_ c21_; v23_: int = call @to_zero v22_; v18_: int = id v23_; + v11_: int = id v18_; + v4_: int = id v11_; + ret v4_; .b20_: v11_: int = id v18_; + v4_: int = id v11_; + ret v4_; .b13_: v4_: int = id v11_; .b6_: diff --git a/tests/snapshots/files__simple_recursive-optimize.snap b/tests/snapshots/files__simple_recursive-optimize.snap index 7a0b2aba..1c94983c 100644 --- a/tests/snapshots/files__simple_recursive-optimize.snap +++ b/tests/snapshots/files__simple_recursive-optimize.snap @@ -30,8 +30,13 @@ expression: visualization.result print v22_; v23_: int = call @inc v22_; v18_: int = id v23_; + v11_: int = id v18_; + v4_: int = id v11_; + ret v4_; .b20_: v11_: int = id v18_; + v4_: int = id v11_; + ret v4_; .b13_: v4_: int = id v11_; .b6_: diff --git a/tests/snapshots/files__small-collatz-optimize.snap b/tests/snapshots/files__small-collatz-optimize.snap index 16818e83..d047e3f3 100644 --- a/tests/snapshots/files__small-collatz-optimize.snap +++ b/tests/snapshots/files__small-collatz-optimize.snap @@ -40,7 +40,6 @@ expression: visualization.result v35_: int = id v9_; v36_: int = id v10_; v37_: int = id v11_; -.b38_: v14_: int = id v22_; v15_: int = id v33_; v16_: int = id v8_; @@ -48,26 +47,32 @@ expression: visualization.result v18_: int = id v10_; v19_: int = id v11_; .b20_: - v39_: bool = not v13_; + v38_: bool = not v13_; v6_: int = id v14_; v7_: int = id v15_; v8_: int = id v16_; v9_: int = id v17_; v10_: int = id v18_; v11_: int = id v19_; - br v39_ .b12_ .b40_; + br v38_ .b12_ .b39_; .b28_: - c41_: bool = const true; - v42_: int = mul v10_ v7_; - v43_: int = add v42_ v9_; + c40_: bool = const true; + v41_: int = mul v10_ v7_; + v42_: int = add v41_ v9_; v31_: int = id v22_; - v32_: bool = id c41_; - v33_: int = id v43_; + v32_: bool = id c40_; + v33_: int = id v42_; v34_: int = id v8_; v35_: int = id v9_; v36_: int = id v10_; v37_: int = id v11_; - jmp .b38_; -.b40_: + v14_: int = id v22_; + v15_: int = id v33_; + v16_: int = id v8_; + v17_: int = id v9_; + v18_: int = id v10_; + v19_: int = id v11_; + jmp .b20_; +.b39_: print v6_; } From e836ef95cd97c133b261966033362403ad1764b6 Mon Sep 17 00:00:00 2001 From: oflatt Date: Tue, 29 Oct 2024 14:42:19 -0700 Subject: [PATCH 07/11] small bug fix --- src/rvsdg/optimize_direct_jumps.rs | 13 +++++++++---- tests/snapshots/files__sqrt_small-optimize.snap | 5 +---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/rvsdg/optimize_direct_jumps.rs b/src/rvsdg/optimize_direct_jumps.rs index 030e2142..49b8c51d 100644 --- a/src/rvsdg/optimize_direct_jumps.rs +++ b/src/rvsdg/optimize_direct_jumps.rs @@ -22,11 +22,14 @@ impl SimpleCfgFunction { // fusing down only needs to happen once // fuze up may need to run until fixed point // collapse empty blocks may also need to run until fixed point - self.fuse_down() + let mut res = self + .fuse_down() .fuze_up() .fuze_up() .collapse_empty_blocks() - .collapse_empty_blocks() + .collapse_empty_blocks(); + res.remove_unreachable(); + res } /// Finds blocks with only id instructions and fuses them with their parents @@ -41,7 +44,8 @@ impl SimpleCfgFunction { // check if fusing up is possible- instructions are all id // and parents directly jump to this block - // and the footer is empty + // and the footer is empty. + // Also needs at least one parent let should_apply = self.graph[node].instrs.iter().all(|instr| { matches!( instr, @@ -56,7 +60,8 @@ impl SimpleCfgFunction { .edges_directed(*parent, Direction::Outgoing) .count(); parent_outgoing == 1 - }) && self.graph[node].footer.is_empty(); + }) && self.graph[node].footer.is_empty() + && !parents.is_empty(); let new_instrs = self.graph[node].instrs.clone(); // move instructions from node up to parents diff --git a/tests/snapshots/files__sqrt_small-optimize.snap b/tests/snapshots/files__sqrt_small-optimize.snap index 19c2e1cc..df3f8a56 100644 --- a/tests/snapshots/files__sqrt_small-optimize.snap +++ b/tests/snapshots/files__sqrt_small-optimize.snap @@ -55,11 +55,8 @@ expression: visualization.result v8_: float = id v13_; v9_: bool = id v36_; br v9_ .b37_ .b11_; -.b37_: - ret; .b11_: v38_: float = fdiv v8_ v8_; print v38_; - jmp .b37_; -.b39_: +.b37_: } From e4622a48e4c9a94eaaee297e1012eb27a3ccdbc1 Mon Sep 17 00:00:00 2001 From: oflatt Date: Wed, 30 Oct 2024 09:44:23 -0700 Subject: [PATCH 08/11] snapshots after rebase --- ...ndant_computation-optimize-sequential.snap | 9 +- ...es__fib_recursive-optimize-sequential.snap | 596 ++++++++++-------- ...mma_condition_and-optimize-sequential.snap | 3 + ..._dead_code_nested-optimize-sequential.snap | 21 + ..._store_forwarding-optimize-sequential.snap | 22 +- ...les__recurse_once-optimize-sequential.snap | 5 + ..._simple_recursive-optimize-sequential.snap | 5 + ...es__small-collatz-optimize-sequential.snap | 25 +- ...files__sqrt_small-optimize-sequential.snap | 5 +- 9 files changed, 397 insertions(+), 294 deletions(-) diff --git a/tests/snapshots/files__collatz_redundant_computation-optimize-sequential.snap b/tests/snapshots/files__collatz_redundant_computation-optimize-sequential.snap index 7340d95a..fb459901 100644 --- a/tests/snapshots/files__collatz_redundant_computation-optimize-sequential.snap +++ b/tests/snapshots/files__collatz_redundant_computation-optimize-sequential.snap @@ -49,7 +49,6 @@ expression: visualization.result v33_: int = id v9_; v34_: int = id v10_; v35_: int = id v11_; -.b37_: v14_: int = id v6_; v15_: int = id v31_; v16_: int = id v8_; @@ -65,6 +64,14 @@ expression: visualization.result v10_: int = id v18_; v11_: int = id v19_; br v39_ .b12_ .b40_; +.b37_: + v14_: int = id v6_; + v15_: int = id v31_; + v16_: int = id v8_; + v17_: int = id v9_; + v18_: int = id v10_; + v19_: int = id v11_; + jmp .b20_; .b40_: print v0; } diff --git a/tests/snapshots/files__fib_recursive-optimize-sequential.snap b/tests/snapshots/files__fib_recursive-optimize-sequential.snap index 9be0217f..a5c5e9f6 100644 --- a/tests/snapshots/files__fib_recursive-optimize-sequential.snap +++ b/tests/snapshots/files__fib_recursive-optimize-sequential.snap @@ -16,244 +16,286 @@ expression: visualization.result v11_: bool = eq c2_ c2_; v12_: int = id v0; br v11_ .b13_ .b14_; +.b13_: + v15_: int = id v0; + v5_: int = id v15_; + ret v5_; .b14_: - v15_: bool = eq c2_ v0; - br v15_ .b16_ .b17_; -.b16_: - v18_: bool = eq c2_ c2_; - v19_: int = id c2_; - br v18_ .b20_ .b21_; + v16_: bool = eq c2_ v0; + br v16_ .b17_ .b18_; +.b17_: + v19_: bool = eq c2_ c2_; + v20_: int = id c2_; + br v19_ .b21_ .b22_; .b21_: - v22_: bool = eq c2_ c2_; - br v22_ .b23_ .b24_; -.b23_: - v25_: int = call @fac c2_; - v26_: int = id c2_; -.b27_: - v19_: int = id v26_; -.b20_: + v23_: int = id c2_; + v12_: int = id v23_; + v15_: int = id v0; + v5_: int = id v15_; + ret v5_; +.b22_: + v24_: bool = eq c2_ c2_; + br v24_ .b25_ .b26_; +.b25_: + v27_: int = call @fac c2_; v28_: int = id c2_; -.b29_: - v12_: int = id v28_; -.b13_: - v30_: int = id v0; -.b31_: - v5_: int = id v30_; + v20_: int = id v28_; + v23_: int = id c2_; + v12_: int = id v23_; + v15_: int = id v0; + v5_: int = id v15_; ret v5_; -.b24_: - c32_: int = const -1; - v33_: int = sub c32_ c2_; - v34_: int = call @fac c32_; - v35_: int = call @fac v33_; - v36_: int = add v34_ v35_; - v26_: int = id v36_; - jmp .b27_; -.b17_: - c37_: int = const -2; - v38_: bool = eq c2_ c37_; - c39_: int = const -1; - v40_: bool = eq c2_ c39_; +.b26_: + c29_: int = const -1; + v30_: int = sub c29_ c2_; + v31_: int = call @fac c29_; + v32_: int = call @fac v30_; + v33_: int = add v31_ v32_; + v28_: int = id v33_; + v20_: int = id v28_; + v23_: int = id c2_; + v12_: int = id v23_; + v15_: int = id v0; + v5_: int = id v15_; + ret v5_; +.b18_: + c34_: int = const -2; + v35_: bool = eq c2_ c34_; + c36_: int = const -1; + v37_: bool = eq c2_ c36_; + v38_: int = id v0; + br v37_ .b39_ .b40_; +.b39_: v41_: int = id v0; - br v40_ .b42_ .b43_; -.b43_: - v44_: bool = eq c39_ v0; - br v44_ .b45_ .b46_; -.b45_: - v47_: int = call @fac c2_; - v48_: int = id c39_; -.b49_: - v41_: int = id v48_; .b42_: - v50_: int = id v0; - br v38_ .b51_ .b52_; -.b52_: - v53_: bool = eq c37_ v0; - br v53_ .b54_ .b55_; -.b54_: - v56_: int = call @fac c2_; - v57_: int = id v0; + br v35_ .b43_ .b44_; +.b44_: + v45_: bool = eq c34_ v0; + br v45_ .b46_ .b47_; +.b46_: + v48_: int = call @fac c2_; + v49_: int = id v0; + v41_: int = id v49_; +.b43_: + v50_: int = add v38_ v41_; + v23_: int = id v50_; + v12_: int = id v23_; + v15_: int = id v0; + v5_: int = id v15_; + ret v5_; +.b47_: + c51_: int = const -4; + c52_: int = const -3; + v53_: int = call @fac c52_; + v54_: int = call @fac c51_; + v55_: int = add v53_ v54_; + v49_: int = id v55_; + v41_: int = id v49_; + jmp .b43_; +.b40_: + v56_: bool = eq c36_ v0; + br v56_ .b57_ .b58_; +.b57_: + v59_: int = call @fac c2_; + v60_: int = id c36_; + v38_: int = id v60_; + v41_: int = id v0; + jmp .b42_; .b58_: - v50_: int = id v57_; -.b51_: - v59_: int = add v41_ v50_; - v28_: int = id v59_; - jmp .b29_; -.b55_: - c60_: int = const -4; c61_: int = const -3; - v62_: int = call @fac c61_; - v63_: int = call @fac c60_; - v64_: int = add v62_ v63_; - v57_: int = id v64_; - jmp .b58_; -.b46_: - c65_: int = const -3; - c66_: int = const -2; - v67_: int = call @fac c66_; - v68_: int = call @fac c65_; - v69_: int = add v67_ v68_; - v48_: int = id v69_; - jmp .b49_; + c62_: int = const -2; + v63_: int = call @fac c62_; + v64_: int = call @fac c61_; + v65_: int = add v63_ v64_; + v60_: int = id v65_; + v38_: int = id v60_; + v41_: int = id v0; + jmp .b42_; .b10_: - v70_: int = sub v0 c4_; - v71_: int = sub v70_ c4_; - v72_: bool = eq c2_ v71_; - v73_: bool = eq c2_ v70_; - v74_: int = id c4_; - br v73_ .b75_ .b76_; + v66_: int = sub v0 c4_; + v67_: int = sub v66_ c4_; + v68_: bool = eq c2_ v67_; + v69_: bool = eq c2_ v66_; + v70_: int = id c4_; + br v69_ .b71_ .b72_; +.b71_: + v73_: int = id c4_; +.b74_: + br v68_ .b75_ .b76_; .b76_: - v77_: bool = eq c4_ v70_; + v77_: bool = eq c4_ v67_; br v77_ .b78_ .b79_; .b78_: v80_: bool = eq c2_ c2_; - v81_: int = id v70_; + v81_: int = id c4_; br v80_ .b82_ .b83_; -.b83_: - v84_: bool = eq c2_ v70_; - br v84_ .b85_ .b86_; -.b85_: - v87_: int = call @fac c2_; - v88_: int = id c2_; -.b89_: - v81_: int = id v88_; .b82_: - v90_: int = id v70_; -.b91_: - v74_: int = id v90_; + v84_: int = id c4_; + v73_: int = id v84_; .b75_: - v92_: int = id c4_; - br v72_ .b93_ .b94_; -.b94_: - v95_: bool = eq c4_ v71_; - br v95_ .b96_ .b97_; -.b96_: - v98_: bool = eq c2_ c2_; - v99_: int = id c4_; - br v98_ .b100_ .b101_; + v85_: int = add v70_ v73_; + v15_: int = id v85_; + v5_: int = id v15_; + ret v5_; +.b83_: + v86_: bool = eq c2_ c4_; + br v86_ .b87_ .b88_; +.b87_: + v89_: int = call @fac c2_; + v90_: int = id c4_; + v81_: int = id v90_; + v84_: int = id c4_; + v73_: int = id v84_; + jmp .b75_; +.b88_: + c91_: int = const -2; + c92_: int = const -1; + v93_: int = call @fac c92_; + v94_: int = call @fac c91_; + v95_: int = add v93_ v94_; + v90_: int = id v95_; + v81_: int = id v90_; + v84_: int = id c4_; + v73_: int = id v84_; + jmp .b75_; +.b79_: + v96_: int = sub v67_ c4_; + v97_: int = sub v96_ c4_; + v98_: bool = eq c2_ v97_; + v99_: bool = eq c2_ v96_; + v100_: int = id c4_; + br v99_ .b101_ .b102_; .b101_: - v102_: bool = eq c2_ c4_; - br v102_ .b103_ .b104_; -.b103_: - v105_: int = call @fac c2_; - v106_: int = id c4_; -.b107_: - v99_: int = id v106_; -.b100_: - v108_: int = id c4_; -.b109_: - v92_: int = id v108_; -.b93_: - v110_: int = add v74_ v92_; - v30_: int = id v110_; - jmp .b31_; + v103_: int = id c4_; .b104_: - c111_: int = const -2; - c112_: int = const -1; - v113_: int = call @fac c112_; - v114_: int = call @fac c111_; - v115_: int = add v113_ v114_; - v106_: int = id v115_; - jmp .b107_; -.b97_: - v116_: int = sub v71_ c4_; - v117_: int = sub v116_ c4_; - v118_: bool = eq c2_ v117_; - v119_: bool = eq c2_ v116_; - v120_: int = id c4_; - br v119_ .b121_ .b122_; -.b122_: - v123_: bool = eq c4_ v116_; - br v123_ .b124_ .b125_; -.b124_: - v126_: int = call @fac c2_; - v127_: int = id c4_; -.b128_: - v120_: int = id v127_; -.b121_: - v129_: int = id c4_; - br v118_ .b130_ .b131_; -.b131_: - v132_: bool = eq c4_ v117_; - br v132_ .b133_ .b134_; + br v98_ .b105_ .b106_; +.b106_: + v107_: bool = eq c4_ v97_; + br v107_ .b108_ .b109_; +.b108_: + v110_: int = call @fac c2_; + v111_: int = id c4_; + v103_: int = id v111_; +.b105_: + v112_: int = add v100_ v103_; + v84_: int = id v112_; + v73_: int = id v84_; + jmp .b75_; +.b109_: + v113_: int = sub v97_ c4_; + v114_: int = sub v113_ c4_; + v115_: int = call @fac v113_; + v116_: int = call @fac v114_; + v117_: int = add v115_ v116_; + v111_: int = id v117_; + v103_: int = id v111_; + jmp .b105_; +.b102_: + v118_: bool = eq c4_ v96_; + br v118_ .b119_ .b120_; +.b119_: + v121_: int = call @fac c2_; + v122_: int = id c4_; + v100_: int = id v122_; + v103_: int = id c4_; + jmp .b104_; +.b120_: + v123_: int = sub v96_ c4_; + v124_: int = sub v123_ c4_; + v125_: int = call @fac v123_; + v126_: int = call @fac v124_; + v127_: int = add v125_ v126_; + v122_: int = id v127_; + v100_: int = id v122_; + v103_: int = id c4_; + jmp .b104_; +.b72_: + v128_: bool = eq c4_ v66_; + br v128_ .b129_ .b130_; +.b129_: + v131_: bool = eq c2_ c2_; + v132_: int = id v66_; + br v131_ .b133_ .b134_; .b133_: - v135_: int = call @fac c2_; - v136_: int = id c4_; + v135_: int = id v66_; + v70_: int = id v135_; + v73_: int = id c4_; + jmp .b74_; +.b134_: + v136_: bool = eq c2_ v66_; + br v136_ .b137_ .b138_; .b137_: - v129_: int = id v136_; + v139_: int = call @fac c2_; + v140_: int = id c2_; + v132_: int = id v140_; + v135_: int = id v66_; + v70_: int = id v135_; + v73_: int = id c4_; + jmp .b74_; +.b138_: + c141_: int = const -2; + c142_: int = const -1; + v143_: int = call @fac c142_; + v144_: int = call @fac c141_; + v145_: int = add v143_ v144_; + v140_: int = id v145_; + v132_: int = id v140_; + v135_: int = id v66_; + v70_: int = id v135_; + v73_: int = id c4_; + jmp .b74_; .b130_: - v138_: int = add v120_ v129_; - v108_: int = id v138_; - jmp .b109_; -.b134_: - v139_: int = sub v117_ c4_; - v140_: int = sub v139_ c4_; - v141_: int = call @fac v139_; - v142_: int = call @fac v140_; - v143_: int = add v141_ v142_; - v136_: int = id v143_; - jmp .b137_; -.b125_: - v144_: int = sub v116_ c4_; - v145_: int = sub v144_ c4_; - v146_: int = call @fac v144_; - v147_: int = call @fac v145_; - v148_: int = add v146_ v147_; - v127_: int = id v148_; - jmp .b128_; -.b86_: - c149_: int = const -2; - c150_: int = const -1; - v151_: int = call @fac c150_; - v152_: int = call @fac c149_; - v153_: int = add v151_ v152_; - v88_: int = id v153_; - jmp .b89_; -.b79_: - v154_: int = sub v70_ c4_; - v155_: int = sub v154_ c4_; - v156_: bool = eq c2_ v155_; - v157_: bool = eq c2_ v154_; - v158_: int = id c4_; - br v157_ .b159_ .b160_; -.b160_: - v161_: bool = eq c4_ v154_; - br v161_ .b162_ .b163_; -.b162_: - v164_: int = call @fac c2_; - v165_: int = id v154_; -.b166_: - v158_: int = id v165_; + v146_: int = sub v66_ c4_; + v147_: int = sub v146_ c4_; + v148_: bool = eq c2_ v147_; + v149_: bool = eq c2_ v146_; + v150_: int = id c4_; + br v149_ .b151_ .b152_; +.b151_: + v153_: int = id c4_; +.b154_: + br v148_ .b155_ .b156_; +.b156_: + v157_: bool = eq c4_ v147_; + br v157_ .b158_ .b159_; +.b158_: + v160_: int = call @fac c2_; + v161_: int = id c4_; + v153_: int = id v161_; +.b155_: + v162_: int = add v150_ v153_; + v135_: int = id v162_; + v70_: int = id v135_; + v73_: int = id c4_; + jmp .b74_; .b159_: - v167_: int = id c4_; - br v156_ .b168_ .b169_; + v163_: int = sub v147_ c4_; + v164_: int = sub v163_ c4_; + v165_: int = call @fac v163_; + v166_: int = call @fac v164_; + v167_: int = add v165_ v166_; + v161_: int = id v167_; + v153_: int = id v161_; + jmp .b155_; +.b152_: + v168_: bool = eq c4_ v146_; + br v168_ .b169_ .b170_; .b169_: - v170_: bool = eq c4_ v155_; - br v170_ .b171_ .b172_; -.b171_: - v173_: int = call @fac c2_; - v174_: int = id c4_; -.b175_: - v167_: int = id v174_; -.b168_: - v176_: int = add v158_ v167_; - v90_: int = id v176_; - jmp .b91_; -.b172_: - v177_: int = sub v155_ c4_; - v178_: int = sub v177_ c4_; - v179_: int = call @fac v177_; - v180_: int = call @fac v178_; - v181_: int = add v179_ v180_; - v174_: int = id v181_; - jmp .b175_; -.b163_: - v182_: int = sub v154_ c4_; - v183_: int = sub v182_ c4_; - v184_: int = call @fac v182_; - v185_: int = call @fac v183_; - v186_: int = add v184_ v185_; - v165_: int = id v186_; - jmp .b166_; + v171_: int = call @fac c2_; + v172_: int = id v146_; + v150_: int = id v172_; + v153_: int = id c4_; + jmp .b154_; +.b170_: + v173_: int = sub v146_ c4_; + v174_: int = sub v173_ c4_; + v175_: int = call @fac v173_; + v176_: int = call @fac v174_; + v177_: int = add v175_ v176_; + v172_: int = id v177_; + v150_: int = id v172_; + v153_: int = id c4_; + jmp .b154_; .b6_: ret v5_; } @@ -272,71 +314,83 @@ expression: visualization.result v11_: bool = eq c2_ c2_; v12_: int = id c1_; br v11_ .b13_ .b14_; -.b14_: - v15_: bool = eq c1_ c2_; - br v15_ .b16_ .b17_; -.b16_: - v18_: int = call @fac c2_; - v19_: int = id c2_; -.b20_: - v12_: int = id v19_; .b13_: - v21_: int = id c1_; -.b22_: - v5_: int = id v21_; + v15_: int = id c1_; + v5_: int = id v15_; print v5_; ret; +.b14_: + v16_: bool = eq c1_ c2_; + br v16_ .b17_ .b18_; .b17_: - c23_: int = const -1; - v24_: int = sub c23_ c1_; - v25_: int = call @fac c23_; - v26_: int = call @fac v24_; - v27_: int = add v25_ v26_; - v19_: int = id v27_; - jmp .b20_; + v19_: int = call @fac c2_; + v20_: int = id c2_; + v12_: int = id v20_; + v15_: int = id c1_; + v5_: int = id v15_; + print v5_; + ret; +.b18_: + c21_: int = const -1; + v22_: int = sub c21_ c1_; + v23_: int = call @fac c21_; + v24_: int = call @fac v22_; + v25_: int = add v23_ v24_; + v20_: int = id v25_; + v12_: int = id v20_; + v15_: int = id c1_; + v5_: int = id v15_; + print v5_; + ret; .b10_: - v28_: bool = eq c2_ c2_; - v29_: bool = eq c2_ c4_; - v30_: int = id c4_; - br v29_ .b31_ .b32_; + v26_: bool = eq c2_ c2_; + v27_: bool = eq c2_ c4_; + v28_: int = id c4_; + br v27_ .b29_ .b30_; +.b29_: + v31_: int = id c4_; .b32_: - v33_: bool = eq c4_ c4_; - br v33_ .b34_ .b35_; + br v26_ .b33_ .b34_; .b34_: - v36_: int = call @fac c2_; - v37_: int = id c4_; -.b38_: - v30_: int = id v37_; -.b31_: + v35_: bool = eq c2_ c4_; + br v35_ .b36_ .b37_; +.b36_: + v38_: int = call @fac c2_; v39_: int = id c4_; - br v28_ .b40_ .b41_; -.b41_: - v42_: bool = eq c2_ c4_; - br v42_ .b43_ .b44_; -.b43_: - v45_: int = call @fac c2_; - v46_: int = id c4_; + v31_: int = id v39_; +.b33_: + v40_: int = add v28_ v31_; + v15_: int = id v40_; + v5_: int = id v15_; + print v5_; + ret; +.b37_: + c41_: int = const -2; + c42_: int = const -1; + v43_: int = call @fac c42_; + v44_: int = call @fac c41_; + v45_: int = add v43_ v44_; + v39_: int = id v45_; + v31_: int = id v39_; + jmp .b33_; +.b30_: + v46_: bool = eq c4_ c4_; + br v46_ .b47_ .b48_; .b47_: - v39_: int = id v46_; -.b40_: - v48_: int = add v30_ v39_; - v21_: int = id v48_; - jmp .b22_; -.b44_: - c49_: int = const -2; - c50_: int = const -1; - v51_: int = call @fac c50_; - v52_: int = call @fac c49_; - v53_: int = add v51_ v52_; - v46_: int = id v53_; - jmp .b47_; -.b35_: - c54_: int = const -1; - v55_: int = call @fac c2_; - v56_: int = call @fac c54_; - v57_: int = add v55_ v56_; - v37_: int = id v57_; - jmp .b38_; + v49_: int = call @fac c2_; + v50_: int = id c4_; + v28_: int = id v50_; + v31_: int = id c4_; + jmp .b32_; +.b48_: + c51_: int = const -1; + v52_: int = call @fac c2_; + v53_: int = call @fac c51_; + v54_: int = add v52_ v53_; + v50_: int = id v54_; + v28_: int = id v50_; + v31_: int = id c4_; + jmp .b32_; .b6_: print v5_; } diff --git a/tests/snapshots/files__gamma_condition_and-optimize-sequential.snap b/tests/snapshots/files__gamma_condition_and-optimize-sequential.snap index e55e8d25..1a664fca 100644 --- a/tests/snapshots/files__gamma_condition_and-optimize-sequential.snap +++ b/tests/snapshots/files__gamma_condition_and-optimize-sequential.snap @@ -17,6 +17,9 @@ expression: visualization.result br v4_ .b12_ .b13_; .b12_: v11_: int = id c5_; + v7_: int = id v11_; + print v7_; + ret; .b13_: v7_: int = id v11_; .b9_: diff --git a/tests/snapshots/files__if_dead_code_nested-optimize-sequential.snap b/tests/snapshots/files__if_dead_code_nested-optimize-sequential.snap index af261b41..4ee4289b 100644 --- a/tests/snapshots/files__if_dead_code_nested-optimize-sequential.snap +++ b/tests/snapshots/files__if_dead_code_nested-optimize-sequential.snap @@ -23,6 +23,12 @@ expression: visualization.result v13_: int = id c11_; v14_: bool = id c10_; v15_: int = id c11_; + v18_: int = id v13_; + v19_: int = id c11_; + print v19_; + print v3_; + print v18_; + ret; .b17_: v18_: int = id v13_; v19_: int = id c11_; @@ -50,10 +56,25 @@ expression: visualization.result v30_: int = id c35_; v31_: bool = id c21_; v32_: int = id c4_; + v23_: int = id v30_; + v24_: bool = id v31_; + v25_: int = id v32_; + v18_: int = id v23_; + v19_: int = id c4_; + print v19_; + print v3_; + print v18_; + ret; .b34_: v23_: int = id v30_; v24_: bool = id v31_; v25_: int = id v32_; + v18_: int = id v23_; + v19_: int = id c4_; + print v19_; + print v3_; + print v18_; + ret; .b27_: v18_: int = id v23_; v19_: int = id c4_; diff --git a/tests/snapshots/files__mem_loop_store_forwarding-optimize-sequential.snap b/tests/snapshots/files__mem_loop_store_forwarding-optimize-sequential.snap index 9eb1c1a7..eaa52a49 100644 --- a/tests/snapshots/files__mem_loop_store_forwarding-optimize-sequential.snap +++ b/tests/snapshots/files__mem_loop_store_forwarding-optimize-sequential.snap @@ -14,18 +14,24 @@ expression: visualization.result v9_: ptr = id v3_; v10_: ptr = id v7_; v11_: bool = id v0; -.b12_: v8_: ptr = id v9_; v9_: ptr = id v8_; v10_: ptr = id v10_; v11_: bool = id v11_; - br v11_ .b12_ .b13_; +.b12_: + br v11_ .b13_ .b14_; .b13_: - c14_: int = const 20; - c15_: int = const 10; - store v9_ c15_; - store v10_ c14_; - v16_: int = load v9_; - print v16_; + v8_: ptr = id v9_; + v9_: ptr = id v8_; + v10_: ptr = id v10_; + v11_: bool = id v11_; + jmp .b12_; +.b14_: + c15_: int = const 20; + c16_: int = const 10; + store v9_ c16_; + store v10_ c15_; + v17_: int = load v9_; + print v17_; free v8_; } diff --git a/tests/snapshots/files__recurse_once-optimize-sequential.snap b/tests/snapshots/files__recurse_once-optimize-sequential.snap index 095b6cb8..d001635f 100644 --- a/tests/snapshots/files__recurse_once-optimize-sequential.snap +++ b/tests/snapshots/files__recurse_once-optimize-sequential.snap @@ -27,8 +27,13 @@ expression: visualization.result v22_: int = sub v16_ c21_; v23_: int = call @to_zero v22_; v18_: int = id v23_; + v11_: int = id v18_; + v4_: int = id v11_; + ret v4_; .b20_: v11_: int = id v18_; + v4_: int = id v11_; + ret v4_; .b13_: v4_: int = id v11_; .b6_: diff --git a/tests/snapshots/files__simple_recursive-optimize-sequential.snap b/tests/snapshots/files__simple_recursive-optimize-sequential.snap index 7a0b2aba..1c94983c 100644 --- a/tests/snapshots/files__simple_recursive-optimize-sequential.snap +++ b/tests/snapshots/files__simple_recursive-optimize-sequential.snap @@ -30,8 +30,13 @@ expression: visualization.result print v22_; v23_: int = call @inc v22_; v18_: int = id v23_; + v11_: int = id v18_; + v4_: int = id v11_; + ret v4_; .b20_: v11_: int = id v18_; + v4_: int = id v11_; + ret v4_; .b13_: v4_: int = id v11_; .b6_: diff --git a/tests/snapshots/files__small-collatz-optimize-sequential.snap b/tests/snapshots/files__small-collatz-optimize-sequential.snap index 16818e83..d047e3f3 100644 --- a/tests/snapshots/files__small-collatz-optimize-sequential.snap +++ b/tests/snapshots/files__small-collatz-optimize-sequential.snap @@ -40,7 +40,6 @@ expression: visualization.result v35_: int = id v9_; v36_: int = id v10_; v37_: int = id v11_; -.b38_: v14_: int = id v22_; v15_: int = id v33_; v16_: int = id v8_; @@ -48,26 +47,32 @@ expression: visualization.result v18_: int = id v10_; v19_: int = id v11_; .b20_: - v39_: bool = not v13_; + v38_: bool = not v13_; v6_: int = id v14_; v7_: int = id v15_; v8_: int = id v16_; v9_: int = id v17_; v10_: int = id v18_; v11_: int = id v19_; - br v39_ .b12_ .b40_; + br v38_ .b12_ .b39_; .b28_: - c41_: bool = const true; - v42_: int = mul v10_ v7_; - v43_: int = add v42_ v9_; + c40_: bool = const true; + v41_: int = mul v10_ v7_; + v42_: int = add v41_ v9_; v31_: int = id v22_; - v32_: bool = id c41_; - v33_: int = id v43_; + v32_: bool = id c40_; + v33_: int = id v42_; v34_: int = id v8_; v35_: int = id v9_; v36_: int = id v10_; v37_: int = id v11_; - jmp .b38_; -.b40_: + v14_: int = id v22_; + v15_: int = id v33_; + v16_: int = id v8_; + v17_: int = id v9_; + v18_: int = id v10_; + v19_: int = id v11_; + jmp .b20_; +.b39_: print v6_; } diff --git a/tests/snapshots/files__sqrt_small-optimize-sequential.snap b/tests/snapshots/files__sqrt_small-optimize-sequential.snap index 19c2e1cc..df3f8a56 100644 --- a/tests/snapshots/files__sqrt_small-optimize-sequential.snap +++ b/tests/snapshots/files__sqrt_small-optimize-sequential.snap @@ -55,11 +55,8 @@ expression: visualization.result v8_: float = id v13_; v9_: bool = id v36_; br v9_ .b37_ .b11_; -.b37_: - ret; .b11_: v38_: float = fdiv v8_ v8_; print v38_; - jmp .b37_; -.b39_: +.b37_: } From 488242d7463d559cfbcd749b40b6df694bf5273d Mon Sep 17 00:00:00 2001 From: oflatt Date: Wed, 30 Oct 2024 14:56:23 -0700 Subject: [PATCH 09/11] better comments --- src/rvsdg/optimize_direct_jumps.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/rvsdg/optimize_direct_jumps.rs b/src/rvsdg/optimize_direct_jumps.rs index 49b8c51d..2a2cb972 100644 --- a/src/rvsdg/optimize_direct_jumps.rs +++ b/src/rvsdg/optimize_direct_jumps.rs @@ -22,6 +22,7 @@ impl SimpleCfgFunction { // fusing down only needs to happen once // fuze up may need to run until fixed point // collapse empty blocks may also need to run until fixed point + // right now we just run them twice let mut res = self .fuse_down() .fuze_up() @@ -34,6 +35,13 @@ impl SimpleCfgFunction { /// Finds blocks with only id instructions and fuses them with their parents /// The parent must jump directly to the block + /// A -> B -> C + /// / + /// D + /// + /// If B has only id instructions, we can fuse it into both A and D. + /// These id instructions are optimized away by register allocation in LLVM, so this is fine. + /// If there are non-id instructions, this causes code blowup. Id instructions are "free" fn fuze_up(mut self) -> SimpleCfgFunction { for node in self.graph.node_indices().collect::>() { let parents = self @@ -171,14 +179,13 @@ impl SimpleCfgFunction { // loop over every edge in the graph for edge in self.graph.edge_references() { // if this edge is a source -> empty -> target - // and target has only one incoming edge + // and the empty node has no instructions - let target_node = edge.target(); - let target_outgoing = self.graph.edges_directed(target_node, Direction::Outgoing); - if self.graph[target_node].instrs.is_empty() - && self.graph[target_node].footer.is_empty() + let empty_node = edge.target(); + let empty_outgoing = self.graph.edges_directed(empty_node, Direction::Outgoing); + if self.graph[empty_node].instrs.is_empty() && self.graph[empty_node].footer.is_empty() { - if let &[target_out] = target_outgoing.collect::>().as_slice() { + if let &[target_out] = empty_outgoing.collect::>().as_slice() { // point to new_target instead let source_node = edge.source(); let source_edge = edge.id(); From f2f40ccf6174ca570760ef7aae3dc78c8d9fc224 Mon Sep 17 00:00:00 2001 From: oflatt Date: Wed, 30 Oct 2024 15:26:36 -0700 Subject: [PATCH 10/11] rewrite empty block with @chandrakananandi --- src/rvsdg/optimize_direct_jumps.rs | 51 +++++++++++++++++------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/rvsdg/optimize_direct_jumps.rs b/src/rvsdg/optimize_direct_jumps.rs index 2a2cb972..8a922114 100644 --- a/src/rvsdg/optimize_direct_jumps.rs +++ b/src/rvsdg/optimize_direct_jumps.rs @@ -170,34 +170,41 @@ impl SimpleCfgFunction { } } - // this function looks for all CFG fragments of the form - // source node --(source edge)-> empty node --(target edge)-> target node - // (where there is only one target edge and the empty node has no instructions) - // and changes the source edge to point to the target node + // this function looks for all CFG empty blocks with a direct jump out + // and makes sure they are removed by having the parents skip them fn collapse_empty_blocks(mut self) -> SimpleCfgFunction { - let mut to_replace = vec![]; - // loop over every edge in the graph - for edge in self.graph.edge_references() { - // if this edge is a source -> empty -> target - // and the empty node has no instructions + let mut to_remove = vec![]; + for node in self.graph.node_indices().collect::>() { + // empty block with a single direct jump out + if self.graph[node].instrs.is_empty() { + if let [single_child] = self + .graph + .edges_directed(node, Direction::Outgoing) + .map(|edge| edge.target()) + .collect::>() + .as_slice() + { + let parents = self + .graph + .edges_directed(node, Direction::Incoming) + .map(|parent| { + let source = parent.source(); + let weight = parent.weight().clone(); + to_remove.push(parent.id()); + (source, weight) + }) + .collect::>(); - let empty_node = edge.target(); - let empty_outgoing = self.graph.edges_directed(empty_node, Direction::Outgoing); - if self.graph[empty_node].instrs.is_empty() && self.graph[empty_node].footer.is_empty() - { - if let &[target_out] = empty_outgoing.collect::>().as_slice() { - // point to new_target instead - let source_node = edge.source(); - let source_edge = edge.id(); - let source_weight = edge.weight().clone(); - to_replace.push((source_edge, source_node, target_out.target(), source_weight)); + // for every parent edge, point to child instead of node + for (source, weight) in parents { + self.graph.add_edge(source, *single_child, weight); + } } } } - for (source_edge, source_node, target_node, source_weight) in to_replace { - self.graph.remove_edge(source_edge); - self.graph.add_edge(source_node, target_node, source_weight); + for edge in to_remove { + self.graph.remove_edge(edge); } self } From 71224325fa35def1a909356894fb6687c506c5df Mon Sep 17 00:00:00 2001 From: oflatt Date: Wed, 30 Oct 2024 15:50:59 -0700 Subject: [PATCH 11/11] footer needs to be empty too --- src/rvsdg/optimize_direct_jumps.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rvsdg/optimize_direct_jumps.rs b/src/rvsdg/optimize_direct_jumps.rs index 8a922114..75c4e2d3 100644 --- a/src/rvsdg/optimize_direct_jumps.rs +++ b/src/rvsdg/optimize_direct_jumps.rs @@ -8,7 +8,7 @@ use bril_rs::{Instruction, ValueOps}; use indexmap::IndexMap; use petgraph::{ stable_graph::{NodeIndex, StableDiGraph, StableGraph}, - visit::{DfsPostOrder, EdgeRef, IntoEdgeReferences}, + visit::{DfsPostOrder, EdgeRef}, Direction, }; @@ -176,7 +176,7 @@ impl SimpleCfgFunction { let mut to_remove = vec![]; for node in self.graph.node_indices().collect::>() { // empty block with a single direct jump out - if self.graph[node].instrs.is_empty() { + if self.graph[node].instrs.is_empty() && self.graph[node].footer.is_empty() { if let [single_child] = self .graph .edges_directed(node, Direction::Outgoing)