From 1cd91b6f3086d7ca68d361319063510ea2a8afd0 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 21 Sep 2017 12:16:32 -0700 Subject: [PATCH] Eliminate layout::Cursor from cton_frontend. Replace all uses with a FuncCursor. Avoid the anti-pattern of passing parts of a function around as independent references. --- lib/cretonne/src/loop_analysis.rs | 37 +- lib/cretonne/src/topo_order.rs | 10 +- lib/frontend/src/frontend.rs | 11 +- lib/frontend/src/ssa.rs | 599 ++++++++---------------------- 4 files changed, 172 insertions(+), 485 deletions(-) diff --git a/lib/cretonne/src/loop_analysis.rs b/lib/cretonne/src/loop_analysis.rs index 05ce1952f2..21c612356e 100644 --- a/lib/cretonne/src/loop_analysis.rs +++ b/lib/cretonne/src/loop_analysis.rs @@ -223,7 +223,8 @@ impl LoopAnalysis { #[cfg(test)] mod test { - use ir::{Function, InstBuilder, Cursor, CursorBase, types}; + use cursor::{Cursor, FuncCursor}; + use ir::{Function, InstBuilder, types}; use loop_analysis::{Loop, LoopAnalysis}; use flowgraph::ControlFlowGraph; use dominator_tree::DominatorTree; @@ -238,21 +239,20 @@ mod test { let cond = func.dfg.append_ebb_arg(ebb0, types::I32); { - let dfg = &mut func.dfg; - let cur = &mut Cursor::new(&mut func.layout); + let mut cur = FuncCursor::new(&mut func); cur.insert_ebb(ebb0); - dfg.ins(cur).jump(ebb1, &[]); + cur.ins().jump(ebb1, &[]); cur.insert_ebb(ebb1); - dfg.ins(cur).jump(ebb2, &[]); + cur.ins().jump(ebb2, &[]); cur.insert_ebb(ebb2); - dfg.ins(cur).brnz(cond, ebb1, &[]); - dfg.ins(cur).jump(ebb3, &[]); + cur.ins().brnz(cond, ebb1, &[]); + cur.ins().jump(ebb3, &[]); cur.insert_ebb(ebb3); - dfg.ins(cur).brnz(cond, ebb0, &[]); + cur.ins().brnz(cond, ebb0, &[]); } @@ -291,29 +291,28 @@ mod test { let cond = func.dfg.append_ebb_arg(ebb0, types::I32); { - let dfg = &mut func.dfg; - let cur = &mut Cursor::new(&mut func.layout); + let mut cur = FuncCursor::new(&mut func); cur.insert_ebb(ebb0); - dfg.ins(cur).brnz(cond, ebb1, &[]); - dfg.ins(cur).jump(ebb3, &[]); + cur.ins().brnz(cond, ebb1, &[]); + cur.ins().jump(ebb3, &[]); cur.insert_ebb(ebb1); - dfg.ins(cur).jump(ebb2, &[]); + cur.ins().jump(ebb2, &[]); cur.insert_ebb(ebb2); - dfg.ins(cur).brnz(cond, ebb1, &[]); - dfg.ins(cur).jump(ebb5, &[]); + cur.ins().brnz(cond, ebb1, &[]); + cur.ins().jump(ebb5, &[]); cur.insert_ebb(ebb3); - dfg.ins(cur).jump(ebb4, &[]); + cur.ins().jump(ebb4, &[]); cur.insert_ebb(ebb4); - dfg.ins(cur).brnz(cond, ebb3, &[]); - dfg.ins(cur).jump(ebb5, &[]); + cur.ins().brnz(cond, ebb3, &[]); + cur.ins().jump(ebb5, &[]); cur.insert_ebb(ebb5); - dfg.ins(cur).brnz(cond, ebb0, &[]); + cur.ins().brnz(cond, ebb0, &[]); } diff --git a/lib/cretonne/src/topo_order.rs b/lib/cretonne/src/topo_order.rs index 2224b339a1..db566ae7c8 100644 --- a/lib/cretonne/src/topo_order.rs +++ b/lib/cretonne/src/topo_order.rs @@ -80,9 +80,10 @@ impl TopoOrder { #[cfg(test)] mod test { + use cursor::{Cursor, FuncCursor}; use flowgraph::ControlFlowGraph; use dominator_tree::DominatorTree; - use ir::{Function, InstBuilder, Cursor, CursorBase}; + use ir::{Function, InstBuilder}; use std::iter; use super::*; @@ -105,13 +106,12 @@ mod test { let ebb1 = func.dfg.make_ebb(); { - let dfg = &mut func.dfg; - let cur = &mut Cursor::new(&mut func.layout); + let mut cur = FuncCursor::new(&mut func); cur.insert_ebb(ebb0); - dfg.ins(cur).jump(ebb1, &[]); + cur.ins().jump(ebb1, &[]); cur.insert_ebb(ebb1); - dfg.ins(cur).jump(ebb1, &[]); + cur.ins().jump(ebb1, &[]); } let cfg = ControlFlowGraph::with_function(&func); diff --git a/lib/frontend/src/frontend.rs b/lib/frontend/src/frontend.rs index 98ef98ac62..75c7dfe481 100644 --- a/lib/frontend/src/frontend.rs +++ b/lib/frontend/src/frontend.rs @@ -271,12 +271,7 @@ where /// created. Forgetting to call this method on every block will cause inconsistences in the /// produced functions. pub fn seal_block(&mut self, ebb: Ebb) { - let side_effects = self.builder.ssa.seal_ebb_header_block( - ebb, - &mut self.func.dfg, - &mut self.func.layout, - &mut self.func.jump_tables, - ); + let side_effects = self.builder.ssa.seal_ebb_header_block(ebb, self.func); self.handle_ssa_side_effects(side_effects); } @@ -292,9 +287,7 @@ where "this variable is used but its type has not been declared", ); let (val, side_effects) = self.builder.ssa.use_var( - &mut self.func.dfg, - &mut self.func.layout, - &mut self.func.jump_tables, + self.func, var, ty, self.position.basic_block, diff --git a/lib/frontend/src/ssa.rs b/lib/frontend/src/ssa.rs index e054ee511c..0d3e00c5a9 100644 --- a/lib/frontend/src/ssa.rs +++ b/lib/frontend/src/ssa.rs @@ -5,8 +5,8 @@ //! In: Jhala R., De Bosschere K. (eds) Compiler Construction. CC 2013. //! Lecture Notes in Computer Science, vol 7791. Springer, Berlin, Heidelberg -use cretonne::ir::{Ebb, Value, Inst, Type, DataFlowGraph, JumpTables, Layout, Cursor, CursorBase, - InstBuilder}; +use cretonne::cursor::{Cursor, FuncCursor}; +use cretonne::ir::{Ebb, Value, Inst, Type, Function, InstBuilder}; use cretonne::ir::instructions::BranchInfo; use cretonne::entity::{EntityRef, PrimaryMap, EntityMap}; use cretonne::packed_option::PackedOption; @@ -217,9 +217,7 @@ where /// responsible for making sure that you initialize your variables. pub fn use_var( &mut self, - dfg: &mut DataFlowGraph, - layout: &mut Layout, - jts: &mut JumpTables, + func: &mut Function, var: Variable, ty: Type, block: Block, @@ -232,16 +230,14 @@ where } // Otherwise, we have to do a non-local lookup. - self.use_var_nonlocal(dfg, layout, jts, var, ty, block) + self.use_var_nonlocal(func, var, ty, block) } // The non-local case of use_var. Query each predecessor for a value and add branch // arguments as needed to satisfy the use. fn use_var_nonlocal( &mut self, - dfg: &mut DataFlowGraph, - layout: &mut Layout, - jts: &mut JumpTables, + func: &mut Function, var: Variable, ty: Type, block: Block, @@ -255,11 +251,11 @@ where // Only one predecessor, straightforward case UseVarCases::SealedOnePredecessor(data.predecessors[0].0) } else { - let val = dfg.append_ebb_arg(data.ebb, ty); + let val = func.dfg.append_ebb_arg(data.ebb, ty); UseVarCases::SealedMultiplePredecessors(val, data.ebb) } } else { - let val = dfg.append_ebb_arg(data.ebb, ty); + let val = func.dfg.append_ebb_arg(data.ebb, ty); data.undef_variables.push((var, val)); UseVarCases::Unsealed(val) } @@ -271,7 +267,7 @@ where // The block has a single predecessor or multiple predecessor with // the same value, we look into it. UseVarCases::SealedOnePredecessor(pred) => { - let (val, mids) = self.use_var(dfg, layout, jts, var, ty, pred); + let (val, mids) = self.use_var(func, var, ty, pred); self.def_var(var, val, block); (val, mids) } @@ -285,7 +281,7 @@ where // If multiple predecessor we look up a use_var in each of them: // if they all yield the same value no need for an Ebb argument self.def_var(var, val, block); - self.predecessors_lookup(dfg, layout, jts, val, var, ebb) + self.predecessors_lookup(func, val, var, ebb) } } } @@ -354,13 +350,7 @@ where /// take into account the Phi function placed by the SSA algorithm. /// /// Returns the list of newly created ebbs for critical edge splitting. - pub fn seal_ebb_header_block( - &mut self, - ebb: Ebb, - dfg: &mut DataFlowGraph, - layout: &mut Layout, - jts: &mut JumpTables, - ) -> SideEffects { + pub fn seal_ebb_header_block(&mut self, ebb: Ebb, func: &mut Function) -> SideEffects { let block = self.header_block(ebb); let (undef_vars, ebb): (Vec<(Variable, Value)>, Ebb) = match self.blocks[block] { @@ -378,7 +368,7 @@ where // For each undef var we look up values in the predecessors and create an Ebb argument // only if necessary. for (var, val) in undef_vars { - let (_, local_side_effects) = self.predecessors_lookup(dfg, layout, jts, val, var, ebb); + let (_, local_side_effects) = self.predecessors_lookup(func, val, var, ebb); side_effects.append(local_side_effects); } @@ -399,15 +389,13 @@ where /// list of Ebb that are the middle of newly created critical edges splits. fn predecessors_lookup( &mut self, - dfg: &mut DataFlowGraph, - layout: &mut Layout, - jts: &mut JumpTables, + func: &mut Function, temp_arg_val: Value, temp_arg_var: Variable, dest_ebb: Ebb, ) -> (Value, SideEffects) { let mut pred_values: ZeroOneOrMore = ZeroOneOrMore::Zero(); - let ty = dfg.value_type(temp_arg_val); + let ty = func.dfg.value_type(temp_arg_val); let mut side_effects = SideEffects::new(); // Iterate over the predecessors. To avoid borrowing `self` for the whole loop, @@ -417,8 +405,7 @@ where for &(pred, _) in &preds { // For each predecessor, we query what is the local SSA value corresponding // to var and we put it as an argument of the branch instruction. - let (pred_val, local_side_effects) = - self.use_var(dfg, layout, jts, temp_arg_var, ty, pred); + let (pred_val, local_side_effects) = self.use_var(func, temp_arg_var, ty, pred); match pred_values { ZeroOneOrMore::Zero() => { if pred_val != temp_arg_val { @@ -441,17 +428,17 @@ where // The variable is used but never defined before. This is an irregularity in the // code, but rather than throwing an error we silently initialize the variable to // 0. This will have no effect since this situation happens in unreachable code. - if !layout.is_ebb_inserted(dest_ebb) { - layout.append_ebb(dest_ebb) + if !func.layout.is_ebb_inserted(dest_ebb) { + func.layout.append_ebb(dest_ebb) }; - let mut cur = Cursor::new(layout).at_first_insertion_point(dest_ebb); - let ty = dfg.value_type(temp_arg_val); + let ty = func.dfg.value_type(temp_arg_val); + let mut cur = FuncCursor::new(func).at_first_insertion_point(dest_ebb); let val = if ty.is_int() { - dfg.ins(&mut cur).iconst(ty, 0) + cur.ins().iconst(ty, 0) } else if ty == F32 { - dfg.ins(&mut cur).f32const(Ieee32::with_bits(0)) + cur.ins().f32const(Ieee32::with_bits(0)) } else if ty == F64 { - dfg.ins(&mut cur).f64const(Ieee64::with_bits(0)) + cur.ins().f64const(Ieee64::with_bits(0)) } else { panic!("value used but never declared and initialization not supported") }; @@ -463,8 +450,8 @@ where // so we don't need to have it as an ebb argument. // We need to replace all the occurences of val with pred_val but since // we can't afford a re-writing pass right now we just declare an alias. - dfg.remove_ebb_arg(temp_arg_val); - dfg.change_to_alias(temp_arg_val, pred_val); + func.dfg.remove_ebb_arg(temp_arg_val); + func.dfg.change_to_alias(temp_arg_val, pred_val); pred_val } ZeroOneOrMore::More() => { @@ -480,14 +467,12 @@ where .unwrap(); if let Some((middle_ebb, middle_block, middle_jump_inst)) = self.append_jump_argument( - dfg, - layout, + func, *last_inst, *pred_block, dest_ebb, pred_val, temp_arg_var, - jts, ) { *pred_block = middle_block; @@ -511,41 +496,39 @@ where /// critical edge splitting. fn append_jump_argument( &mut self, - dfg: &mut DataFlowGraph, - layout: &mut Layout, + func: &mut Function, jump_inst: Inst, jump_inst_block: Block, dest_ebb: Ebb, val: Value, var: Variable, - jts: &mut JumpTables, ) -> Option<(Ebb, Block, Inst)> { - match dfg[jump_inst].analyze_branch(&dfg.value_lists) { + match func.dfg[jump_inst].analyze_branch(&func.dfg.value_lists) { BranchInfo::NotABranch => { panic!("you have declared a non-branch instruction as a predecessor to an ebb"); } // For a single destination appending a jump argument to the instruction // is sufficient. BranchInfo::SingleDest(_, _) => { - dfg.append_inst_arg(jump_inst, val); + func.dfg.append_inst_arg(jump_inst, val); None } BranchInfo::Table(jt) => { // In the case of a jump table, the situation is tricky because br_table doesn't // support arguments. // We have to split the critical edge - let middle_ebb = dfg.make_ebb(); - layout.append_ebb(middle_ebb); + let middle_ebb = func.dfg.make_ebb(); + func.layout.append_ebb(middle_ebb); let block = self.declare_ebb_header_block(middle_ebb); self.blocks[block].add_predecessor(jump_inst_block, jump_inst); - self.seal_ebb_header_block(middle_ebb, dfg, layout, jts); - for old_dest in jts[jt].as_mut_slice() { + self.seal_ebb_header_block(middle_ebb, func); + for old_dest in func.jump_tables[jt].as_mut_slice() { if old_dest.unwrap() == dest_ebb { *old_dest = PackedOption::from(middle_ebb); } } - let mut cur = Cursor::new(layout).at_bottom(middle_ebb); - let middle_jump_inst = dfg.ins(&mut cur).jump(dest_ebb, &[val]); + let mut cur = FuncCursor::new(func).at_bottom(middle_ebb); + let middle_jump_inst = cur.ins().jump(dest_ebb, &[val]); self.def_var(var, val, block); Some((middle_ebb, block, middle_jump_inst)) } @@ -581,8 +564,9 @@ where #[cfg(test)] mod tests { + use cretonne::cursor::{Cursor, FuncCursor}; use cretonne::entity::EntityRef; - use cretonne::ir::{Function, InstBuilder, Cursor, CursorBase, Inst, JumpTableData}; + use cretonne::ir::{Function, InstBuilder, Inst, JumpTableData}; use cretonne::ir::types::*; use cretonne::verify_function; use cretonne::ir::instructions::BranchInfo; @@ -623,105 +607,37 @@ mod tests { let block = ssa.declare_ebb_header_block(ebb0); let x_var = Variable(0); let x_ssa = { - let cur = &mut Cursor::new(&mut func.layout); + let mut cur = FuncCursor::new(&mut func); cur.insert_ebb(ebb0); - func.dfg.ins(cur).iconst(I32, 1) + cur.ins().iconst(I32, 1) }; ssa.def_var(x_var, x_ssa, block); let y_var = Variable(1); let y_ssa = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).iconst(I32, 2) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().iconst(I32, 2) }; ssa.def_var(y_var, y_ssa, block); - assert_eq!( - ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block, - ).0, - x_ssa - ); - assert_eq!( - ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - y_var, - I32, - block, - ).0, - y_ssa - ); + assert_eq!(ssa.use_var(&mut func, x_var, I32, block).0, x_ssa); + assert_eq!(ssa.use_var(&mut func, y_var, I32, block).0, y_ssa); let z_var = Variable(2); - let x_use1 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block, - ).0; - let y_use1 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - y_var, - I32, - block, - ).0; + let x_use1 = ssa.use_var(&mut func, x_var, I32, block).0; + let y_use1 = ssa.use_var(&mut func, y_var, I32, block).0; let z1_ssa = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).iadd(x_use1, y_use1) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().iadd(x_use1, y_use1) }; ssa.def_var(z_var, z1_ssa, block); - assert_eq!( - ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - z_var, - I32, - block, - ).0, - z1_ssa - ); - let x_use2 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block, - ).0; - let z_use1 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - z_var, - I32, - block, - ).0; + assert_eq!(ssa.use_var(&mut func, z_var, I32, block).0, z1_ssa); + let x_use2 = ssa.use_var(&mut func, x_var, I32, block).0; + let z_use1 = ssa.use_var(&mut func, z_var, I32, block).0; let z2_ssa = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).iadd(x_use2, z_use1) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().iadd(x_use2, z_use1) }; ssa.def_var(z_var, z2_ssa, block); - assert_eq!( - ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - z_var, - I32, - block, - ).0, - z2_ssa - ); + assert_eq!(ssa.use_var(&mut func, z_var, I32, block).0, z2_ssa); } #[test] @@ -743,146 +659,57 @@ mod tests { let block0 = ssa.declare_ebb_header_block(ebb0); let x_var = Variable(0); let x_ssa = { - let cur = &mut Cursor::new(&mut func.layout); + let mut cur = FuncCursor::new(&mut func); cur.insert_ebb(ebb0); cur.insert_ebb(ebb1); cur.goto_bottom(ebb0); - func.dfg.ins(cur).iconst(I32, 1) + cur.ins().iconst(I32, 1) }; ssa.def_var(x_var, x_ssa, block0); let y_var = Variable(1); let y_ssa = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).iconst(I32, 2) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().iconst(I32, 2) }; ssa.def_var(y_var, y_ssa, block0); - assert_eq!( - ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block0, - ).0, - x_ssa - ); - assert_eq!( - ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - y_var, - I32, - block0, - ).0, - y_ssa - ); + assert_eq!(ssa.use_var(&mut func, x_var, I32, block0).0, x_ssa); + assert_eq!(ssa.use_var(&mut func, y_var, I32, block0).0, y_ssa); let z_var = Variable(2); - let x_use1 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block0, - ).0; - let y_use1 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - y_var, - I32, - block0, - ).0; + let x_use1 = ssa.use_var(&mut func, x_var, I32, block0).0; + let y_use1 = ssa.use_var(&mut func, y_var, I32, block0).0; let z1_ssa = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).iadd(x_use1, y_use1) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().iadd(x_use1, y_use1) }; ssa.def_var(z_var, z1_ssa, block0); - assert_eq!( - ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - z_var, - I32, - block0, - ).0, - z1_ssa - ); - let y_use2 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - y_var, - I32, - block0, - ).0; + assert_eq!(ssa.use_var(&mut func, z_var, I32, block0).0, z1_ssa); + let y_use2 = ssa.use_var(&mut func, y_var, I32, block0).0; let jump_inst: Inst = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).brnz(y_use2, ebb1, &[]) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().brnz(y_use2, ebb1, &[]) }; let block1 = ssa.declare_ebb_body_block(block0); - let x_use2 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block1, - ).0; + let x_use2 = ssa.use_var(&mut func, x_var, I32, block1).0; assert_eq!(x_use2, x_ssa); - let z_use1 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - z_var, - I32, - block1, - ).0; + let z_use1 = ssa.use_var(&mut func, z_var, I32, block1).0; assert_eq!(z_use1, z1_ssa); let z2_ssa = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).iadd(x_use2, z_use1) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().iadd(x_use2, z_use1) }; ssa.def_var(z_var, z2_ssa, block1); - assert_eq!( - ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - z_var, - I32, - block1, - ).0, - z2_ssa - ); - ssa.seal_ebb_header_block(ebb0, &mut func.dfg, &mut func.layout, &mut func.jump_tables); + assert_eq!(ssa.use_var(&mut func, z_var, I32, block1).0, z2_ssa); + ssa.seal_ebb_header_block(ebb0, &mut func); let block2 = ssa.declare_ebb_header_block(ebb1); ssa.declare_ebb_predecessor(ebb1, block0, jump_inst); - ssa.seal_ebb_header_block(ebb1, &mut func.dfg, &mut func.layout, &mut func.jump_tables); - let x_use3 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block2, - ).0; + ssa.seal_ebb_header_block(ebb1, &mut func); + let x_use3 = ssa.use_var(&mut func, x_var, I32, block2).0; assert_eq!(x_ssa, x_use3); - let y_use3 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - y_var, - I32, - block2, - ).0; + let y_use3 = ssa.use_var(&mut func, y_var, I32, block2).0; assert_eq!(y_ssa, y_use3); let y2_ssa = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb1); - func.dfg.ins(cur).iadd(x_use3, y_use3) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().iadd(x_use3, y_use3) }; ssa.def_var(y_var, y2_ssa, block2); match func.dfg[jump_inst].analyze_branch(&func.dfg.value_lists) { @@ -917,179 +744,89 @@ mod tests { // jump ebb1 let block0 = ssa.declare_ebb_header_block(ebb0); - ssa.seal_ebb_header_block(ebb0, &mut func.dfg, &mut func.layout, &mut func.jump_tables); + ssa.seal_ebb_header_block(ebb0, &mut func); let x_var = Variable(0); let x1 = { - let cur = &mut Cursor::new(&mut func.layout); + let mut cur = FuncCursor::new(&mut func); cur.insert_ebb(ebb0); cur.insert_ebb(ebb1); cur.insert_ebb(ebb2); cur.goto_bottom(ebb0); - func.dfg.ins(cur).iconst(I32, 1) + cur.ins().iconst(I32, 1) }; ssa.def_var(x_var, x1, block0); - assert_eq!( - ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block0, - ).0, - x1 - ); + assert_eq!(ssa.use_var(&mut func, x_var, I32, block0).0, x1); let y_var = Variable(1); let y1 = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).iconst(I32, 2) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().iconst(I32, 2) }; ssa.def_var(y_var, y1, block0); - assert_eq!( - ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - y_var, - I32, - block0, - ).0, - y1 - ); + assert_eq!(ssa.use_var(&mut func, y_var, I32, block0).0, y1); let z_var = Variable(2); - let x2 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block0, - ).0; + let x2 = ssa.use_var(&mut func, x_var, I32, block0).0; assert_eq!(x2, x1); - let y2 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - y_var, - I32, - block0, - ).0; + let y2 = ssa.use_var(&mut func, y_var, I32, block0).0; assert_eq!(y2, y1); let z1 = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).iadd(x2, y2) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().iadd(x2, y2) }; ssa.def_var(z_var, z1, block0); let jump_ebb0_ebb1 = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).jump(ebb1, &[]) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().jump(ebb1, &[]) }; let block1 = ssa.declare_ebb_header_block(ebb1); ssa.declare_ebb_predecessor(ebb1, block0, jump_ebb0_ebb1); - let z2 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - z_var, - I32, - block1, - ).0; - let y3 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - y_var, - I32, - block1, - ).0; + let z2 = ssa.use_var(&mut func, z_var, I32, block1).0; + let y3 = ssa.use_var(&mut func, y_var, I32, block1).0; let z3 = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb1); - func.dfg.ins(cur).iadd(z2, y3) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb1); + cur.ins().iadd(z2, y3) }; ssa.def_var(z_var, z3, block1); - let y4 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - y_var, - I32, - block1, - ).0; + let y4 = ssa.use_var(&mut func, y_var, I32, block1).0; assert_eq!(y4, y3); let jump_ebb1_ebb2 = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb1); - func.dfg.ins(cur).brnz(y4, ebb2, &[]) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb1); + cur.ins().brnz(y4, ebb2, &[]) }; let block2 = ssa.declare_ebb_body_block(block1); - let z4 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - z_var, - I32, - block2, - ).0; + let z4 = ssa.use_var(&mut func, z_var, I32, block2).0; assert_eq!(z4, z3); - let x3 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block2, - ).0; + let x3 = ssa.use_var(&mut func, x_var, I32, block2).0; let z5 = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb1); - func.dfg.ins(cur).isub(z4, x3) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb1); + cur.ins().isub(z4, x3) }; ssa.def_var(z_var, z5, block2); - let y5 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - y_var, - I32, - block2, - ).0; + let y5 = ssa.use_var(&mut func, y_var, I32, block2).0; assert_eq!(y5, y3); { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb1); - func.dfg.ins(cur).return_(&[y5]) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb1); + cur.ins().return_(&[y5]) }; let block3 = ssa.declare_ebb_header_block(ebb2); ssa.declare_ebb_predecessor(ebb2, block1, jump_ebb1_ebb2); - ssa.seal_ebb_header_block(ebb2, &mut func.dfg, &mut func.layout, &mut func.jump_tables); - let y6 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - y_var, - I32, - block3, - ).0; + ssa.seal_ebb_header_block(ebb2, &mut func); + let y6 = ssa.use_var(&mut func, y_var, I32, block3).0; assert_eq!(y6, y3); - let x4 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block3, - ).0; + let x4 = ssa.use_var(&mut func, x_var, I32, block3).0; assert_eq!(x4, x3); let y7 = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb2); - func.dfg.ins(cur).isub(y6, x4) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb2); + cur.ins().isub(y6, x4) }; ssa.def_var(y_var, y7, block3); let jump_ebb2_ebb1 = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb2); - func.dfg.ins(cur).jump(ebb1, &[]) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb2); + cur.ins().jump(ebb1, &[]) }; ssa.declare_ebb_predecessor(ebb1, block3, jump_ebb2_ebb1); - ssa.seal_ebb_header_block(ebb1, &mut func.dfg, &mut func.layout, &mut func.jump_tables); + ssa.seal_ebb_header_block(ebb1, &mut func); assert_eq!(func.dfg.ebb_args(ebb1)[0], z2); assert_eq!(func.dfg.ebb_args(ebb1)[1], y3); assert_eq!(func.dfg.resolve_aliases(x3), x1); @@ -1114,60 +851,46 @@ mod tests { // return // let block0 = ssa.declare_ebb_header_block(ebb0); - ssa.seal_ebb_header_block(ebb0, &mut func.dfg, &mut func.layout, &mut func.jump_tables); + ssa.seal_ebb_header_block(ebb0, &mut func); let x_var = Variable(0); let x1 = { - let cur = &mut Cursor::new(&mut func.layout); + let mut cur = FuncCursor::new(&mut func); cur.insert_ebb(ebb0); cur.insert_ebb(ebb1); cur.goto_bottom(ebb0); - func.dfg.ins(cur).iconst(I32, 1) + cur.ins().iconst(I32, 1) }; ssa.def_var(x_var, x1, block0); let mut data = JumpTableData::new(); data.push_entry(ebb1); let jt = func.create_jump_table(data); - ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block0, - ).0; + ssa.use_var(&mut func, x_var, I32, block0).0; let br_table = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).br_table(x1, jt) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().br_table(x1, jt) }; let block1 = ssa.declare_ebb_body_block(block0); let x3 = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).iconst(I32, 2) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().iconst(I32, 2) }; ssa.def_var(x_var, x3, block1); let jump_inst = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).jump(ebb1, &[]) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().jump(ebb1, &[]) }; let block2 = ssa.declare_ebb_header_block(ebb1); ssa.declare_ebb_predecessor(ebb1, block1, jump_inst); ssa.declare_ebb_predecessor(ebb1, block0, br_table); - ssa.seal_ebb_header_block(ebb1, &mut func.dfg, &mut func.layout, &mut func.jump_tables); - let x4 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block2, - ).0; + ssa.seal_ebb_header_block(ebb1, &mut func); + let x4 = ssa.use_var(&mut func, x_var, I32, block2).0; { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb1); - func.dfg.ins(cur).iadd_imm(x4, 1) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb1); + cur.ins().iadd_imm(x4, 1) }; { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb1); - func.dfg.ins(cur).return_(&[]) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb1); + cur.ins().return_(&[]) }; let flags = settings::Flags::new(&settings::builder()); match verify_function(&func, &flags) { @@ -1197,82 +920,54 @@ mod tests { let x_var = Variable(0); let y_var = Variable(1); let z_var = Variable(2); - ssa.seal_ebb_header_block(ebb0, &mut func.dfg, &mut func.layout, &mut func.jump_tables); + ssa.seal_ebb_header_block(ebb0, &mut func); let x1 = { - let cur = &mut Cursor::new(&mut func.layout); + let mut cur = FuncCursor::new(&mut func); cur.insert_ebb(ebb0); cur.insert_ebb(ebb1); cur.goto_bottom(ebb0); - func.dfg.ins(cur).iconst(I32, 0) + cur.ins().iconst(I32, 0) }; ssa.def_var(x_var, x1, block0); let y1 = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).iconst(I32, 1) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().iconst(I32, 1) }; ssa.def_var(y_var, y1, block0); let z1 = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).iconst(I32, 2) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().iconst(I32, 2) }; ssa.def_var(z_var, z1, block0); let jump_inst = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb0); - func.dfg.ins(cur).jump(ebb1, &[]) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb0); + cur.ins().jump(ebb1, &[]) }; let block1 = ssa.declare_ebb_header_block(ebb1); ssa.declare_ebb_predecessor(ebb1, block0, jump_inst); - let z2 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - z_var, - I32, - block1, - ).0; + let z2 = ssa.use_var(&mut func, z_var, I32, block1).0; assert_eq!(func.dfg.ebb_args(ebb1)[0], z2); - let x2 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block1, - ).0; + let x2 = ssa.use_var(&mut func, x_var, I32, block1).0; assert_eq!(func.dfg.ebb_args(ebb1)[1], x2); let x3 = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb1); - func.dfg.ins(cur).iadd(x2, z2) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb1); + cur.ins().iadd(x2, z2) }; ssa.def_var(x_var, x3, block1); - let x4 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - x_var, - I32, - block1, - ).0; - let y3 = ssa.use_var( - &mut func.dfg, - &mut func.layout, - &mut func.jump_tables, - y_var, - I32, - block1, - ).0; + let x4 = ssa.use_var(&mut func, x_var, I32, block1).0; + let y3 = ssa.use_var(&mut func, y_var, I32, block1).0; assert_eq!(func.dfg.ebb_args(ebb1)[2], y3); let y4 = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb1); - func.dfg.ins(cur).isub(y3, x4) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb1); + cur.ins().isub(y3, x4) }; ssa.def_var(y_var, y4, block1); let jump_inst = { - let cur = &mut Cursor::new(&mut func.layout).at_bottom(ebb1); - func.dfg.ins(cur).jump(ebb1, &[]) + let mut cur = FuncCursor::new(&mut func).at_bottom(ebb1); + cur.ins().jump(ebb1, &[]) }; ssa.declare_ebb_predecessor(ebb1, block1, jump_inst); - ssa.seal_ebb_header_block(ebb1, &mut func.dfg, &mut func.layout, &mut func.jump_tables); + ssa.seal_ebb_header_block(ebb1, &mut func); // At sealing the "z" argument disappear but the remaining "x" and "y" args have to be // in the right order. assert_eq!(func.dfg.ebb_args(ebb1)[1], y3);