From 3d317ed8e430da8b6e0a714ae78726cec8cfbf56 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Fri, 26 Jul 2024 20:08:04 +0530 Subject: [PATCH 01/10] value numbering analysis --- sway-ir/src/instruction.rs | 6 +- sway-ir/src/optimize.rs | 2 + sway-ir/src/optimize/cse.rs | 310 ++++++++++++++++++++++++++++++++++++ sway-ir/src/pass_manager.rs | 13 +- sway-ir/src/printer.rs | 3 +- sway-ir/tests/cse/cse1.ir | 17 ++ sway-ir/tests/cse/cse2.ir | 16 ++ sway-ir/tests/cse/cse3.ir | 22 +++ 8 files changed, 375 insertions(+), 14 deletions(-) create mode 100644 sway-ir/src/optimize/cse.rs create mode 100644 sway-ir/tests/cse/cse1.ir create mode 100644 sway-ir/tests/cse/cse2.ir create mode 100644 sway-ir/tests/cse/cse3.ir diff --git a/sway-ir/src/instruction.rs b/sway-ir/src/instruction.rs index 4932f4359ff..072d4ab1dfd 100644 --- a/sway-ir/src/instruction.rs +++ b/sway-ir/src/instruction.rs @@ -204,19 +204,19 @@ pub enum FuelVmInstruction { } /// Comparison operations. -#[derive(Debug, Clone, Copy, Hash)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub enum Predicate { Equal, LessThan, GreaterThan, } -#[derive(Debug, Clone, Copy, Hash)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub enum UnaryOpKind { Not, } -#[derive(Debug, Clone, Copy, Hash)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub enum BinaryOpKind { Add, Sub, diff --git a/sway-ir/src/optimize.rs b/sway-ir/src/optimize.rs index 7aeade50bfd..5b153b18603 100644 --- a/sway-ir/src/optimize.rs +++ b/sway-ir/src/optimize.rs @@ -19,6 +19,8 @@ pub mod const_demotion; pub use const_demotion::*; pub mod constants; pub use constants::*; +pub mod cse; +pub use cse::*; pub mod dce; pub use dce::*; pub mod inline; diff --git a/sway-ir/src/optimize/cse.rs b/sway-ir/src/optimize/cse.rs new file mode 100644 index 00000000000..74532a6b6a0 --- /dev/null +++ b/sway-ir/src/optimize/cse.rs @@ -0,0 +1,310 @@ +//! Value numbering based common subexpression elimination + +use itertools::Itertools; +use rustc_hash::{FxHashMap, FxHasher}; +use slotmap::Key; +use std::{ + collections::hash_map, + fmt::Debug, + hash::{Hash, Hasher}, +}; + +use crate::{ + AnalysisResults, BinaryOpKind, Context, DebugWithContext, Function, InstOp, IrError, Pass, + PassMutability, PostOrder, Predicate, ScopedPass, Type, UnaryOpKind, Value, POSTORDER_NAME, +}; + +pub const CSE_NAME: &str = "cse"; + +pub fn create_cse_pass() -> Pass { + Pass { + name: CSE_NAME, + descr: "Common subexpression elimination", + runner: ScopedPass::FunctionPass(PassMutability::Transform(cse)), + deps: vec![POSTORDER_NAME], + } +} + +#[derive(Clone, Copy, Eq, PartialEq, Hash, DebugWithContext)] +enum ValueNumber { + // Top of the lattice = Don't know = uninitialized + Top, + // Belongs to a congruence class represented by the inner value. + Number(Value), +} + +impl Debug for ValueNumber { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Top => write!(f, "Top"), + Self::Number(arg0) => write!(f, "v{:?}", arg0.0.data()), + } + } +} + +#[derive(Clone, Debug, Eq, PartialEq, Hash, DebugWithContext)] +enum Expr { + Phi(Vec), + UnaryOp { + op: UnaryOpKind, + arg: ValueNumber, + }, + BinaryOp { + op: BinaryOpKind, + arg1: ValueNumber, + arg2: ValueNumber, + }, + BitCast(ValueNumber, Type), + CastPtr(ValueNumber, Type), + Cmp(Predicate, ValueNumber, ValueNumber), + GetElemPtr { + base: ValueNumber, + elem_ptr_ty: Type, + indices: Vec, + }, + IntToPtr(ValueNumber, Type), + PtrToInt(ValueNumber, Type), +} + +/// Convert an instruction to an expression for hashing +/// Instructions that we don't handle will have their value numbers be equal to themselves. +fn instr_to_expr(context: &Context, vntable: &VNTable, instr: Value) -> Option { + match &instr.get_instruction(context).unwrap().op { + InstOp::AsmBlock(_, _) => None, + InstOp::UnaryOp { op, arg } => Some(Expr::UnaryOp { + op: *op, + arg: vntable.value_map.get(arg).cloned().unwrap(), + }), + InstOp::BinaryOp { op, arg1, arg2 } => Some(Expr::BinaryOp { + op: *op, + arg1: vntable.value_map.get(arg1).cloned().unwrap(), + arg2: vntable.value_map.get(arg2).cloned().unwrap(), + }), + InstOp::BitCast(val, ty) => Some(Expr::BitCast( + vntable.value_map.get(val).cloned().unwrap(), + *ty, + )), + InstOp::Branch(_) => None, + InstOp::Call(_, _) => None, + InstOp::CastPtr(val, ty) => Some(Expr::CastPtr( + vntable.value_map.get(val).cloned().unwrap(), + *ty, + )), + InstOp::Cmp(pred, val1, val2) => Some(Expr::Cmp( + *pred, + vntable.value_map.get(val1).cloned().unwrap(), + vntable.value_map.get(val2).cloned().unwrap(), + )), + InstOp::ConditionalBranch { .. } => None, + InstOp::ContractCall { .. } => None, + InstOp::FuelVm(_) => todo!(), + InstOp::GetLocal(_) => None, + InstOp::GetConfig(_, _) => None, + InstOp::GetElemPtr { + base, + elem_ptr_ty, + indices, + } => Some(Expr::GetElemPtr { + base: vntable.value_map.get(base).cloned().unwrap(), + elem_ptr_ty: *elem_ptr_ty, + indices: indices + .iter() + .map(|idx| vntable.value_map.get(idx).cloned().unwrap()) + .collect(), + }), + InstOp::IntToPtr(val, ty) => Some(Expr::IntToPtr( + vntable.value_map.get(val).cloned().unwrap(), + *ty, + )), + InstOp::Load(_) => None, + InstOp::MemCopyBytes { .. } => None, + InstOp::MemCopyVal { .. } => None, + InstOp::Nop => None, + InstOp::PtrToInt(val, ty) => Some(Expr::PtrToInt( + vntable.value_map.get(val).cloned().unwrap(), + *ty, + )), + InstOp::Ret(_, _) => None, + InstOp::Store { .. } => None, + } +} + +/// Convert a PHI argument to Expr +fn phi_to_expr(context: &Context, vntable: &VNTable, phi_arg: Value) -> Expr { + let phi_arg = phi_arg.get_argument(context).unwrap(); + let phi_args = phi_arg + .block + .pred_iter(context) + .map(|pred| { + let incoming_val = phi_arg + .get_val_coming_from(context, pred) + .expect("No parameter from predecessor"); + vntable.value_map.get(&incoming_val).cloned().unwrap() + }) + .collect(); + Expr::Phi(phi_args) +} + +#[derive(Default)] +struct VNTable { + value_map: FxHashMap, + expr_map: FxHashMap, +} + +impl Debug for VNTable { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "value_map:\n")?; + for (key, value) in &self.value_map { + write!(f, "\tv{:?} -> {:?}\n", key.0.data(), value)? + } + Ok(()) + } +} + +pub fn cse( + context: &mut Context, + analyses: &AnalysisResults, + function: Function, +) -> Result { + let mut vntable = VNTable::default(); + + // Function arg values map to themselves. + for arg in function.args_iter(context) { + vntable.value_map.insert(arg.1, ValueNumber::Number(arg.1)); + } + + // Initialize all instructions and constants. Constants need special treatmemt. + // They don't have PartialEq implemented. So we need to value number them manually. + // This map maps the hash of a constant value to all possible collisions of it. + let mut const_map = FxHashMap::>::default(); + for (_, inst) in function.instruction_iter(context) { + vntable.value_map.insert(inst, ValueNumber::Top); + for (const_opd_val, const_opd_const) in inst + .get_instruction(context) + .unwrap() + .op + .get_operands() + .iter() + .filter_map(|opd| opd.get_constant(context).map(|copd| (opd, copd))) + { + let mut state = FxHasher::default(); + const_opd_const.hash(&mut state); + let hash = state.finish(); + if let Some(existing_const) = const_map.get(&hash).and_then(|consts| { + consts.iter().find(|val| { + let c = val + .get_constant(context) + .expect("const_map can only contain consts"); + const_opd_const.eq(context, c) + }) + }) { + vntable + .value_map + .insert(*const_opd_val, ValueNumber::Number(*existing_const)); + } else { + const_map + .entry(hash) + .and_modify(|consts| consts.push(*const_opd_val)) + .or_insert_with(|| vec![*const_opd_val]); + vntable + .value_map + .insert(*const_opd_val, ValueNumber::Number(*const_opd_val)); + } + } + } + + // We need to iterate over the blocks in RPO. + let post_order: &PostOrder = analyses.get_analysis_result(function); + + let mut changed = true; + while changed { + changed = false; + // For each block in RPO: + for (block_idx, block) in post_order.po_to_block.iter().rev().enumerate() { + // Process PHIs and then the other instructions. + if block_idx != 0 { + // Entry block arguments are not PHIs. + for (phi, expr_opt) in block + .arg_iter(context) + .map(|arg| (*arg, Some(phi_to_expr(context, &vntable, *arg)))) + .collect_vec() + { + let expr = expr_opt.expect("PHIs must always translate to a valid Expr"); + // We first try to see if PHIs can be simplified into a single value. + let vn = { + let Expr::Phi(ref phi_args) = expr else { + panic!("Expr must be a PHI") + }; + phi_args + .iter() + .map(|vn| Some(*vn)) + .reduce(|vn1, vn2| { + // Here `None` indicates Bottom of the lattice. + if let (Some(vn1), Some(vn2)) = (vn1, vn2) { + match (vn1, vn2) { + (ValueNumber::Top, ValueNumber::Top) => { + Some(ValueNumber::Top) + } + (ValueNumber::Top, ValueNumber::Number(vn)) + | (ValueNumber::Number(vn), ValueNumber::Top) => { + Some(ValueNumber::Number(vn)) + } + (ValueNumber::Number(vn1), ValueNumber::Number(vn2)) => { + (vn1 == vn2).then(|| ValueNumber::Number(vn1)) + } + } + } else { + None + } + }) + .flatten() + // The PHI couldn't be simplifed to a single ValueNumber. + // lookup(expr, x) + .unwrap_or_else(|| match vntable.expr_map.entry(expr) { + hash_map::Entry::Occupied(occ) => *occ.get(), + hash_map::Entry::Vacant(vac) => { + *(vac.insert(ValueNumber::Number(phi))) + } + }) + }; + match vntable.value_map.entry(phi) { + hash_map::Entry::Occupied(occ) if *occ.get() == vn => {} + _ => { + changed = true; + vntable.value_map.insert(phi, vn); + } + } + } + } + + for (inst, expr_opt) in block + .instruction_iter(context) + .map(|instr| (instr, instr_to_expr(context, &vntable, instr))) + .collect_vec() + { + // lookup(expr, x) + let vn = if let Some(expr) = expr_opt { + match vntable.expr_map.entry(expr) { + hash_map::Entry::Occupied(occ) => *occ.get(), + hash_map::Entry::Vacant(vac) => *(vac.insert(ValueNumber::Number(inst))), + } + } else { + // Instructions that always map to their own value number + // (i.e., they can never be equal to some other instruction). + ValueNumber::Number(inst) + }; + match vntable.value_map.entry(inst) { + hash_map::Entry::Occupied(occ) if *occ.get() == vn => {} + _ => { + changed = true; + vntable.value_map.insert(inst, vn); + } + } + } + } + vntable.expr_map.clear(); + } + + dbg!(vntable); + Ok(false) +} diff --git a/sway-ir/src/pass_manager.rs b/sway-ir/src/pass_manager.rs index 3aafda779ad..7c63ae68077 100644 --- a/sway-ir/src/pass_manager.rs +++ b/sway-ir/src/pass_manager.rs @@ -1,14 +1,5 @@ use crate::{ - create_arg_demotion_pass, create_const_demotion_pass, create_const_folding_pass, - create_dce_pass, create_dom_fronts_pass, create_dominators_pass, create_escaped_symbols_pass, - create_fn_dce_pass, create_fn_dedup_debug_profile_pass, create_fn_dedup_release_profile_pass, - create_fn_inline_pass, create_mem2reg_pass, create_memcpyopt_pass, create_misc_demotion_pass, - create_module_printer_pass, create_module_verifier_pass, create_postorder_pass, - create_ret_demotion_pass, create_simplify_cfg_pass, create_sroa_pass, Context, Function, - IrError, Module, ARG_DEMOTION_NAME, CONST_DEMOTION_NAME, CONST_FOLDING_NAME, DCE_NAME, - FN_DCE_NAME, FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, FN_INLINE_NAME, - MEM2REG_NAME, MEMCPYOPT_NAME, MISC_DEMOTION_NAME, RET_DEMOTION_NAME, SIMPLIFY_CFG_NAME, - SROA_NAME, + create_arg_demotion_pass, create_const_demotion_pass, create_const_folding_pass, create_cse_pass, create_dce_pass, create_dom_fronts_pass, create_dominators_pass, create_escaped_symbols_pass, create_fn_dce_pass, create_fn_dedup_debug_profile_pass, create_fn_dedup_release_profile_pass, create_fn_inline_pass, create_mem2reg_pass, create_memcpyopt_pass, create_misc_demotion_pass, create_module_printer_pass, create_module_verifier_pass, create_postorder_pass, create_ret_demotion_pass, create_simplify_cfg_pass, create_sroa_pass, Context, Function, IrError, Module, ARG_DEMOTION_NAME, CONST_DEMOTION_NAME, CONST_FOLDING_NAME, CSE_NAME, DCE_NAME, FN_DCE_NAME, FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, FN_INLINE_NAME, MEM2REG_NAME, MEMCPYOPT_NAME, MISC_DEMOTION_NAME, RET_DEMOTION_NAME, SIMPLIFY_CFG_NAME, SROA_NAME }; use downcast_rs::{impl_downcast, Downcast}; use rustc_hash::FxHashMap; @@ -399,6 +390,7 @@ pub fn register_known_passes(pm: &mut PassManager) { pm.register(create_simplify_cfg_pass()); pm.register(create_fn_dce_pass()); pm.register(create_dce_pass()); + pm.register(create_cse_pass()); pm.register(create_arg_demotion_pass()); pm.register(create_const_demotion_pass()); pm.register(create_ret_demotion_pass()); @@ -417,6 +409,7 @@ pub fn create_o1_pass_group() -> PassGroup { o1.append_pass(FN_DCE_NAME); o1.append_pass(FN_INLINE_NAME); o1.append_pass(CONST_FOLDING_NAME); + o1.append_pass(CSE_NAME); o1.append_pass(SIMPLIFY_CFG_NAME); o1.append_pass(CONST_FOLDING_NAME); o1.append_pass(SIMPLIFY_CFG_NAME); diff --git a/sway-ir/src/printer.rs b/sway-ir/src/printer.rs index 19b90c92861..80f336c8d35 100644 --- a/sway-ir/src/printer.rs +++ b/sway-ir/src/printer.rs @@ -6,6 +6,7 @@ use std::collections::{BTreeMap, HashMap}; +use slotmap::Key; use sway_types::SourceEngine; use crate::{ @@ -1242,7 +1243,7 @@ impl Namer { fn default_name(&mut self, value: &Value) -> String { self.names.get(value).cloned().unwrap_or_else(|| { - let new_name = format!("v{}", self.next_value_idx); + let new_name = format!("v{:?}", value.0.data()); self.next_value_idx += 1; self.names.insert(*value, new_name.clone()); new_name diff --git a/sway-ir/tests/cse/cse1.ir b/sway-ir/tests/cse/cse1.ir new file mode 100644 index 00000000000..4ba901a8b80 --- /dev/null +++ b/sway-ir/tests/cse/cse1.ir @@ -0,0 +1,17 @@ +// regex: ID=[[:alpha:]0-9]+ + +script { + fn main() -> bool { + entry(): + v0 = const u64 11 + v1 = const u64 0 + v3 = add v0, v1 + v4 = add v0, v1 + v10 = const u64 10 + v11 = add v1, v0 + v2 = cmp eq v3 v4 + v3 = cmp eq v11 v3 + v4 = cmp eq v2 v3 + ret bool v4 + } +} diff --git a/sway-ir/tests/cse/cse2.ir b/sway-ir/tests/cse/cse2.ir new file mode 100644 index 00000000000..e268e03903c --- /dev/null +++ b/sway-ir/tests/cse/cse2.ir @@ -0,0 +1,16 @@ +// regex: ID=[[:alpha:]0-9]+ + +script { + fn main() -> bool { + entry(): + v0 = const u64 11 + v0_dup = const u64 11 + v1 = const u64 0 + v3 = add v0, v1 + v4 = add v0, v1 + v5 = sub v0, v3 + v6 = sub v0_dup, v4 + v2 = cmp eq v5 v6 + ret bool v2 + } +} diff --git a/sway-ir/tests/cse/cse3.ir b/sway-ir/tests/cse/cse3.ir new file mode 100644 index 00000000000..71994e9e408 --- /dev/null +++ b/sway-ir/tests/cse/cse3.ir @@ -0,0 +1,22 @@ +script { + entry fn main(a: u64, b: u64) -> () { + entry(a: u64, b: u64): + v5v1 = add a, b + v6v1 = const u64 0 + br while(v6v1, v5v1) + + while(v3v1: u64, v4v1: u64): + v8v1 = cmp lt v3v1 v4v1 + cbr v8v1, while_body(), end_while() + + while_body(): + v10v1 = add a, b + v11v1 = const u64 1 + v12v1 = add v3v1, v11v1 + br while(v12v1, v10v1) + + end_while(): + v14v1 = const unit () + ret () v14v1 + } +} From f5a48de8eb23e2057b5424ecf0fea88f275c733d Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Mon, 29 Jul 2024 12:13:53 +0530 Subject: [PATCH 02/10] initialize PHIs too --- sway-ir/src/optimize/cse.rs | 15 +++++++++++---- sway-ir/src/pass_manager.rs | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/sway-ir/src/optimize/cse.rs b/sway-ir/src/optimize/cse.rs index 74532a6b6a0..015b268331f 100644 --- a/sway-ir/src/optimize/cse.rs +++ b/sway-ir/src/optimize/cse.rs @@ -10,8 +10,9 @@ use std::{ }; use crate::{ - AnalysisResults, BinaryOpKind, Context, DebugWithContext, Function, InstOp, IrError, Pass, - PassMutability, PostOrder, Predicate, ScopedPass, Type, UnaryOpKind, Value, POSTORDER_NAME, + block, function_print, AnalysisResults, BinaryOpKind, Context, DebugWithContext, Function, + InstOp, IrError, Pass, PassMutability, PostOrder, Predicate, ScopedPass, Type, UnaryOpKind, + Value, POSTORDER_NAME, }; pub const CSE_NAME: &str = "cse"; @@ -97,7 +98,7 @@ fn instr_to_expr(context: &Context, vntable: &VNTable, instr: Value) -> Option None, InstOp::ContractCall { .. } => None, - InstOp::FuelVm(_) => todo!(), + InstOp::FuelVm(_) => None, InstOp::GetLocal(_) => None, InstOp::GetConfig(_, _) => None, InstOp::GetElemPtr { @@ -173,6 +174,13 @@ pub fn cse( vntable.value_map.insert(arg.1, ValueNumber::Number(arg.1)); } + // Map all other arg values map to Top. + for block in function.block_iter(context).skip(1) { + for arg in block.arg_iter(context) { + vntable.value_map.insert(*arg, ValueNumber::Top); + } + } + // Initialize all instructions and constants. Constants need special treatmemt. // They don't have PartialEq implemented. So we need to value number them manually. // This map maps the hash of a constant value to all possible collisions of it. @@ -305,6 +313,5 @@ pub fn cse( vntable.expr_map.clear(); } - dbg!(vntable); Ok(false) } diff --git a/sway-ir/src/pass_manager.rs b/sway-ir/src/pass_manager.rs index 7c63ae68077..2f70aff256e 100644 --- a/sway-ir/src/pass_manager.rs +++ b/sway-ir/src/pass_manager.rs @@ -409,8 +409,8 @@ pub fn create_o1_pass_group() -> PassGroup { o1.append_pass(FN_DCE_NAME); o1.append_pass(FN_INLINE_NAME); o1.append_pass(CONST_FOLDING_NAME); - o1.append_pass(CSE_NAME); o1.append_pass(SIMPLIFY_CFG_NAME); + o1.append_pass(CSE_NAME); o1.append_pass(CONST_FOLDING_NAME); o1.append_pass(SIMPLIFY_CFG_NAME); o1.append_pass(FN_DCE_NAME); From 4a1cf031fec5ca8972d12a47def91e527dcedba2 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Wed, 14 Aug 2024 14:30:06 +0530 Subject: [PATCH 03/10] Add CSE optimization and update unit tests --- sway-ir/src/analysis/dominator.rs | 51 +++++++++---- sway-ir/src/optimize/cse.rs | 118 +++++++++++++++++++++++++++--- sway-ir/src/optimize/mem2reg.rs | 4 +- sway-ir/src/pass_manager.rs | 11 ++- sway-ir/src/printer.rs | 3 +- sway-ir/tests/cse/cse1.ir | 4 + sway-ir/tests/cse/cse2.ir | 6 ++ sway-ir/tests/cse/cse3.ir | 31 +++++--- sway-ir/tests/tests.rs | 28 +++++-- 9 files changed, 206 insertions(+), 50 deletions(-) diff --git a/sway-ir/src/analysis/dominator.rs b/sway-ir/src/analysis/dominator.rs index 72de08fb690..9dfe35a310f 100644 --- a/sway-ir/src/analysis/dominator.rs +++ b/sway-ir/src/analysis/dominator.rs @@ -28,7 +28,8 @@ impl DomTreeNode { } // The dominator tree is represented by mapping each Block to its DomTreeNode. -pub type DomTree = FxIndexMap; +#[derive(Default)] +pub struct DomTree(FxIndexMap); impl AnalysisResultT for DomTree {} // Dominance frontier sets. @@ -120,11 +121,11 @@ fn compute_dom_tree( let entry = function.get_entry_block(context); // This is to make the algorithm happy. It'll be changed to None later. - dom_tree.insert(entry, DomTreeNode::new(Some(entry))); + dom_tree.0.insert(entry, DomTreeNode::new(Some(entry))); // initialize the dominators tree. This allows us to do dom_tree[b] fearlessly. // Note that we just previously initialized "entry", so we skip that here. for b in po.po_to_block.iter().take(po.po_to_block.len() - 1) { - dom_tree.insert(*b, DomTreeNode::new(None)); + dom_tree.0.insert(*b, DomTreeNode::new(None)); } let mut changed = true; @@ -149,12 +150,12 @@ fn compute_dom_tree( .pred_iter(context) .filter(|p| **p != picked_pred && po.block_to_po.contains_key(p)) { - if dom_tree[p].parent.is_some() { + if dom_tree.0[p].parent.is_some() { // if doms[p] already calculated new_idom = intersect(po, &dom_tree, *p, new_idom); } } - let b_node = dom_tree.get_mut(b).unwrap(); + let b_node = dom_tree.0.get_mut(b).unwrap(); match b_node.parent { Some(idom) if idom == new_idom => {} _ => { @@ -175,29 +176,49 @@ fn compute_dom_tree( ) -> Block { while finger1 != finger2 { while po.block_to_po[&finger1] < po.block_to_po[&finger2] { - finger1 = dom_tree[&finger1].parent.unwrap(); + finger1 = dom_tree.0[&finger1].parent.unwrap(); } while po.block_to_po[&finger2] < po.block_to_po[&finger1] { - finger2 = dom_tree[&finger2].parent.unwrap(); + finger2 = dom_tree.0[&finger2].parent.unwrap(); } } finger1 } // Fix the root. - dom_tree.get_mut(&entry).unwrap().parent = None; + dom_tree.0.get_mut(&entry).unwrap().parent = None; // Build the children. let child_parent: Vec<_> = dom_tree + .0 .iter() .filter_map(|(n, n_node)| n_node.parent.map(|n_parent| (*n, n_parent))) .collect(); for (child, parent) in child_parent { - dom_tree.get_mut(&parent).unwrap().children.push(child); + dom_tree.0.get_mut(&parent).unwrap().children.push(child); } Ok(Box::new(dom_tree)) } +impl DomTree { + /// Does `dominator` dominate `dominatee`? + pub fn dominates(&self, dominator: Block, dominatee: Block) -> bool { + let mut node_opt = Some(dominatee); + while let Some(node) = node_opt { + if node == dominator { + return true; + } + node_opt = self.0[&node].parent; + } + false + } + + /// Get an iterator over the childre nodes + pub fn children(&self, node: Block) -> impl Iterator + '_ { + self.0[&node].children.iter().cloned() + } +} + pub const DOM_FRONTS_NAME: &str = "dominance-frontiers"; pub fn create_dom_fronts_pass() -> Pass { @@ -217,23 +238,23 @@ fn compute_dom_fronts( ) -> Result { let dom_tree: &DomTree = analyses.get_analysis_result(function); let mut res = DomFronts::default(); - for (b, _) in dom_tree.iter() { + for (b, _) in dom_tree.0.iter() { res.insert(*b, IndexSet::default()); } // for all nodes, b - for (b, _) in dom_tree.iter() { + for (b, _) in dom_tree.0.iter() { // if the number of predecessors of b >= 2 if b.num_predecessors(context) > 1 { // unwrap() is safe as b is not "entry", and hence must have idom. - let b_idom = dom_tree[b].parent.unwrap(); + let b_idom = dom_tree.0[b].parent.unwrap(); // for all (reachable) predecessors, p, of b - for p in b.pred_iter(context).filter(|&p| dom_tree.contains_key(p)) { + for p in b.pred_iter(context).filter(|&p| dom_tree.0.contains_key(p)) { let mut runner = *p; while runner != b_idom { // add b to runner’s dominance frontier set res.get_mut(&runner).unwrap().insert(*b); - runner = dom_tree[&runner].parent.unwrap(); + runner = dom_tree.0[&runner].parent.unwrap(); } } } @@ -244,7 +265,7 @@ fn compute_dom_fronts( /// Print dominator tree in the graphviz dot format. pub fn print_dot(context: &Context, func_name: &str, dom_tree: &DomTree) -> String { let mut res = format!("digraph {func_name} {{\n"); - for (b, idom) in dom_tree.iter() { + for (b, idom) in dom_tree.0.iter() { if let Some(idom) = idom.parent { let _ = writeln!( res, diff --git a/sway-ir/src/optimize/cse.rs b/sway-ir/src/optimize/cse.rs index 015b268331f..b25a929e3ba 100644 --- a/sway-ir/src/optimize/cse.rs +++ b/sway-ir/src/optimize/cse.rs @@ -1,7 +1,9 @@ -//! Value numbering based common subexpression elimination +//! Value numbering based common subexpression elimination. +//! Reference: Value Driven Redundancy Elimination - Loren Taylor Simpson. +use core::panic; use itertools::Itertools; -use rustc_hash::{FxHashMap, FxHasher}; +use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; use slotmap::Key; use std::{ collections::hash_map, @@ -10,9 +12,9 @@ use std::{ }; use crate::{ - block, function_print, AnalysisResults, BinaryOpKind, Context, DebugWithContext, Function, - InstOp, IrError, Pass, PassMutability, PostOrder, Predicate, ScopedPass, Type, UnaryOpKind, - Value, POSTORDER_NAME, + AnalysisResults, BinaryOpKind, Context, DebugWithContext, DomTree, Function, InstOp, IrError, + Pass, PassMutability, PostOrder, Predicate, ScopedPass, Type, UnaryOpKind, Value, + DOMINATORS_NAME, POSTORDER_NAME, }; pub const CSE_NAME: &str = "cse"; @@ -22,7 +24,7 @@ pub fn create_cse_pass() -> Pass { name: CSE_NAME, descr: "Common subexpression elimination", runner: ScopedPass::FunctionPass(PassMutability::Transform(cse)), - deps: vec![POSTORDER_NAME], + deps: vec![POSTORDER_NAME, DOMINATORS_NAME], } } @@ -154,14 +156,49 @@ struct VNTable { impl Debug for VNTable { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "value_map:\n")?; - for (key, value) in &self.value_map { - write!(f, "\tv{:?} -> {:?}\n", key.0.data(), value)? - } + writeln!(f, "value_map:")?; + self.value_map.iter().for_each(|(key, value)| { + writeln!(f, "\tv{:?} -> {:?}", key.0.data(), value).expect("writeln! failed"); + }); Ok(()) } } +/// Wrapper around [DomTree::dominates] to work at instruction level. +/// Does `inst1` dominate `inst2` ? +fn dominates(context: &Context, dom_tree: &DomTree, inst1: Value, inst2: Value) -> bool { + let block1 = match &context.values[inst1.0].value { + crate::ValueDatum::Argument(arg) => arg.block, + crate::ValueDatum::Constant(_) => { + panic!("Shouldn't be querying dominance info for constants") + } + crate::ValueDatum::Instruction(i) => i.parent, + }; + let block2 = match &context.values[inst2.0].value { + crate::ValueDatum::Argument(arg) => arg.block, + crate::ValueDatum::Constant(_) => { + panic!("Shouldn't be querying dominance info for constants") + } + crate::ValueDatum::Instruction(i) => i.parent, + }; + + if block1 == block2 { + let inst1_idx = block1 + .instruction_iter(context) + .position(|inst| inst == inst1) + // Not found indicates a block argument + .unwrap_or(0); + let inst2_idx = block1 + .instruction_iter(context) + .position(|inst| inst == inst2) + // Not found indicates a block argument + .unwrap_or(0); + inst1_idx < inst2_idx + } else { + dom_tree.dominates(block1, block2) + } +} + pub fn cse( context: &mut Context, analyses: &AnalysisResults, @@ -224,6 +261,7 @@ pub fn cse( // We need to iterate over the blocks in RPO. let post_order: &PostOrder = analyses.get_analysis_result(function); + // RPO based value number (Sec 4.2). let mut changed = true; while changed { changed = false; @@ -258,7 +296,7 @@ pub fn cse( Some(ValueNumber::Number(vn)) } (ValueNumber::Number(vn1), ValueNumber::Number(vn2)) => { - (vn1 == vn2).then(|| ValueNumber::Number(vn1)) + (vn1 == vn2).then_some(ValueNumber::Number(vn1)) } } } else { @@ -313,5 +351,61 @@ pub fn cse( vntable.expr_map.clear(); } - Ok(false) + // create a partition of congruent (equal) values. + let mut partition = FxHashMap::>::default(); + vntable.value_map.iter().for_each(|(v, vn)| { + // If v is a constant or its value number is itself, don't add to the partition. + // The latter condition is so that we have only > 1 sized partitions. + if v.is_constant(context) + || matches!(vn, ValueNumber::Top) + || matches!(vn, ValueNumber::Number(v2) if v == v2) + { + return; + } + partition + .entry(*vn) + .and_modify(|part| { + part.insert(*v); + }) + .or_insert(vec![*v].into_iter().collect()); + }); + + // For convenience, now add back back `v` into `partition[VN[v]]` if it isn't already there. + partition.iter_mut().for_each(|(vn, v_part)| { + let ValueNumber::Number(v) = vn else { + panic!("We cannot have Top at this point"); + }; + v_part.insert(*v); + assert!( + v_part.len() > 1, + "We've only created partitions with size greater than 1" + ); + }); + + // There are two ways to replace congruent values (see the paper cited, Sec 5). + // 1. Dominator based. If v1 and v2 are equal, v1 dominates v2, we just remove v2 + // and replace its uses with v1. Simple, and what we're going to do. + // 2. AVAIL based. More powerful, but also requires a data-flow-analysis for AVAIL + // and later on, mem2reg again since replacements will need breaking SSA. + let dom_tree: &DomTree = analyses.get_analysis_result(function); + let mut replace_map = FxHashMap::::default(); + let mut modified = false; + // Check every set in the partition. + partition.iter().for_each(|(_leader, vals)| { + // Iterate over every pair of values, checking if one can replace the other. + for v_pair in vals.iter().combinations(2) { + let (v1, v2) = (*v_pair[0], *v_pair[1]); + if dominates(context, dom_tree, v1, v2) { + modified = true; + replace_map.insert(v2, v1); + } else if dominates(context, dom_tree, v2, v1) { + modified = true; + replace_map.insert(v1, v2); + } + } + }); + + function.replace_values(context, &replace_map, None); + + Ok(modified) } diff --git a/sway-ir/src/optimize/mem2reg.rs b/sway-ir/src/optimize/mem2reg.rs index 0a3484cec4a..c7c8a5b847b 100644 --- a/sway-ir/src/optimize/mem2reg.rs +++ b/sway-ir/src/optimize/mem2reg.rs @@ -319,12 +319,12 @@ pub fn promote_to_registers( } // Process dominator children. - for child in dom_tree[&node].children.iter() { + for child in dom_tree.children(node) { record_rewrites( context, function, dom_tree, - *child, + child, safe_locals, phi_to_local, name_stack, diff --git a/sway-ir/src/pass_manager.rs b/sway-ir/src/pass_manager.rs index 2f70aff256e..1e2ce28c849 100644 --- a/sway-ir/src/pass_manager.rs +++ b/sway-ir/src/pass_manager.rs @@ -1,5 +1,14 @@ use crate::{ - create_arg_demotion_pass, create_const_demotion_pass, create_const_folding_pass, create_cse_pass, create_dce_pass, create_dom_fronts_pass, create_dominators_pass, create_escaped_symbols_pass, create_fn_dce_pass, create_fn_dedup_debug_profile_pass, create_fn_dedup_release_profile_pass, create_fn_inline_pass, create_mem2reg_pass, create_memcpyopt_pass, create_misc_demotion_pass, create_module_printer_pass, create_module_verifier_pass, create_postorder_pass, create_ret_demotion_pass, create_simplify_cfg_pass, create_sroa_pass, Context, Function, IrError, Module, ARG_DEMOTION_NAME, CONST_DEMOTION_NAME, CONST_FOLDING_NAME, CSE_NAME, DCE_NAME, FN_DCE_NAME, FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, FN_INLINE_NAME, MEM2REG_NAME, MEMCPYOPT_NAME, MISC_DEMOTION_NAME, RET_DEMOTION_NAME, SIMPLIFY_CFG_NAME, SROA_NAME + create_arg_demotion_pass, create_const_demotion_pass, create_const_folding_pass, + create_cse_pass, create_dce_pass, create_dom_fronts_pass, create_dominators_pass, + create_escaped_symbols_pass, create_fn_dce_pass, create_fn_dedup_debug_profile_pass, + create_fn_dedup_release_profile_pass, create_fn_inline_pass, create_mem2reg_pass, + create_memcpyopt_pass, create_misc_demotion_pass, create_module_printer_pass, + create_module_verifier_pass, create_postorder_pass, create_ret_demotion_pass, + create_simplify_cfg_pass, create_sroa_pass, Context, Function, IrError, Module, + ARG_DEMOTION_NAME, CONST_DEMOTION_NAME, CONST_FOLDING_NAME, CSE_NAME, DCE_NAME, FN_DCE_NAME, + FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, FN_INLINE_NAME, MEM2REG_NAME, + MEMCPYOPT_NAME, MISC_DEMOTION_NAME, RET_DEMOTION_NAME, SIMPLIFY_CFG_NAME, SROA_NAME, }; use downcast_rs::{impl_downcast, Downcast}; use rustc_hash::FxHashMap; diff --git a/sway-ir/src/printer.rs b/sway-ir/src/printer.rs index 80f336c8d35..19b90c92861 100644 --- a/sway-ir/src/printer.rs +++ b/sway-ir/src/printer.rs @@ -6,7 +6,6 @@ use std::collections::{BTreeMap, HashMap}; -use slotmap::Key; use sway_types::SourceEngine; use crate::{ @@ -1243,7 +1242,7 @@ impl Namer { fn default_name(&mut self, value: &Value) -> String { self.names.get(value).cloned().unwrap_or_else(|| { - let new_name = format!("v{:?}", value.0.data()); + let new_name = format!("v{}", self.next_value_idx); self.next_value_idx += 1; self.names.insert(*value, new_name.clone()); new_name diff --git a/sway-ir/tests/cse/cse1.ir b/sway-ir/tests/cse/cse1.ir index 4ba901a8b80..687c12f8d76 100644 --- a/sway-ir/tests/cse/cse1.ir +++ b/sway-ir/tests/cse/cse1.ir @@ -1,14 +1,18 @@ // regex: ID=[[:alpha:]0-9]+ +// regex: VAR=v\d+ script { fn main() -> bool { entry(): v0 = const u64 11 v1 = const u64 0 + // check: $(v3=$VAR) = add v3 = add v0, v1 + // check: $(v4=$VAR) = add v4 = add v0, v1 v10 = const u64 10 v11 = add v1, v0 + // check: cmp eq $v3 $v3 v2 = cmp eq v3 v4 v3 = cmp eq v11 v3 v4 = cmp eq v2 v3 diff --git a/sway-ir/tests/cse/cse2.ir b/sway-ir/tests/cse/cse2.ir index e268e03903c..ec609f74d60 100644 --- a/sway-ir/tests/cse/cse2.ir +++ b/sway-ir/tests/cse/cse2.ir @@ -1,4 +1,5 @@ // regex: ID=[[:alpha:]0-9]+ +// regex: VAR=v\d+ script { fn main() -> bool { @@ -6,10 +7,15 @@ script { v0 = const u64 11 v0_dup = const u64 11 v1 = const u64 0 + // check: $(v3=$VAR) = add v3 = add v0, v1 + // check: $(v4=$VAR) = add v4 = add v0, v1 + // check: $(v5=$VAR) = sub v5 = sub v0, v3 + // check: $(v6=$VAR) = sub v6 = sub v0_dup, v4 + // check: cmp eq $v5 $v5 v2 = cmp eq v5 v6 ret bool v2 } diff --git a/sway-ir/tests/cse/cse3.ir b/sway-ir/tests/cse/cse3.ir index 71994e9e408..89a3df2fdd3 100644 --- a/sway-ir/tests/cse/cse3.ir +++ b/sway-ir/tests/cse/cse3.ir @@ -1,22 +1,29 @@ +// regex: ID=[[:alpha:]0-9]+ +// regex: VAR=v\d+ + script { entry fn main(a: u64, b: u64) -> () { entry(a: u64, b: u64): - v5v1 = add a, b - v6v1 = const u64 0 - br while(v6v1, v5v1) + // check: $(v5=$VAR) = add a, b + v5 = add a, b + v6 = const u64 0 + br while(v6, v5) - while(v3v1: u64, v4v1: u64): - v8v1 = cmp lt v3v1 v4v1 - cbr v8v1, while_body(), end_while() + while(v3: u64, v4: u64): + // check: cmp lt $VAR $v5 + v8 = cmp lt v3 v4 + cbr v8, while_body(), end_while() while_body(): - v10v1 = add a, b - v11v1 = const u64 1 - v12v1 = add v3v1, v11v1 - br while(v12v1, v10v1) + // check: $(v10=$VAR) = add a, b + v10 = add a, b + v11 = const u64 1 + v12 = add v3, v11 + // check: br while($VAR, $v5) + br while(v12, v10) end_while(): - v14v1 = const unit () - ret () v14v1 + v14 = const unit () + ret () v14 } } diff --git a/sway-ir/tests/tests.rs b/sway-ir/tests/tests.rs index 54bc88176c4..efbfc8ba1b0 100644 --- a/sway-ir/tests/tests.rs +++ b/sway-ir/tests/tests.rs @@ -3,12 +3,12 @@ use std::path::PathBuf; use itertools::Itertools; use sway_ir::{ create_arg_demotion_pass, create_const_demotion_pass, create_const_folding_pass, - create_dce_pass, create_dom_fronts_pass, create_dominators_pass, create_escaped_symbols_pass, - create_mem2reg_pass, create_memcpyopt_pass, create_misc_demotion_pass, create_postorder_pass, - create_ret_demotion_pass, create_simplify_cfg_pass, metadata_to_inline, optimize as opt, - register_known_passes, Context, ExperimentalFlags, Function, IrError, PassGroup, PassManager, - Value, DCE_NAME, FN_DCE_NAME, FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, - MEM2REG_NAME, SROA_NAME, + create_cse_pass, create_dce_pass, create_dom_fronts_pass, create_dominators_pass, + create_escaped_symbols_pass, create_mem2reg_pass, create_memcpyopt_pass, + create_misc_demotion_pass, create_postorder_pass, create_ret_demotion_pass, + create_simplify_cfg_pass, metadata_to_inline, optimize as opt, register_known_passes, Context, + ExperimentalFlags, Function, IrError, PassGroup, PassManager, Value, DCE_NAME, FN_DCE_NAME, + FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, MEM2REG_NAME, SROA_NAME, }; use sway_types::SourceEngine; @@ -266,6 +266,22 @@ fn dce() { // ------------------------------------------------------------------------------------------------- +#[allow(clippy::needless_collect)] +#[test] +fn cse() { + run_tests("cse", |_first_line, ir: &mut Context| { + let mut pass_mgr = PassManager::default(); + let mut pass_group = PassGroup::default(); + pass_mgr.register(create_postorder_pass()); + pass_mgr.register(create_dominators_pass()); + let pass = pass_mgr.register(create_cse_pass()); + pass_group.append_pass(pass); + pass_mgr.run(ir, &pass_group).unwrap() + }) +} + +// ------------------------------------------------------------------------------------------------- + #[allow(clippy::needless_collect)] #[test] fn mem2reg() { From 504783cd173ae395e3405645be9d83f2a732c253 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Thu, 15 Aug 2024 16:41:12 +0530 Subject: [PATCH 04/10] do not replace consts --- sway-ir/src/optimize/cse.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sway-ir/src/optimize/cse.rs b/sway-ir/src/optimize/cse.rs index b25a929e3ba..783925ae5c9 100644 --- a/sway-ir/src/optimize/cse.rs +++ b/sway-ir/src/optimize/cse.rs @@ -12,9 +12,9 @@ use std::{ }; use crate::{ - AnalysisResults, BinaryOpKind, Context, DebugWithContext, DomTree, Function, InstOp, IrError, - Pass, PassMutability, PostOrder, Predicate, ScopedPass, Type, UnaryOpKind, Value, - DOMINATORS_NAME, POSTORDER_NAME, + function_print, AnalysisResults, BinaryOpKind, Context, DebugWithContext, DomTree, Function, + InstOp, IrError, Pass, PassMutability, PostOrder, Predicate, ScopedPass, Type, UnaryOpKind, + Value, DOMINATORS_NAME, POSTORDER_NAME, }; pub const CSE_NAME: &str = "cse"; @@ -177,6 +177,7 @@ fn dominates(context: &Context, dom_tree: &DomTree, inst1: Value, inst2: Value) let block2 = match &context.values[inst2.0].value { crate::ValueDatum::Argument(arg) => arg.block, crate::ValueDatum::Constant(_) => { + dbg!(inst1, inst2); panic!("Shouldn't be querying dominance info for constants") } crate::ValueDatum::Instruction(i) => i.parent, @@ -204,6 +205,9 @@ pub fn cse( analyses: &AnalysisResults, function: Function, ) -> Result { + if function.get_name(context) == "sha256_6" { + function_print(context, function); + } let mut vntable = VNTable::default(); // Function arg values map to themselves. @@ -358,7 +362,7 @@ pub fn cse( // The latter condition is so that we have only > 1 sized partitions. if v.is_constant(context) || matches!(vn, ValueNumber::Top) - || matches!(vn, ValueNumber::Number(v2) if v == v2) + || matches!(vn, ValueNumber::Number(v2) if (v == v2 || v2.is_constant(context))) { return; } From 10561bfdc8d6b4da596b948e5b3f2dfc2c5f8d57 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Thu, 15 Aug 2024 16:46:14 +0530 Subject: [PATCH 05/10] spell fix --- sway-ir/src/optimize/cse.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sway-ir/src/optimize/cse.rs b/sway-ir/src/optimize/cse.rs index 783925ae5c9..0c3925c1e72 100644 --- a/sway-ir/src/optimize/cse.rs +++ b/sway-ir/src/optimize/cse.rs @@ -308,7 +308,7 @@ pub fn cse( } }) .flatten() - // The PHI couldn't be simplifed to a single ValueNumber. + // The PHI couldn't be simplified to a single ValueNumber. // lookup(expr, x) .unwrap_or_else(|| match vntable.expr_map.entry(expr) { hash_map::Entry::Occupied(occ) => *occ.get(), From 03963c5983b33ed4e3c4b0722c7370764844bb87 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Fri, 16 Aug 2024 21:00:09 +0530 Subject: [PATCH 06/10] Should not combine 2 PHIs, they may be in different loops --- sway-ir/src/optimize/cse.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/sway-ir/src/optimize/cse.rs b/sway-ir/src/optimize/cse.rs index 0c3925c1e72..3c3d0eaab70 100644 --- a/sway-ir/src/optimize/cse.rs +++ b/sway-ir/src/optimize/cse.rs @@ -158,7 +158,9 @@ impl Debug for VNTable { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { writeln!(f, "value_map:")?; self.value_map.iter().for_each(|(key, value)| { - writeln!(f, "\tv{:?} -> {:?}", key.0.data(), value).expect("writeln! failed"); + if format!("v{:?}", key.0.data()) == "v620v3" { + writeln!(f, "\tv{:?} -> {:?}", key.0.data(), value).expect("writeln! failed"); + } }); Ok(()) } @@ -309,14 +311,9 @@ pub fn cse( }) .flatten() // The PHI couldn't be simplified to a single ValueNumber. - // lookup(expr, x) - .unwrap_or_else(|| match vntable.expr_map.entry(expr) { - hash_map::Entry::Occupied(occ) => *occ.get(), - hash_map::Entry::Vacant(vac) => { - *(vac.insert(ValueNumber::Number(phi))) - } - }) + .unwrap_or_else(|| ValueNumber::Number(phi)) }; + match vntable.value_map.entry(phi) { hash_map::Entry::Occupied(occ) if *occ.get() == vn => {} _ => { @@ -355,6 +352,8 @@ pub fn cse( vntable.expr_map.clear(); } + dbg!(&vntable); + // create a partition of congruent (equal) values. let mut partition = FxHashMap::>::default(); vntable.value_map.iter().for_each(|(v, vn)| { From 14528883b72f28be55452181f2819e9db311fea8 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Fri, 16 Aug 2024 21:00:56 +0530 Subject: [PATCH 07/10] clippy fix --- sway-ir/src/optimize/cse.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sway-ir/src/optimize/cse.rs b/sway-ir/src/optimize/cse.rs index 3c3d0eaab70..2d239bcdeb1 100644 --- a/sway-ir/src/optimize/cse.rs +++ b/sway-ir/src/optimize/cse.rs @@ -311,7 +311,7 @@ pub fn cse( }) .flatten() // The PHI couldn't be simplified to a single ValueNumber. - .unwrap_or_else(|| ValueNumber::Number(phi)) + .unwrap_or(ValueNumber::Number(phi)) }; match vntable.value_map.entry(phi) { From 8462fdfb4b62c1a332be6afde98ddcb913bb2908 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Fri, 16 Aug 2024 21:28:35 +0530 Subject: [PATCH 08/10] update tests --- .../language/u256/u256_abi/json_abi_oracle_new_encoding.json | 2 +- .../array_of_structs_caller/src/main.sw | 2 +- .../require_contract_deployment/asset_ops_test/src/main.sw | 2 +- .../require_contract_deployment/bal_opcode/src/main.sw | 2 +- .../call_abi_with_tuples/src/main.sw | 2 +- .../require_contract_deployment/call_basic_storage/src/main.sw | 2 +- .../call_contract_with_type_aliases/src/main.sw | 2 +- .../call_increment_contract/src/main.sw | 2 +- .../require_contract_deployment/call_storage_enum/src/main.sw | 2 +- .../require_contract_deployment/caller_auth_test/src/main.sw | 2 +- .../require_contract_deployment/caller_context_test/src/main.sw | 2 +- .../nested_struct_args_caller/src/main.sw | 2 +- .../storage_access_caller/src/main.sw | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json index d2552663ebd..a982fde719b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/u256/u256_abi/json_abi_oracle_new_encoding.json @@ -7,7 +7,7 @@ "typeArguments": null }, "name": "SOME_U256", - "offset": 816 + "offset": 808 } ], "encoding": "1", diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw index cd5a22ec0a3..b6cce9fb794 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw @@ -6,7 +6,7 @@ use std::hash::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x14ed3cd06c2947248f69d54bfa681fe40d26267be84df7e19e253622b7921bbe; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x316c03d37b53eaeffe22c2d2df50d675e2b2ee07bd8b73f852e686129aeba462; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release +const CONTRACT_ID = 0xe8034b7b83eb42bd3c52757f5f1cd5808bef1594804ed4f0f4a4bbb6514fe411; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release fn main() -> u64 { let addr = abi(TestContract, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw index 376ccd9b332..2796aac89fa 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/asset_ops_test/src/main.sw @@ -14,7 +14,7 @@ const FUEL_COIN_CONTRACT_ID = 0x04126a159537ffa66c60c062904e0408e92fa044f61742ae #[cfg(experimental_new_encoding = false)] const BALANCE_CONTRACT_ID = 0xf6cd545152ac83225e8e7df2efb5c6fa6e37bc9b9e977b5ea8103d28668925df; #[cfg(experimental_new_encoding = true)] -const BALANCE_CONTRACT_ID = 0x51088b17e33a9fbbcac387cd3e462571dfce54e340579d7130c5b6fe08793ea9; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const BALANCE_CONTRACT_ID = 0x0f5c045cc0b1dc371e0513fd0173a90aeb386629ae0511d90e400c57d65d6328; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release fn main() -> bool { let default_gas = 1_000_000_000_000; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw index 79c9b83161e..096e15715f4 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/bal_opcode/src/main.sw @@ -5,7 +5,7 @@ use balance_test_abi::BalanceTest; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xf6cd545152ac83225e8e7df2efb5c6fa6e37bc9b9e977b5ea8103d28668925df; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x51088b17e33a9fbbcac387cd3e462571dfce54e340579d7130c5b6fe08793ea9; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const CONTRACT_ID = 0x0f5c045cc0b1dc371e0513fd0173a90aeb386629ae0511d90e400c57d65d6328; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release fn main() -> bool { let balance_test_contract = abi(BalanceTest, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw index a326a415454..6c9d0685336 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_abi_with_tuples/src/main.sw @@ -6,7 +6,7 @@ use abi_with_tuples::{MyContract, Location, Person}; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xfdc14550c8aee742cd556d0ab7f378b7be0d3b1e6e086c097352e94590d4ed02; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x3e643ef32d855086058951d13730fc9cb891dba39147c545e4b2e8df0ed42f19; // AUTO-CONTRACT-ID ../../test_contracts/abi_with_tuples_contract --release +const CONTRACT_ID = 0x8c5c7f3e4f466f55d2ee66c264d52dcbaa721e120b9fe9e321ed1426511af663; // AUTO-CONTRACT-ID ../../test_contracts/abi_with_tuples_contract --release fn main() -> bool { let the_abi = abi(MyContract, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw index 6647c07e1b9..75ef2fe7ead 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_basic_storage/src/main.sw @@ -4,7 +4,7 @@ use basic_storage_abi::{BasicStorage, Quad}; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x94db39f409a31b9f2ebcadeea44378e419208c20de90f5d8e1e33dc1523754cb; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xcaaa4d2e98f4cea99de2ab3a79d160a01b5bd39796a3419c29f97faf27c8c717; // AUTO-CONTRACT-ID ../../test_contracts/basic_storage --release +const CONTRACT_ID = 0x14dcde44157de2afab6253cc27033c25febef024cbd11eb0f27b68e7b2ea81f0; // AUTO-CONTRACT-ID ../../test_contracts/basic_storage --release fn main() -> u64 { let addr = abi(BasicStorage, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw index 8dc12a1b8f5..008f5ae7d7b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw @@ -5,7 +5,7 @@ use contract_with_type_aliases_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x0cbeb6efe3104b460be769bdc4ea101ebf16ccc16f2d7b667ec3e1c7f5ce35b5; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xba120652492747e60222b5a37946c840a5bb91ba2665e11d000b9bd3063db237; // AUTO-CONTRACT-ID ../../test_contracts/contract_with_type_aliases --release +const CONTRACT_ID = 0xb805a413bff66e2130bac4cc63e8f54e655503dc629072f64ad8fd6601890814; // AUTO-CONTRACT-ID ../../test_contracts/contract_with_type_aliases --release fn main() { let caller = abi(MyContract, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw index 4716a5e8da8..86b094cc73f 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_increment_contract/src/main.sw @@ -6,7 +6,7 @@ use dynamic_contract_call::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xd1b4047af7ef111c023ab71069e01dc2abfde487c0a0ce1268e4f447e6c6e4c2; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x6f2d0d8ffc753e2efecf66dd00e258520e6a7bba294e302d239eb1f4d81efc4e; // AUTO-CONTRACT-ID ../../test_contracts/increment_contract --release +const CONTRACT_ID = 0x39606c9d9d395f231cc76e5b90826a8788ca25999df72e1ece4aafe6fe33ec07; // AUTO-CONTRACT-ID ../../test_contracts/increment_contract --release fn main() -> bool { let the_abi = abi(Incrementor, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw index 1c950a32e0f..e0d1e8af974 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_storage_enum/src/main.sw @@ -5,7 +5,7 @@ use storage_enum_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xc601d11767195485a6654d566c67774134668863d8c797a8c69e8778fb1f89e9; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x90691afac688061184bffdf134ed06119d6187371d550a095a1d09d8406bc104; // AUTO-CONTRACT-ID ../../test_contracts/storage_enum_contract --release +const CONTRACT_ID = 0x7ebcca623be0e2ae91c08a3fcbd7eb90b9e31a2cdfb93f996dbce0e0c44464ff; // AUTO-CONTRACT-ID ../../test_contracts/storage_enum_contract --release fn main() -> u64 { let caller = abi(StorageEnum, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw index 8b8bed75d36..bcd2fe6e757 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_auth_test/src/main.sw @@ -5,7 +5,7 @@ use auth_testing_abi::AuthTesting; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xc2eec20491b53aab7232cbd27c31d15417b4e9daf0b89c74cc242ef1295f681f; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x17078468cc937c3653ad0d2df73255aae6fc95934d4765897f3950773cb32199; // AUTO-CONTRACT-ID ../../test_contracts/auth_testing_contract --release +const CONTRACT_ID = 0xd4529187df29ad2f22bdefec7b9d3bebb81ade2d67ddef8f263da80c4f2b6fe8; // AUTO-CONTRACT-ID ../../test_contracts/auth_testing_contract --release // should be false in the case of a script fn main() -> bool { diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw index b5fc50227fd..21433cf8870 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/caller_context_test/src/main.sw @@ -6,7 +6,7 @@ use context_testing_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x6054c11cda000f5990373a4d61929396165be4dfdd61d5b7bd26da60ab0d8577; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x54f18a2b2e131fb8f0774c8ca368292101755a195cc609ea2fc88e708921b0a3; // AUTO-CONTRACT-ID ../../test_contracts/context_testing_contract --release +const CONTRACT_ID = 0x9fdffb1c0274daa03de1245907a657ae2832a1530a0127572dbc64562e50128f; // AUTO-CONTRACT-ID ../../test_contracts/context_testing_contract --release fn main() -> bool { let gas: u64 = u64::max(); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw index 715860df705..7c787662077 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/nested_struct_args_caller/src/main.sw @@ -5,7 +5,7 @@ use nested_struct_args_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0xe63d33a1b3a6903808b379f6a41a72fa8a370e8b76626775e7d9d2f9c4c5da40; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x118efc99167f16e4f9b916ac6b3a85ca08e579cad533d1fca14fb3b460df691e; // AUTO-CONTRACT-ID ../../test_contracts/nested_struct_args_contract --release +const CONTRACT_ID = 0x99fbde6a68019774d28c05d2682124fe2dedb5343e1e1e140c11e5bbbcbc775b; // AUTO-CONTRACT-ID ../../test_contracts/nested_struct_args_contract --release fn main() -> bool { let caller = abi(NestedStructArgs, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw index f720cbddea9..1366011b2d3 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/storage_access_caller/src/main.sw @@ -6,7 +6,7 @@ use std::hash::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x3bc28acd66d327b8c1b9624c1fabfc07e9ffa1b5d71c2832c3bfaaf8f4b805e9; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xa6026cfed3ba7a4ab3aa17908da17248f0489c042acc7ffaefb8b6c6536b069a; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release +const CONTRACT_ID = 0xa138fa6272a72eb7e796db53f89e7c1862cb128882f18bf2029b4b7446795e1e; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release fn main() -> bool { let caller = abi(StorageAccess, CONTRACT_ID); From d1e035c28fdd1335eba3d66a0e0757bb0da6aaa2 Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Mon, 19 Aug 2024 07:19:02 +0530 Subject: [PATCH 09/10] remove dbg prints --- sway-ir/src/optimize/cse.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/sway-ir/src/optimize/cse.rs b/sway-ir/src/optimize/cse.rs index 2d239bcdeb1..7423cc2fa62 100644 --- a/sway-ir/src/optimize/cse.rs +++ b/sway-ir/src/optimize/cse.rs @@ -12,9 +12,9 @@ use std::{ }; use crate::{ - function_print, AnalysisResults, BinaryOpKind, Context, DebugWithContext, DomTree, Function, - InstOp, IrError, Pass, PassMutability, PostOrder, Predicate, ScopedPass, Type, UnaryOpKind, - Value, DOMINATORS_NAME, POSTORDER_NAME, + AnalysisResults, BinaryOpKind, Context, DebugWithContext, DomTree, Function, InstOp, IrError, + Pass, PassMutability, PostOrder, Predicate, ScopedPass, Type, UnaryOpKind, Value, + DOMINATORS_NAME, POSTORDER_NAME, }; pub const CSE_NAME: &str = "cse"; @@ -179,7 +179,6 @@ fn dominates(context: &Context, dom_tree: &DomTree, inst1: Value, inst2: Value) let block2 = match &context.values[inst2.0].value { crate::ValueDatum::Argument(arg) => arg.block, crate::ValueDatum::Constant(_) => { - dbg!(inst1, inst2); panic!("Shouldn't be querying dominance info for constants") } crate::ValueDatum::Instruction(i) => i.parent, @@ -207,9 +206,6 @@ pub fn cse( analyses: &AnalysisResults, function: Function, ) -> Result { - if function.get_name(context) == "sha256_6" { - function_print(context, function); - } let mut vntable = VNTable::default(); // Function arg values map to themselves. @@ -352,8 +348,6 @@ pub fn cse( vntable.expr_map.clear(); } - dbg!(&vntable); - // create a partition of congruent (equal) values. let mut partition = FxHashMap::>::default(); vntable.value_map.iter().for_each(|(v, vn)| { From a90df95ceca4cad03e90357a1afb6009cb8c0a5f Mon Sep 17 00:00:00 2001 From: Vaivaswatha Nagaraj Date: Mon, 9 Sep 2024 11:17:32 +0530 Subject: [PATCH 10/10] Fix tests and run cargo fmt --- sway-ir/src/pass_manager.rs | 12 ++++++- sway-ir/tests/tests.rs | 9 +++++- .../json_abi_oracle_new_encoding.json | 32 +++++++++---------- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/sway-ir/src/pass_manager.rs b/sway-ir/src/pass_manager.rs index d86b19b9b31..9edb21626c3 100644 --- a/sway-ir/src/pass_manager.rs +++ b/sway-ir/src/pass_manager.rs @@ -1,5 +1,15 @@ use crate::{ - create_arg_demotion_pass, create_ccp_pass, create_const_demotion_pass, create_const_folding_pass, create_cse_pass, create_dce_pass, create_dom_fronts_pass, create_dominators_pass, create_escaped_symbols_pass, create_fn_dce_pass, create_fn_dedup_debug_profile_pass, create_fn_dedup_release_profile_pass, create_fn_inline_pass, create_mem2reg_pass, create_memcpyopt_pass, create_misc_demotion_pass, create_module_printer_pass, create_module_verifier_pass, create_postorder_pass, create_ret_demotion_pass, create_simplify_cfg_pass, create_sroa_pass, Context, Function, IrError, Module, ARG_DEMOTION_NAME, CCP_NAME, CONST_DEMOTION_NAME, CONST_FOLDING_NAME, CSE_NAME, DCE_NAME, FN_DCE_NAME, FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, FN_INLINE_NAME, MEM2REG_NAME, MEMCPYOPT_NAME, MISC_DEMOTION_NAME, RET_DEMOTION_NAME, SIMPLIFY_CFG_NAME, SROA_NAME + create_arg_demotion_pass, create_ccp_pass, create_const_demotion_pass, + create_const_folding_pass, create_cse_pass, create_dce_pass, create_dom_fronts_pass, + create_dominators_pass, create_escaped_symbols_pass, create_fn_dce_pass, + create_fn_dedup_debug_profile_pass, create_fn_dedup_release_profile_pass, + create_fn_inline_pass, create_mem2reg_pass, create_memcpyopt_pass, create_misc_demotion_pass, + create_module_printer_pass, create_module_verifier_pass, create_postorder_pass, + create_ret_demotion_pass, create_simplify_cfg_pass, create_sroa_pass, Context, Function, + IrError, Module, ARG_DEMOTION_NAME, CCP_NAME, CONST_DEMOTION_NAME, CONST_FOLDING_NAME, + CSE_NAME, DCE_NAME, FN_DCE_NAME, FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, + FN_INLINE_NAME, MEM2REG_NAME, MEMCPYOPT_NAME, MISC_DEMOTION_NAME, RET_DEMOTION_NAME, + SIMPLIFY_CFG_NAME, SROA_NAME, }; use downcast_rs::{impl_downcast, Downcast}; use rustc_hash::FxHashMap; diff --git a/sway-ir/tests/tests.rs b/sway-ir/tests/tests.rs index 58bd60e8bbb..197d67d400e 100644 --- a/sway-ir/tests/tests.rs +++ b/sway-ir/tests/tests.rs @@ -2,7 +2,14 @@ use std::path::PathBuf; use itertools::Itertools; use sway_ir::{ - create_arg_demotion_pass, create_ccp_pass, create_const_demotion_pass, create_const_folding_pass, create_cse_pass, create_dce_pass, create_dom_fronts_pass, create_dominators_pass, create_escaped_symbols_pass, create_mem2reg_pass, create_memcpyopt_pass, create_misc_demotion_pass, create_postorder_pass, create_ret_demotion_pass, create_simplify_cfg_pass, metadata_to_inline, optimize as opt, register_known_passes, Context, ExperimentalFlags, Function, IrError, PassGroup, PassManager, Value, DCE_NAME, FN_DCE_NAME, FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, MEM2REG_NAME, SROA_NAME + create_arg_demotion_pass, create_ccp_pass, create_const_demotion_pass, + create_const_folding_pass, create_cse_pass, create_dce_pass, create_dom_fronts_pass, + create_dominators_pass, create_escaped_symbols_pass, create_mem2reg_pass, + create_memcpyopt_pass, create_misc_demotion_pass, create_postorder_pass, + create_ret_demotion_pass, create_simplify_cfg_pass, metadata_to_inline, optimize as opt, + register_known_passes, Context, ExperimentalFlags, Function, IrError, PassGroup, PassManager, + Value, DCE_NAME, FN_DCE_NAME, FN_DEDUP_DEBUG_PROFILE_NAME, FN_DEDUP_RELEASE_PROFILE_NAME, + MEM2REG_NAME, SROA_NAME, }; use sway_types::SourceEngine; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json index 0662cd80d0d..b5e886d1a19 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_consts/json_abi_oracle_new_encoding.json @@ -62,82 +62,82 @@ { "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", "name": "BOOL", - "offset": 7208 + "offset": 7216 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "U8", - "offset": 7400 + "offset": 7408 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "ANOTHER_U8", - "offset": 7136 + "offset": 7144 }, { "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", "name": "U16", - "offset": 7344 + "offset": 7352 }, { "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "name": "U32", - "offset": 7384 + "offset": 7392 }, { "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "name": "U64", - "offset": 7392 + "offset": 7400 }, { "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", "name": "U256", - "offset": 7352 + "offset": 7360 }, { "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", "name": "B256", - "offset": 7176 + "offset": 7184 }, { "concreteTypeId": "81fc10c4681a3271cf2d66b2ec6fbc8ed007a442652930844fcf11818c295bff", "name": "CONFIGURABLE_STRUCT", - "offset": 7296 + "offset": 7304 }, { "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", "name": "CONFIGURABLE_ENUM_A", - "offset": 7216 + "offset": 7224 }, { "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", "name": "CONFIGURABLE_ENUM_B", - "offset": 7256 + "offset": 7264 }, { "concreteTypeId": "4926d35d1a5157936b0a29bc126b8aace6d911209a5c130e9b716b0c73643ea6", "name": "ARRAY_BOOL", - "offset": 7144 + "offset": 7152 }, { "concreteTypeId": "776fb5a3824169d6736138565fdc20aad684d9111266a5ff6d5c675280b7e199", "name": "ARRAY_U64", - "offset": 7152 + "offset": 7160 }, { "concreteTypeId": "c998ca9a5f221fe7b5c66ae70c8a9562b86d964408b00d17f883c906bc1fe4be", "name": "TUPLE_BOOL_U64", - "offset": 7328 + "offset": 7336 }, { "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a", "name": "STR_4", - "offset": 7320 + "offset": 7328 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "NOT_USED", - "offset": 7312 + "offset": 7320 } ], "encodingVersion": "1",