diff --git a/forc-plugins/forc-client/tests/deploy.rs b/forc-plugins/forc-client/tests/deploy.rs index c56215961e..0eb0df1224 100644 --- a/forc-plugins/forc-client/tests/deploy.rs +++ b/forc-plugins/forc-client/tests/deploy.rs @@ -377,7 +377,7 @@ async fn test_simple_deploy() { node.kill().unwrap(); let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "57a5ac7d952df0dd7e72812509fd373260bee5dac54cca48c4d0b2841e9bcee3", + "7338571226a3a07d411acc73bf31821d7315365e3e04e309f5055f0b567431fb", ) .unwrap(), proxy: None, @@ -421,7 +421,7 @@ async fn test_deploy_submit_only() { node.kill().unwrap(); let expected = vec![DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "57a5ac7d952df0dd7e72812509fd373260bee5dac54cca48c4d0b2841e9bcee3", + "7338571226a3a07d411acc73bf31821d7315365e3e04e309f5055f0b567431fb", ) .unwrap(), proxy: None, @@ -468,12 +468,12 @@ async fn test_deploy_fresh_proxy() { node.kill().unwrap(); let impl_contract = DeployedPackage::Contract(DeployedContract { id: ContractId::from_str( - "57a5ac7d952df0dd7e72812509fd373260bee5dac54cca48c4d0b2841e9bcee3", + "7338571226a3a07d411acc73bf31821d7315365e3e04e309f5055f0b567431fb", ) .unwrap(), proxy: Some( ContractId::from_str( - "b8588024c0581f715d79c4f5ebd0b9e07f4ed0028f4da4fcf245ec09e1400982", + "2d4f046d31ee52218c189d0c4f30ac74490ab73b0747b4b95908b1ca7f7f7976", ) .unwrap(), ), diff --git a/forc-plugins/forc-debug/tests/server_integration.rs b/forc-plugins/forc-debug/tests/server_integration.rs index 0fadec6e47..02118c8285 100644 --- a/forc-plugins/forc-debug/tests/server_integration.rs +++ b/forc-plugins/forc-debug/tests/server_integration.rs @@ -315,10 +315,10 @@ fn test_sourcemap_build() { // Verify essential source locations are mapped correctly let key_locations = [ // Main function and its contents - (3, 4, "main function parameters"), // Should have 4 instructions + (3, 2, "main function parameters"), // Should have 2 instructions (4, 2, "addition operation"), // Should have 2 instructions (add operation) // Helper function and its contents - (11, 4, "helper function parameters"), // Should have 4 instructions + (11, 2, "helper function parameters"), // Should have 2 instructions (12, 2, "helper addition operation"), // Should have 2 instructions // Test functions (identical patterns) (21, 1, "test_1 first line"), // Each test line should have diff --git a/forc/tests/cli_integration.rs b/forc/tests/cli_integration.rs index ab732872ad..a99b7627c6 100644 --- a/forc/tests/cli_integration.rs +++ b/forc/tests/cli_integration.rs @@ -49,10 +49,10 @@ fn test_forc_test_raw_logs() -> Result<(), rexpect::error::Error> { // Assert that the output is correct process.exp_string(" test test_log_4")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12384,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12300,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.exp_string(" test test_log_2")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12384,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12300,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.process.exit()?; Ok(()) @@ -74,11 +74,11 @@ fn test_forc_test_both_logs() -> Result<(), rexpect::error::Error> { process.exp_string(" test test_log_4")?; process.exp_string("Decoded log value: 4, log rb: 1515152261580153489")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12384,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12300,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.exp_string(" test test_log_2")?; process.exp_string("Decoded log value: 2, log rb: 1515152261580153489")?; process.exp_string("Raw logs:")?; - process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12384,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; + process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12300,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?; process.process.exit()?; Ok(()) } diff --git a/sway-core/src/asm_generation/fuel/abstract_instruction_set.rs b/sway-core/src/asm_generation/fuel/abstract_instruction_set.rs index 32ef5a7f53..6069e5cd6b 100644 --- a/sway-core/src/asm_generation/fuel/abstract_instruction_set.rs +++ b/sway-core/src/asm_generation/fuel/abstract_instruction_set.rs @@ -1,20 +1,12 @@ -use crate::{ - asm_generation::fuel::{ - allocated_abstract_instruction_set::AllocatedAbstractInstructionSet, register_allocator, - }, - asm_lang::{ - allocated_ops::AllocatedOp, Op, OrganizationalOp, RealizedOp, VirtualOp, VirtualRegister, - }, -}; - use sway_error::error::CompileError; -use sway_types::Span; -use std::{collections::HashSet, fmt}; +use crate::asm_lang::{allocated_ops::AllocatedOp, Op, RealizedOp}; -use either::Either; +use std::fmt; -use super::data_section::DataSection; +use super::{ + allocated_abstract_instruction_set::AllocatedAbstractInstructionSet, register_allocator, +}; /// An [AbstractInstructionSet] is a set of instructions that use entirely virtual registers /// and excessive moves, with the intention of later optimizing it. @@ -24,151 +16,6 @@ pub struct AbstractInstructionSet { } impl AbstractInstructionSet { - pub(crate) fn optimize(self, data_section: &DataSection) -> AbstractInstructionSet { - self.const_indexing_aggregates_function(data_section) - .dce() - .simplify_cfg() - .remove_sequential_jumps() - .remove_redundant_moves() - .remove_redundant_ops() - } - - /// Removes any jumps to the subsequent line. - fn remove_sequential_jumps(mut self) -> AbstractInstructionSet { - let dead_jumps: Vec<_> = self - .ops - .windows(2) - .enumerate() - .filter_map(|(idx, ops)| match (&ops[0].opcode, &ops[1].opcode) { - ( - Either::Right(OrganizationalOp::Jump(dst_label)), - Either::Right(OrganizationalOp::Label(label)), - ) if dst_label == label => Some(idx), - _otherwise => None, - }) - .collect(); - - // Replace the dead jumps with NOPs, as it's cheaper. - for idx in dead_jumps { - self.ops[idx] = Op { - opcode: Either::Left(VirtualOp::NOOP), - comment: "remove redundant jump operation".into(), - owning_span: None, - }; - } - - self - } - - fn remove_redundant_moves(mut self) -> AbstractInstructionSet { - // This has a lot of room for improvement. - // - // For now it is just removing MOVEs to registers which are _never_ used. It doesn't - // analyse control flow or other redundancies. Some obvious improvements are: - // - // - Perform a control flow analysis to remove MOVEs to registers which are not used - // _after_ the MOVE. - // - // - Remove the redundant use of temporaries. E.g.: - // MOVE t, a MOVE b, a - // MOVE b, t => USE b - // USE b - loop { - // Gather all the uses for each register. - let uses: HashSet<&VirtualRegister> = - self.ops.iter().fold(HashSet::new(), |mut acc, op| { - for u in &op.use_registers() { - acc.insert(u); - } - acc - }); - - // Loop again and find MOVEs which have a non-constant destination which is never used. - let mut dead_moves = Vec::new(); - for (idx, op) in self.ops.iter().enumerate() { - if let Either::Left(VirtualOp::MOVE( - dst_reg @ VirtualRegister::Virtual(_), - _src_reg, - )) = &op.opcode - { - if !uses.contains(dst_reg) { - dead_moves.push(idx); - } - } - } - - if dead_moves.is_empty() { - break; - } - - // Replace the dead moves with NOPs, as it's cheaper. - for idx in dead_moves { - self.ops[idx] = Op { - opcode: Either::Left(VirtualOp::NOOP), - comment: "remove redundant move operation".into(), - owning_span: None, - }; - } - } - - self - } - - fn remove_redundant_ops(mut self) -> AbstractInstructionSet { - self.ops.retain(|op| { - // It is easier to think in terms of operations we want to remove - // than the operations we want to retain ;-) - #[allow(clippy::match_like_matches_macro)] - // Keep the `match` for adding more ops in the future. - let remove = match &op.opcode { - Either::Left(VirtualOp::NOOP) => true, - _ => false, - }; - - !remove - }); - - self - } - - // At the moment the only verification we do is to make sure used registers are - // initialised. Without doing dataflow analysis we still can't guarantee the init is - // _before_ the use, but future refactoring to convert abstract ops into SSA and BBs will - // make this possible or even make this check redundant. - pub(crate) fn verify(self) -> Result { - macro_rules! add_virt_regs { - ($regs: expr, $set: expr) => { - let mut regs = $regs; - regs.retain(|®| matches!(reg, VirtualRegister::Virtual(_))); - $set.extend(regs.into_iter()); - }; - } - - let mut use_regs = HashSet::new(); - let mut def_regs = HashSet::new(); - for op in &self.ops { - add_virt_regs!(op.use_registers(), use_regs); - add_virt_regs!(op.def_registers(), def_regs); - } - - if def_regs.is_superset(&use_regs) { - Ok(self) - } else { - let bad_regs = use_regs - .difference(&def_regs) - .map(|reg| match reg { - VirtualRegister::Virtual(name) => format!("$r{name}"), - VirtualRegister::Constant(creg) => creg.to_string(), - }) - .collect::>() - .join(", "); - Err(CompileError::InternalOwned( - format!("Program erroneously uses uninitialized virtual registers: {bad_regs}"), - Span::dummy(), - )) - } - } - /// Allocate registers. pub(crate) fn allocate_registers( self, diff --git a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs index 5733d530b1..ee758bb3b0 100644 --- a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs +++ b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs @@ -210,6 +210,10 @@ impl AsmBuilder for FuelAsmBuilder<'_, '_> { .. } = self; + let opt_level = build_config + .map(|cfg| cfg.optimization_level) + .unwrap_or_default(); + let entries = entries .clone() .into_iter() @@ -265,7 +269,7 @@ impl AsmBuilder for FuelAsmBuilder<'_, '_> { } let allocated_program = virtual_abstract_program - .into_allocated_program(fallback_fn) + .into_allocated_program(fallback_fn, opt_level) .map_err(|e| handler.emit_err(e))?; if build_config diff --git a/sway-core/src/asm_generation/fuel/optimizations.rs b/sway-core/src/asm_generation/fuel/optimizations/const_indexed_aggregates.rs similarity index 76% rename from sway-core/src/asm_generation/fuel/optimizations.rs rename to sway-core/src/asm_generation/fuel/optimizations/const_indexed_aggregates.rs index ac012a36bf..b1649bea23 100644 --- a/sway-core/src/asm_generation/fuel/optimizations.rs +++ b/sway-core/src/asm_generation/fuel/optimizations/const_indexed_aggregates.rs @@ -1,17 +1,11 @@ -use std::collections::{BTreeSet, HashMap}; - -use either::Either; -use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_hash::FxHashMap; use crate::{ asm_generation::fuel::compiler_constants, - asm_lang::{ControlFlowOp, Label, VirtualImmediate12, VirtualOp, VirtualRegister}, + asm_lang::{ControlFlowOp, VirtualImmediate12, VirtualOp, VirtualRegister}, }; -use super::{ - abstract_instruction_set::AbstractInstructionSet, analyses::liveness_analysis, - data_section::DataSection, -}; +use super::super::{abstract_instruction_set::AbstractInstructionSet, data_section::DataSection}; impl AbstractInstructionSet { // Aggregates that are const index accessed from a base address @@ -259,105 +253,4 @@ impl AbstractInstructionSet { self } - - pub(crate) fn dce(mut self) -> AbstractInstructionSet { - let liveness = liveness_analysis(&self.ops, false); - let ops = &self.ops; - - let mut cur_live = BTreeSet::default(); - let mut dead_indices = FxHashSet::default(); - for (rev_ix, op) in ops.iter().rev().enumerate() { - let ix = ops.len() - rev_ix - 1; - - let op_use = op.use_registers(); - let mut op_def = op.def_registers(); - op_def.append(&mut op.def_const_registers()); - - if let Either::Right(ControlFlowOp::Jump(_) | ControlFlowOp::JumpIfNotZero(..)) = - op.opcode - { - // Block boundary. Start afresh. - cur_live.clone_from(liveness.get(ix).expect("Incorrect liveness info")); - // Add use(op) to cur_live. - for u in op_use { - cur_live.insert(u.clone()); - } - continue; - } - - let dead = op_def.iter().all(|def| !cur_live.contains(def)) - && match &op.opcode { - Either::Left(op) => !op.has_side_effect(), - Either::Right(_) => false, - }; - // Remove def(op) from cur_live. - for def in &op_def { - cur_live.remove(def); - } - if dead { - dead_indices.insert(ix); - } else { - // Add use(op) to cur_live - for u in op_use { - cur_live.insert(u.clone()); - } - } - } - - // Actually delete the instructions. - let mut new_ops: Vec<_> = std::mem::take(&mut self.ops) - .into_iter() - .enumerate() - .filter_map(|(idx, op)| { - if !dead_indices.contains(&idx) { - Some(op) - } else { - None - } - }) - .collect(); - std::mem::swap(&mut self.ops, &mut new_ops); - - self - } - - // Remove unreachable instructions. - pub(crate) fn simplify_cfg(mut self) -> AbstractInstructionSet { - let ops = &self.ops; - - if ops.is_empty() { - return self; - } - - // Keep track of a map between jump labels and op indices. Useful to compute op successors. - let mut label_to_index: HashMap = HashMap::default(); - for (idx, op) in ops.iter().enumerate() { - if let Either::Right(ControlFlowOp::Label(op_label)) = op.opcode { - label_to_index.insert(op_label, idx); - } - } - - let mut reachables = vec![false; ops.len()]; - let mut worklist = vec![0]; - while let Some(op_idx) = worklist.pop() { - assert!(!reachables[op_idx]); - reachables[op_idx] = true; - let op = &ops[op_idx]; - for s in &op.successors(op_idx, ops, &label_to_index) { - if !reachables[*s] { - worklist.push(*s); - } - } - } - - let reachable_ops = self - .ops - .into_iter() - .enumerate() - .filter_map(|(idx, op)| if reachables[idx] { Some(op) } else { None }) - .collect(); - self.ops = reachable_ops; - - self - } } diff --git a/sway-core/src/asm_generation/fuel/optimizations/constant_propagate.rs b/sway-core/src/asm_generation/fuel/optimizations/constant_propagate.rs new file mode 100644 index 0000000000..0dbb802cf9 --- /dev/null +++ b/sway-core/src/asm_generation/fuel/optimizations/constant_propagate.rs @@ -0,0 +1,239 @@ +use std::collections::hash_map::Entry; + +use either::Either; +use rustc_hash::FxHashMap; + +use crate::asm_lang::{ConstantRegister, ControlFlowOp, Label, Op, VirtualOp, VirtualRegister}; + +use super::super::abstract_instruction_set::AbstractInstructionSet; + +#[derive(Clone, Debug, PartialEq, Eq)] +enum KnownRegValue { + Const(u64), + Eq(VirtualRegister), +} + +impl KnownRegValue { + /// If the value can be represented as a register, return it. + fn register(&self) -> Option { + match self { + KnownRegValue::Const(0) => Some(VirtualRegister::Constant(ConstantRegister::Zero)), + KnownRegValue::Const(1) => Some(VirtualRegister::Constant(ConstantRegister::One)), + KnownRegValue::Eq(v) => Some(v.clone()), + _ => None, + } + } + + /// If the value can be represented as a constant, return it. + fn value(&self) -> Option { + match self { + KnownRegValue::Const(v) => Some(*v), + KnownRegValue::Eq(VirtualRegister::Constant(ConstantRegister::Zero)) => Some(0), + KnownRegValue::Eq(VirtualRegister::Constant(ConstantRegister::One)) => Some(1), + KnownRegValue::Eq(_) => None, + } + } + + /// Check if the value depends on value of another register. + fn depends_on(&self, reg: &VirtualRegister) -> bool { + match self { + KnownRegValue::Const(_) => false, + KnownRegValue::Eq(v) => v == reg, + } + } +} + +#[derive(Clone, Debug, Default)] +struct KnownValues { + values: FxHashMap, +} + +impl KnownValues { + /// Resolve a register to a known value. + fn resolve(&self, v: &VirtualRegister) -> Option { + match v { + VirtualRegister::Constant(ConstantRegister::Zero) => Some(KnownRegValue::Const(0)), + VirtualRegister::Constant(ConstantRegister::One) => Some(KnownRegValue::Const(1)), + other => self.values.get(other).cloned(), + } + } + + /// Clear values that depend on a register having a specific value. + fn clear_dependent_on(&mut self, reg: &VirtualRegister) { + self.values.retain(|_, v| !v.depends_on(reg)); + } + + /// Insert a known value for a register. + fn assign(&mut self, dst: VirtualRegister, value: KnownRegValue) { + self.clear_dependent_on(&dst); + self.values.insert(dst, value); + } +} + +/// What knowledge is lost after an op we don't know how to interpret? +#[derive(Clone, Debug)] +enum ResetKnown { + /// Reset all known values + Full, + /// Reset non-virtual registers in addition to defs + NonVirtual, + /// Only the `def_registers` and `def_const_registers` are reset + Defs, +} +impl ResetKnown { + fn apply(&self, op: &Op, known_values: &mut KnownValues) { + match self { + ResetKnown::Full => { + known_values.values.clear(); + } + ResetKnown::NonVirtual => { + Self::Defs.apply(op, known_values); + known_values + .values + .retain(|k, _| matches!(k, VirtualRegister::Virtual(_))); + } + ResetKnown::Defs => { + for d in op.def_registers() { + known_values.clear_dependent_on(d); + known_values.values.remove(d); + } + for d in op.def_const_registers() { + known_values.clear_dependent_on(d); + known_values.values.remove(d); + } + } + } + } +} + +impl AbstractInstructionSet { + /// Symbolically interpret code and propagate known register values. + pub(crate) fn constant_propagate(mut self) -> AbstractInstructionSet { + if self.ops.is_empty() { + return self; + } + + // The set of labels that are jump targets, and how many places jump to them. + // todo: build proper control flow graph instead + let mut jump_target_labels = FxHashMap::::default(); + for op in &self.ops { + if let Either::Right( + ControlFlowOp::Jump(label) + | ControlFlowOp::JumpIfNotZero(_, label) + | ControlFlowOp::Call(label), + ) = &op.opcode + { + *jump_target_labels.entry(*label).or_default() += 1; + } + } + + let mut known_values = KnownValues::default(); + + for op in &mut self.ops { + // Perform constant propagation on the instruction. + let mut uses_regs: Vec<_> = op.use_registers_mut().into_iter().collect(); + for reg in uses_regs.iter_mut() { + // We only optimize over virtual registers here, constant registers shouldn't be replaced + if !reg.is_virtual() { + continue; + } + if let Some(r) = known_values.resolve(reg).and_then(|r| r.register()) { + **reg = r; + } + } + + // Some instructions can be further simplified with the known values. + match &mut op.opcode { + // Conditional jumps can be simplified if we know the value of the register. + Either::Right(ControlFlowOp::JumpIfNotZero(reg, lab)) => { + if let Some(con) = known_values.resolve(reg).and_then(|r| r.value()) { + if con == 0 { + let Entry::Occupied(mut count) = jump_target_labels.entry(*lab) else { + unreachable!("Jump target label not found in jump_target_labels"); + }; + *count.get_mut() -= 1; + if *count.get() == 0 { + // Nobody jumps to this label anymore + jump_target_labels.remove(lab); + } + op.opcode = Either::Left(VirtualOp::NOOP); + } else { + op.opcode = Either::Right(ControlFlowOp::Jump(*lab)); + } + } + } + _ => {} + } + + // Some ops are known to produce certain results, interpret them here. + let interpreted_op = match &op.opcode { + Either::Left(VirtualOp::MOVI(dst, imm)) => { + let imm = KnownRegValue::Const(imm.value() as u64); + if known_values.resolve(dst) == Some(imm.clone()) { + op.opcode = Either::Left(VirtualOp::NOOP); + } else { + known_values.assign(dst.clone(), imm); + } + true + } + Either::Left(VirtualOp::MOVE(dst, src)) => { + if let Some(known) = known_values.resolve(src) { + if known_values.resolve(dst) == Some(known.clone()) { + op.opcode = Either::Left(VirtualOp::NOOP); + } else { + known_values.assign(dst.clone(), known); + } + } else { + known_values.assign(dst.clone(), KnownRegValue::Eq(src.clone())); + } + true + } + _ => false, + }; + + // If we don't know how to interpret the op, it's outputs are not known. + if !interpreted_op { + let reset = match &op.opcode { + Either::Left(op) => match op { + VirtualOp::ECAL(_, _, _, _) => ResetKnown::Full, + // TODO: this constraint can be relaxed + _ if op.has_side_effect() => ResetKnown::Full, + _ => ResetKnown::Defs, + }, + Either::Right(op) => match op { + // If this is a jump target, then multiple execution paths can lead to it, + // and we can't assume to know register values. + ControlFlowOp::Label(label) => { + if jump_target_labels.contains_key(label) { + ResetKnown::Full + } else { + ResetKnown::Defs + } + } + // Jumping away doesn't invalidate state + ControlFlowOp::Jump(_) | ControlFlowOp::JumpIfNotZero(_, _) => { + ResetKnown::Defs + } + // TODO: `def_const_registers` doesn't contain return value, which + // seems incorrect, so I'm clearing everything as a precaution + ControlFlowOp::Call(_) => ResetKnown::Full, + // These ops mark their outputs properly and cause no control-flow effects + ControlFlowOp::Comment + | ControlFlowOp::SaveRetAddr(_, _) + | ControlFlowOp::ConfigurablesOffsetPlaceholder + | ControlFlowOp::DataSectionOffsetPlaceholder + | ControlFlowOp::LoadLabel(_, _) => ResetKnown::Defs, + // This changes the stack pointer + ControlFlowOp::PushAll(_) => ResetKnown::NonVirtual, + // This can be considered to destroy all known values + ControlFlowOp::PopAll(_) => ResetKnown::Full, + }, + }; + + reset.apply(op, &mut known_values); + } + } + + self + } +} diff --git a/sway-core/src/asm_generation/fuel/optimizations/misc.rs b/sway-core/src/asm_generation/fuel/optimizations/misc.rs new file mode 100644 index 0000000000..fb826a057d --- /dev/null +++ b/sway-core/src/asm_generation/fuel/optimizations/misc.rs @@ -0,0 +1,111 @@ +use super::super::abstract_instruction_set::AbstractInstructionSet; + +use crate::asm_lang::{Op, OrganizationalOp, VirtualOp, VirtualRegister}; + +use std::collections::HashSet; + +use either::Either; + +impl AbstractInstructionSet { + /// Removes any jumps to the subsequent line. + pub(crate) fn remove_sequential_jumps(mut self) -> AbstractInstructionSet { + let dead_jumps: Vec<_> = self + .ops + .windows(2) + .enumerate() + .filter_map(|(idx, ops)| match (&ops[0].opcode, &ops[1].opcode) { + ( + Either::Right(OrganizationalOp::Jump(dst_label)), + Either::Right(OrganizationalOp::Label(label)), + ) if dst_label == label => Some(idx), + _otherwise => None, + }) + .collect(); + + // Replace the dead jumps with NOPs, as it's cheaper. + for idx in dead_jumps { + self.ops[idx] = Op { + opcode: Either::Left(VirtualOp::NOOP), + comment: "remove redundant jump operation".into(), + owning_span: None, + }; + } + + self + } + + pub(crate) fn remove_redundant_moves(mut self) -> AbstractInstructionSet { + // This has a lot of room for improvement. + // + // For now it is just removing MOVEs to registers which are _never_ used. It doesn't + // analyse control flow or other redundancies. Some obvious improvements are: + // + // - Perform a control flow analysis to remove MOVEs to registers which are not used + // _after_ the MOVE. + // + // - Remove the redundant use of temporaries. E.g.: + // MOVE t, a MOVE b, a + // MOVE b, t => USE b + // USE b + loop { + // Gather all the uses for each register. + let uses: HashSet<&VirtualRegister> = + self.ops.iter().fold(HashSet::new(), |mut acc, op| { + for u in &op.use_registers() { + acc.insert(u); + } + acc + }); + + // Loop again and find MOVEs which have a non-constant destination which is never used. + let mut dead_moves = Vec::new(); + for (idx, op) in self.ops.iter().enumerate() { + if let Either::Left(VirtualOp::MOVE( + dst_reg @ VirtualRegister::Virtual(_), + _src_reg, + )) = &op.opcode + { + if !uses.contains(dst_reg) { + dead_moves.push(idx); + } + } + } + + if dead_moves.is_empty() { + break; + } + + // Replace the dead moves with NOPs, as it's cheaper. + for idx in dead_moves { + self.ops[idx] = Op { + opcode: Either::Left(VirtualOp::NOOP), + comment: "remove redundant move operation".into(), + owning_span: None, + }; + } + } + + self + } + + pub(crate) fn remove_redundant_ops(mut self) -> AbstractInstructionSet { + self.ops.retain(|op| { + // It is easier to think in terms of operations we want to remove + // than the operations we want to retain ;-) + #[allow(clippy::match_like_matches_macro)] + // Keep the `match` for adding more ops in the future. + let remove = match &op.opcode { + Either::Left(VirtualOp::NOOP) => true, + Either::Left(VirtualOp::MOVE(a, b)) => a == b, + Either::Left(VirtualOp::CFEI(_, imm)) | Either::Left(VirtualOp::CFSI(_, imm)) => { + imm.value() == 0 + } + _ => false, + }; + + !remove + }); + + self + } +} diff --git a/sway-core/src/asm_generation/fuel/optimizations/mod.rs b/sway-core/src/asm_generation/fuel/optimizations/mod.rs new file mode 100644 index 0000000000..3916474d01 --- /dev/null +++ b/sway-core/src/asm_generation/fuel/optimizations/mod.rs @@ -0,0 +1,55 @@ +mod const_indexed_aggregates; +mod constant_propagate; +mod misc; +mod reachability; +mod verify; + +use std::cmp::Ordering; + +use super::abstract_instruction_set::AbstractInstructionSet; + +use crate::OptLevel; + +use super::data_section::DataSection; + +/// Maximum number of optimization rounds to perform in release build. +const MAX_OPT_ROUNDS: usize = 10; + +impl AbstractInstructionSet { + pub(crate) fn optimize( + mut self, + data_section: &DataSection, + level: OptLevel, + ) -> AbstractInstructionSet { + match level { + // On debug builds do a single pass through the simple optimizations + OptLevel::Opt0 => self + .const_indexing_aggregates_function(data_section) + .constant_propagate() + .dce() + .simplify_cfg() + .remove_sequential_jumps() + .remove_redundant_moves() + .remove_redundant_ops(), + // On release builds we can do more iterations + OptLevel::Opt1 => { + for _ in 0..MAX_OPT_ROUNDS { + let old = self.clone(); + // run two rounds, so that if an optimization depends on another + // it will be applied at least once + self = self.optimize(data_section, OptLevel::Opt0); + self = self.optimize(data_section, OptLevel::Opt0); + match self.ops.len().cmp(&old.ops.len()) { + // Not able to optimize anything, stop here + Ordering::Equal => break, + // Never accept worse results + Ordering::Greater => return old, + // We reduced the number of ops, so continue + Ordering::Less => {} + } + } + self + } + } + } +} diff --git a/sway-core/src/asm_generation/fuel/optimizations/reachability.rs b/sway-core/src/asm_generation/fuel/optimizations/reachability.rs new file mode 100644 index 0000000000..7408764f82 --- /dev/null +++ b/sway-core/src/asm_generation/fuel/optimizations/reachability.rs @@ -0,0 +1,111 @@ +use std::collections::{BTreeSet, HashMap}; + +use either::Either; +use rustc_hash::FxHashSet; + +use crate::asm_lang::{ControlFlowOp, Label}; + +use super::super::{abstract_instruction_set::AbstractInstructionSet, analyses::liveness_analysis}; + +impl AbstractInstructionSet { + pub(crate) fn dce(mut self) -> AbstractInstructionSet { + let liveness = liveness_analysis(&self.ops, false); + let ops = &self.ops; + + let mut cur_live = BTreeSet::default(); + let mut dead_indices = FxHashSet::default(); + for (rev_ix, op) in ops.iter().rev().enumerate() { + let ix = ops.len() - rev_ix - 1; + + let op_use = op.use_registers(); + let mut op_def = op.def_registers(); + op_def.append(&mut op.def_const_registers()); + + if let Either::Right(ControlFlowOp::Jump(_) | ControlFlowOp::JumpIfNotZero(..)) = + op.opcode + { + // Block boundary. Start afresh. + cur_live.clone_from(liveness.get(ix).expect("Incorrect liveness info")); + // Add use(op) to cur_live. + for u in op_use { + cur_live.insert(u.clone()); + } + continue; + } + + let dead = op_def.iter().all(|def| !cur_live.contains(def)) + && match &op.opcode { + Either::Left(op) => !op.has_side_effect(), + Either::Right(_) => false, + }; + // Remove def(op) from cur_live. + for def in &op_def { + cur_live.remove(def); + } + if dead { + dead_indices.insert(ix); + } else { + // Add use(op) to cur_live + for u in op_use { + cur_live.insert(u.clone()); + } + } + } + + // Actually delete the instructions. + let mut new_ops: Vec<_> = std::mem::take(&mut self.ops) + .into_iter() + .enumerate() + .filter_map(|(idx, op)| { + if !dead_indices.contains(&idx) { + Some(op) + } else { + None + } + }) + .collect(); + std::mem::swap(&mut self.ops, &mut new_ops); + + self + } + + // Remove unreachable instructions. + pub(crate) fn simplify_cfg(mut self) -> AbstractInstructionSet { + let ops = &self.ops; + + if ops.is_empty() { + return self; + } + + // Keep track of a map between jump labels and op indices. Useful to compute op successors. + let mut label_to_index: HashMap = HashMap::default(); + for (idx, op) in ops.iter().enumerate() { + if let Either::Right(ControlFlowOp::Label(op_label)) = op.opcode { + label_to_index.insert(op_label, idx); + } + } + + let mut reachables = vec![false; ops.len()]; + let mut worklist = vec![0]; + while let Some(op_idx) = worklist.pop() { + assert!(!reachables[op_idx]); + reachables[op_idx] = true; + let op = &ops[op_idx]; + for s in &op.successors(op_idx, ops, &label_to_index) { + if !reachables[*s] && !worklist.contains(s) { + worklist.push(*s); + } + } + } + + let reachable_ops = self + .ops + .into_iter() + .enumerate() + .filter_map(|(idx, op)| if reachables[idx] { Some(op) } else { None }) + .collect(); + self.ops = reachable_ops; + + self + } +} diff --git a/sway-core/src/asm_generation/fuel/optimizations/verify.rs b/sway-core/src/asm_generation/fuel/optimizations/verify.rs new file mode 100644 index 0000000000..4b3c03b6b5 --- /dev/null +++ b/sway-core/src/asm_generation/fuel/optimizations/verify.rs @@ -0,0 +1,49 @@ +use std::collections::HashSet; + +use sway_error::error::CompileError; +use sway_types::Span; + +use crate::{ + asm_generation::fuel::abstract_instruction_set::AbstractInstructionSet, + asm_lang::VirtualRegister, +}; + +impl AbstractInstructionSet { + // At the moment the only verification we do is to make sure used registers are + // initialised. Without doing dataflow analysis we still can't guarantee the init is + // _before_ the use, but future refactoring to convert abstract ops into SSA and BBs will + // make this possible or even make this check redundant. + pub(crate) fn verify(self) -> Result { + macro_rules! add_virt_regs { + ($regs: expr, $set: expr) => { + let mut regs = $regs; + regs.retain(|®| matches!(reg, VirtualRegister::Virtual(_))); + $set.extend(regs.into_iter()); + }; + } + + let mut use_regs = HashSet::new(); + let mut def_regs = HashSet::new(); + for op in &self.ops { + add_virt_regs!(op.use_registers(), use_regs); + add_virt_regs!(op.def_registers(), def_regs); + } + + if def_regs.is_superset(&use_regs) { + Ok(self) + } else { + let bad_regs = use_regs + .difference(&def_regs) + .map(|reg| match reg { + VirtualRegister::Virtual(name) => format!("$r{name}"), + VirtualRegister::Constant(creg) => creg.to_string(), + }) + .collect::>() + .join(", "); + Err(CompileError::InternalOwned( + format!("Program erroneously uses uninitialized virtual registers: {bad_regs}"), + Span::dummy(), + )) + } + } +} diff --git a/sway-core/src/asm_generation/fuel/programs/abstract.rs b/sway-core/src/asm_generation/fuel/programs/abstract.rs index 50748ede02..cb206a896a 100644 --- a/sway-core/src/asm_generation/fuel/programs/abstract.rs +++ b/sway-core/src/asm_generation/fuel/programs/abstract.rs @@ -17,6 +17,7 @@ use crate::{ VirtualImmediate18, VirtualImmediate24, }, decl_engine::DeclRefFunction, + OptLevel, }; use either::Either; use sway_error::error::CompileError; @@ -82,10 +83,11 @@ impl AbstractProgram { pub(crate) fn into_allocated_program( mut self, fallback_fn: Option, + opt_level: OptLevel, ) -> Result { let mut prologue = self.build_prologue(); self.append_globals_allocation(&mut prologue); - self.append_before_entries(&mut prologue)?; + self.append_before_entries(&mut prologue, opt_level)?; match (self.experimental.new_encoding, self.kind) { (true, ProgramKind::Contract) => { @@ -120,7 +122,7 @@ impl AbstractProgram { // Optimize and then verify abstract functions. let abstract_functions = all_functions - .map(|instruction_set| instruction_set.optimize(&self.data_section)) + .map(|instruction_set| instruction_set.optimize(&self.data_section, opt_level)) .map(AbstractInstructionSet::verify) .collect::, CompileError>>()?; @@ -152,8 +154,12 @@ impl AbstractProgram { fn append_before_entries( &self, prologue: &mut AllocatedAbstractInstructionSet, + opt_level: OptLevel, ) -> Result<(), CompileError> { - let before_entries = self.before_entries.clone().optimize(&self.data_section); + let before_entries = self + .before_entries + .clone() + .optimize(&self.data_section, opt_level); let before_entries = before_entries.verify()?; let mut before_entries = before_entries.allocate_registers()?; prologue.ops.append(&mut before_entries.ops); diff --git a/sway-core/src/asm_lang/mod.rs b/sway-core/src/asm_lang/mod.rs index 91feeb1264..fa518a7218 100644 --- a/sway-core/src/asm_lang/mod.rs +++ b/sway-core/src/asm_lang/mod.rs @@ -733,6 +733,13 @@ impl Op { } } + pub(crate) fn use_registers_mut(&mut self) -> BTreeSet<&mut VirtualRegister> { + match &mut self.opcode { + Either::Left(virt_op) => virt_op.use_registers_mut(), + Either::Right(org_op) => org_op.use_registers_mut(), + } + } + pub(crate) fn def_registers(&self) -> BTreeSet<&VirtualRegister> { match &self.opcode { Either::Left(virt_op) => virt_op.def_registers(), @@ -1364,6 +1371,26 @@ impl ControlFlowOp { .collect() } + pub(crate) fn use_registers_mut(&mut self) -> BTreeSet<&mut Reg> { + use ControlFlowOp::*; + (match self { + Label(_) + | Comment + | Jump(_) + | Call(_) + | SaveRetAddr(..) + | DataSectionOffsetPlaceholder + | ConfigurablesOffsetPlaceholder + | LoadLabel(..) + | PushAll(_) + | PopAll(_) => vec![], + + JumpIfNotZero(r1, _) => vec![r1], + }) + .into_iter() + .collect() + } + pub(crate) fn def_registers(&self) -> BTreeSet<&Reg> { use ControlFlowOp::*; (match self { diff --git a/sway-core/src/asm_lang/virtual_ops.rs b/sway-core/src/asm_lang/virtual_ops.rs index 137db3ac48..d48dfd7b96 100644 --- a/sway-core/src/asm_lang/virtual_ops.rs +++ b/sway-core/src/asm_lang/virtual_ops.rs @@ -610,6 +610,7 @@ impl VirtualOp { .into_iter() .collect() } + /// Returns a list of all registers *read* by instruction `self`. pub(crate) fn use_registers(&self) -> BTreeSet<&VirtualRegister> { use VirtualOp::*; @@ -737,6 +738,133 @@ impl VirtualOp { .collect() } + /// Returns a list of all registers *read* by instruction `self`. + pub(crate) fn use_registers_mut(&mut self) -> BTreeSet<&mut VirtualRegister> { + use VirtualOp::*; + (match self { + /* Arithmetic/Logic (ALU) Instructions */ + ADD(_r1, r2, r3) => vec![r2, r3], + ADDI(_r1, r2, _i) => vec![r2], + AND(_r1, r2, r3) => vec![r2, r3], + ANDI(_r1, r2, _i) => vec![r2], + DIV(_r1, r2, r3) => vec![r2, r3], + DIVI(_r1, r2, _i) => vec![r2], + EQ(_r1, r2, r3) => vec![r2, r3], + EXP(_r1, r2, r3) => vec![r2, r3], + EXPI(_r1, r2, _i) => vec![r2], + GT(_r1, r2, r3) => vec![r2, r3], + LT(_r1, r2, r3) => vec![r2, r3], + MLOG(_r1, r2, r3) => vec![r2, r3], + MOD(_r1, r2, r3) => vec![r2, r3], + MODI(_r1, r2, _i) => vec![r2], + MOVE(_r1, r2) => vec![r2], + MOVI(_r1, _i) => vec![], + MROO(_r1, r2, r3) => vec![r2, r3], + MUL(_r1, r2, r3) => vec![r2, r3], + MULI(_r1, r2, _i) => vec![r2], + NOOP => vec![], + NOT(_r1, r2) => vec![r2], + OR(_r1, r2, r3) => vec![r2, r3], + ORI(_r1, r2, _i) => vec![r2], + SLL(_r1, r2, r3) => vec![r2, r3], + SLLI(_r1, r2, _i) => vec![r2], + SRL(_r1, r2, r3) => vec![r2, r3], + SRLI(_r1, r2, _i) => vec![r2], + SUB(_r1, r2, r3) => vec![r2, r3], + SUBI(_r1, r2, _i) => vec![r2], + XOR(_r1, r2, r3) => vec![r2, r3], + XORI(_r1, r2, _i) => vec![r2], + // Note that most of the `WQ..` instructions *read* from the `r1` result register, + // because the register itself does not contain the result, but provides the + // memory address at which the result will be stored. + WQOP(r1, r2, r3, _) => vec![r1, r2, r3], + WQML(r1, r2, r3, _) => vec![r1, r2, r3], + WQDV(r1, r2, r3, _) => vec![r1, r2, r3], + WQMD(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + WQCM(_, r2, r3, _) => vec![r2, r3], + WQAM(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + WQMM(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + + /* Control Flow Instructions */ + JMP(r1) => vec![r1], + JI(_im) => vec![], + JNE(r1, r2, r3) => vec![r1, r2, r3], + JNEI(r1, r2, _i) => vec![r1, r2], + JNZI(r1, _i) => vec![r1], + RET(r1) => vec![r1], + + /* Memory Instructions */ + ALOC(hp, r1) => vec![hp, r1], + CFEI(sp, _imm) => vec![sp], + CFSI(sp, _imm) => vec![sp], + CFE(sp, r1) => vec![sp, r1], + CFS(sp, r1) => vec![sp, r1], + LB(_r1, r2, _i) => vec![r2], + LW(_r1, r2, _i) => vec![r2], + MCL(r1, r2) => vec![r1, r2], + MCLI(r1, _imm) => vec![r1], + MCP(r1, r2, r3) => vec![r1, r2, r3], + MCPI(r1, r2, _imm) => vec![r1, r2], + MEQ(_r1, r2, r3, r4) => vec![r2, r3, r4], + SB(r1, r2, _i) => vec![r1, r2], + SW(r1, r2, _i) => vec![r1, r2], + + /* Contract Instructions */ + BAL(_r1, r2, r3) => vec![r2, r3], + BHEI(_r1) => vec![], + BHSH(r1, r2) => vec![r1, r2], + BURN(r1, r2) => vec![r1, r2], + CALL(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + CB(r1) => vec![r1], + CCP(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + CROO(r1, r2) => vec![r1, r2], + CSIZ(_r1, r2) => vec![r2], + BSIZ(_r1, r2) => vec![r2], + LDC(r1, r2, r3, _i0) => vec![r1, r2, r3], + BLDD(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + LOG(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + LOGD(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + MINT(r1, r2) => vec![r1, r2], + RETD(r1, r2) => vec![r1, r2], + RVRT(r1) => vec![r1], + SMO(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + SCWQ(r1, _r2, r3) => vec![r1, r3], + SRW(_r1, _r2, r3) => vec![r3], + SRWQ(r1, _r2, r3, r4) => vec![r1, r3, r4], + SWW(r1, _r2, r3) => vec![r1, r3], + SWWQ(r1, _r2, r3, r4) => vec![r1, r3, r4], + TIME(_r1, r2) => vec![r2], + TR(r1, r2, r3) => vec![r1, r2, r3], + TRO(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + + /* Cryptographic Instructions */ + ECK1(r1, r2, r3) => vec![r1, r2, r3], + ECR1(r1, r2, r3) => vec![r1, r2, r3], + ED19(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + K256(r1, r2, r3) => vec![r1, r2, r3], + S256(r1, r2, r3) => vec![r1, r2, r3], + ECOP(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + EPAR(_r1, r2, r3, r4) => vec![r2, r3, r4], + + /* Other Instructions */ + ECAL(r1, r2, r3, r4) => vec![r1, r2, r3, r4], + FLAG(r1) => vec![r1], + GM(_r1, _imm) => vec![], + GTF(_r1, r2, _i) => vec![r2], + + /* Non-VM Instructions */ + BLOB(_imm) => vec![], + DataSectionOffsetPlaceholder => vec![], + ConfigurablesOffsetPlaceholder => vec![], + LoadDataId(_r1, _i) => vec![], + AddrDataId(_r1, _i) => vec![], + + Undefined => vec![], + }) + .into_iter() + .collect() + } + /// Returns a list of all registers *written* by instruction `self`. All of our opcodes define /// exactly 0 or 1 register, so the size of this returned vector should always be at most 1. pub(crate) fn def_registers(&self) -> BTreeSet<&VirtualRegister> { diff --git a/sway-core/src/build_config.rs b/sway-core/src/build_config.rs index 15fda8cd16..dbf8c7f94e 100644 --- a/sway-core/src/build_config.rs +++ b/sway-core/src/build_config.rs @@ -256,6 +256,17 @@ impl BuildConfig { } } + /// Dummy build config that can be used for testing. + /// This is not not valid generally, but asm generation will accept it. + pub fn dummy_for_asm_generation() -> Self { + Self::root_from_file_name_and_manifest_path( + PathBuf::from("/"), + PathBuf::from("/"), + BuildTarget::default(), + DbgGeneration::None, + ) + } + pub fn with_print_dca_graph(self, a: Option) -> Self { Self { print_dca_graph: a, diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/const_generics/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_fail/language/const_generics/stdout.snap index ed3b3372d5..b26a0ffc23 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/language/const_generics/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/const_generics/stdout.snap @@ -1,5 +1,5 @@ --- -source: test/tests/tests.rs +source: test/src/snapshot/mod.rs --- > forc build --path test/src/e2e_vm_tests/test_programs/should_fail/language/const_generics exit status: 1 @@ -28,4 +28,4 @@ output: Building test/src/e2e_vm_tests/test_programs/should_fail/language/const_generics Compiling library std (sway-lib-std) Compiling script const_generics (test/src/e2e_vm_tests/test_programs/should_fail/language/const_generics) - Finished debug [unoptimized + fuel] target(s) [272 B] in ??? + Finished debug [unoptimized + fuel] target(s) [264 B] in ??? diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/attributes_deprecated/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/attributes_deprecated/stdout.snap index eb89f9bdba..9d9c938137 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/attributes_deprecated/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/attributes_deprecated/stdout.snap @@ -182,4 +182,4 @@ warning: Function is deprecated ____ Compiled contract "attributes_deprecated" with 19 warnings. - Finished release [optimized + fuel] target(s) [1.152 KB] in ??? + Finished release [optimized + fuel] target(s) [1.056 KB] in ??? 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 d8c52d54b8..c63a44c8f7 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": 6640 + "offset": 6232 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "U8", - "offset": 6832 + "offset": 6424 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "ANOTHER_U8", - "offset": 6568 + "offset": 6160 }, { "concreteTypeId": "29881aad8730c5ab11d275376323d8e4ff4179aae8ccb6c13fe4902137e162ef", "name": "U16", - "offset": 6776 + "offset": 6368 }, { "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "name": "U32", - "offset": 6816 + "offset": 6408 }, { "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "name": "U64", - "offset": 6824 + "offset": 6416 }, { "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", "name": "U256", - "offset": 6784 + "offset": 6376 }, { "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", "name": "B256", - "offset": 6608 + "offset": 6200 }, { "concreteTypeId": "81fc10c4681a3271cf2d66b2ec6fbc8ed007a442652930844fcf11818c295bff", "name": "CONFIGURABLE_STRUCT", - "offset": 6728 + "offset": 6320 }, { "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", "name": "CONFIGURABLE_ENUM_A", - "offset": 6648 + "offset": 6240 }, { "concreteTypeId": "a2922861f03be8a650595dd76455b95383a61b46dd418f02607fa2e00dc39d5c", "name": "CONFIGURABLE_ENUM_B", - "offset": 6688 + "offset": 6280 }, { "concreteTypeId": "4926d35d1a5157936b0a29bc126b8aace6d911209a5c130e9b716b0c73643ea6", "name": "ARRAY_BOOL", - "offset": 6576 + "offset": 6168 }, { "concreteTypeId": "776fb5a3824169d6736138565fdc20aad684d9111266a5ff6d5c675280b7e199", "name": "ARRAY_U64", - "offset": 6584 + "offset": 6176 }, { "concreteTypeId": "c998ca9a5f221fe7b5c66ae70c8a9562b86d964408b00d17f883c906bc1fe4be", "name": "TUPLE_BOOL_U64", - "offset": 6760 + "offset": 6352 }, { "concreteTypeId": "94f0fa95c830be5e4f711963e83259fe7e8bc723278ab6ec34449e791a99b53a", "name": "STR_4", - "offset": 6752 + "offset": 6344 }, { "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", "name": "NOT_USED", - "offset": 6744 + "offset": 6336 } ], "encodingVersion": "1", diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap index 6aea07d2cf..a17bf55924 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode/stdout.snap @@ -1,6 +1,5 @@ --- source: test/src/snapshot/mod.rs -assertion_line: 125 --- > forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/configurable_dedup_decode --release --ir final --asm final exit status: 0 @@ -378,31 +377,30 @@ addi $$arg2 $ssp i0 ; get pointer to configurable TUPLE stack address sub $$reta $pc $is ; get current instruction offset from instructions start ($is) srli $$reta $$reta i2 ; get current instruction offset in 32-bit words addi $$reta $$reta i4 ; set new return address -jmpf $zero i78 ; decode configurable TUPLE +jmpf $zero i77 ; decode configurable TUPLE addr $$arg0 data_Configurable_1; get pointer to configurable WRAPPED default value addi $$arg1 $zero i8 ; get length of configurable WRAPPED default value addi $$arg2 $ssp i8 ; get pointer to configurable WRAPPED stack address sub $$reta $pc $is ; get current instruction offset from instructions start ($is) srli $$reta $$reta i2 ; get current instruction offset in 32-bit words addi $$reta $$reta i4 ; set new return address -jmpf $zero i71 ; decode configurable WRAPPED +jmpf $zero i70 ; decode configurable WRAPPED move $$locbase $sp ; save locals base register for function __entry cfei i360 ; allocate 360 bytes for locals and 0 slots for call arguments addi $r0 $$locbase i320 ; get offset to local sub $$reta $pc $is ; get current instruction offset from instructions start ($is) srli $$reta $$reta i2 ; get current instruction offset in 32-bit words addi $$reta $$reta i4 ; [call]: set new return address -jmpf $zero i126 ; [call]: call main_8 +jmpf $zero i118 ; [call]: call main_8 move $r1 $$retv ; [call]: copy the return value movi $r2 i1024 ; initialize constant into register aloc $r2 -move $r2 $hp ; return value from ASM block with return register hp -addi $r3 $$locbase i112 ; get offset to local -sw $$locbase $r2 i14 ; store word -movi $r2 i1024 ; initialize constant into register -sw $$locbase $r2 i15 ; store word +addi $r2 $$locbase i112 ; get offset to local +sw $$locbase $hp i14 ; store word +movi $r3 i1024 ; initialize constant into register +sw $$locbase $r3 i15 ; store word sw $$locbase $zero i16 ; store word -mcpi $$locbase $r3 i24 ; copy memory +mcpi $$locbase $r2 i24 ; copy memory addi $r2 $$locbase i184 ; get offset to local mcpi $r2 $$locbase i24 ; copy memory addi $r3 $$locbase i272 ; get offset to local @@ -411,27 +409,27 @@ addi $r2 $$locbase i24 ; get offset to local mcpi $r2 $r3 i24 ; copy memory addi $r3 $$locbase i136 ; get offset to local mcpi $r3 $r2 i24 ; copy memory -lw $r6 $$locbase i17 ; load word -lw $r5 $$locbase i18 ; load word -lw $r2 $$locbase i19 ; load word -movi $r3 i8 ; initialize constant into register -add $r3 $r2 $r3 -gt $r4 $r3 $r5 -jnzf $r4 $zero i1 +lw $r2 $$locbase i17 ; load word +lw $r6 $$locbase i18 ; load word +lw $r3 $$locbase i19 ; load word +movi $r4 i8 ; initialize constant into register +add $r4 $r3 $r4 +gt $r5 $r4 $r6 +jnzf $r5 $zero i1 jmpf $zero i7 -movi $r4 i2 ; initialize constant into register -mul $r4 $r5 $r4 -movi $r5 i8 ; initialize constant into register -add $r5 $r4 $r5 -aloc $r5 -mcp $hp $r6 $r2 -move $r6 $hp ; return value from ASM block with return register hp -add $r2 $r6 $r2 -sw $r2 $r1 i0 ; store word +movi $r5 i2 ; initialize constant into register +mul $r5 $r6 $r5 +movi $r6 i8 ; initialize constant into register +add $r6 $r5 $r6 +aloc $r6 +mcp $hp $r2 $r3 +move $r2 $hp ; move parameter from branch to block argument +add $r3 $r2 $r3 +sw $r3 $r1 i0 ; store word addi $r1 $$locbase i208 ; get offset to local -sw $$locbase $r6 i26 ; store word -sw $$locbase $r5 i27 ; store word -sw $$locbase $r3 i28 ; store word +sw $$locbase $r2 i26 ; store word +sw $$locbase $r6 i27 ; store word +sw $$locbase $r4 i28 ; store word addi $r2 $$locbase i48 ; get offset to local mcpi $r2 $r1 i24 ; copy memory addi $r1 $$locbase i248 ; get offset to local @@ -461,17 +459,13 @@ pshl i15 ; save registers 16..40 pshh i524288 ; save registers 40..64 move $$locbase $sp ; save locals base register for function abi_decode_in_place_0 cfei i24 ; allocate 24 bytes for locals and 0 slots for call arguments -move $r0 $$arg0 ; save argument 0 (ptr) -move $r1 $$arg1 ; save argument 1 (len) move $r2 $$arg2 ; save argument 2 (target) move $r3 $$reta ; save return address -move $$arg0 $r0 ; [call]: pass argument 0 -move $$arg1 $r1 ; [call]: pass argument 1 move $$arg2 $$locbase ; [call]: pass argument 2 sub $$reta $pc $is ; get current instruction offset from instructions start ($is) srli $$reta $$reta i2 ; get current instruction offset in 32-bit words addi $$reta $$reta i4 ; [call]: set new return address -jmpf $zero i19 ; [call]: call from_parts_1 +jmpf $zero i18 ; [call]: call from_parts_1 lw $r0 $$retv i0 ; load word sw $$locbase $r0 i1 ; store word addi $r0 $$locbase i8 ; get offset to local @@ -479,9 +473,8 @@ move $$arg0 $r0 ; [call]: pass argument 0 sub $$reta $pc $is ; get current instruction offset from instructions start ($is) srli $$reta $$reta i2 ; get current instruction offset in 32-bit words addi $$reta $$reta i4 ; [call]: set new return address -jmpf $zero i23 ; [call]: call abi_decode_3 -move $r0 $$retv ; [call]: copy the return value -sw $$locbase $r0 i2 ; store word +jmpf $zero i21 ; [call]: call abi_decode_3 +sw $$locbase $$retv i2 ; store word addi $r0 $$locbase i16 ; get offset to local movi $r1 i8 ; initialize constant into register mcp $r2 $r0 $r1 ; mcp target temp size @@ -491,49 +484,45 @@ move $$reta $r3 ; restore return address poph i524288 ; restore registers 40..64 popl i15 ; restore registers 16..40 jmp $$reta ; return from call -pshl i7 ; save registers 16..40 +pshl i3 ; save registers 16..40 pshh i524288 ; save registers 40..64 move $$locbase $sp ; save locals base register for function from_parts_1 -move $r0 $$arg0 ; save argument 0 (ptr) -move $r1 $$arg2 ; save argument 2 (__ret_value) -move $r2 $$reta ; save return address -sw $r1 $r0 i0 ; store word -move $$retv $r1 ; set return value -move $$reta $r2 ; restore return address -poph i524288 ; restore registers 40..64 -popl i7 ; restore registers 16..40 -jmp $$reta ; return from call -pshl i31 ; save registers 16..40 -pshh i524288 ; save registers 40..64 -move $$locbase $sp ; save locals base register for function abi_decode_3 -move $r0 $$arg0 ; save argument 0 (buffer) +move $r0 $$arg2 ; save argument 2 (__ret_value) move $r1 $$reta ; save return address -lw $r2 $r0 i0 ; load word -lw $r2 $r2 i0 ; lw val ptr i0 -lw $r3 $r0 i0 ; load word -movi $r4 i8 ; initialize constant into register -add $r3 $r3 $r4 -sw $r0 $r3 i0 ; store word -move $$retv $r2 ; set return value +sw $$arg2 $$arg0 i0 ; store word +move $$retv $r0 ; set return value move $$reta $r1 ; restore return address poph i524288 ; restore registers 40..64 -popl i31 ; restore registers 16..40 +popl i3 ; restore registers 16..40 jmp $$reta ; return from call -pshl i7 ; save registers 16..40 +pshl i15 ; save registers 16..40 pshh i524288 ; save registers 40..64 -move $$locbase $sp ; save locals base register for function main_8 +move $$locbase $sp ; save locals base register for function abi_decode_3 move $r0 $$reta ; save return address -lw $r1 $ssp i1 ; load word -lw $r2 $ssp i0 ; load word -add $r1 $r1 $r2 +lw $r1 $$arg0 i0 ; load word +lw $r1 $r1 i0 ; lw val ptr i0 +lw $r2 $$arg0 i0 ; load word +movi $r3 i8 ; initialize constant into register +add $r2 $r2 $r3 +sw $$arg0 $r2 i0 ; store word move $$retv $r1 ; set return value move $$reta $r0 ; restore return address poph i524288 ; restore registers 40..64 -popl i7 ; restore registers 16..40 +popl i15 ; restore registers 16..40 +jmp $$reta ; return from call +pshl i3 ; save registers 16..40 +pshh i524288 ; save registers 40..64 +move $$locbase $sp ; save locals base register for function main_8 +lw $r0 $ssp i1 ; load word +lw $r1 $ssp i0 ; load word +add $r0 $r0 $r1 +move $$retv $r0 ; set return value +poph i524288 ; restore registers 40..64 +popl i3 ; restore registers 16..40 jmp $$reta ; return from call .data: data__0 .bytes[8] 00 00 00 00 00 00 00 02 ........ data__1 .bytes[8] 00 00 00 00 00 00 00 01 ........ - Finished release [optimized + fuel] target(s) [688 B] in ??? + Finished release [optimized + fuel] target(s) [648 B] in ??? diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg/stdout.snap index 96fc5f9d44..91949dc85b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg/stdout.snap @@ -2,15 +2,15 @@ source: test/src/snapshot/mod.rs --- > forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg --asm final | grep ecal -ecal $r4 $r2 $r3 $r0 ; ecal id fd buf count +ecal $r0 $r2 $r3 $$retv ; ecal id fd buf count ecal $r2 $r1 $zero $zero ; ecal id fd zero zero -ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count -ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count -ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count -ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count +ecal $r4 $r1 $r2 $r3 ; ecal id fd buf count +ecal $r4 $r1 $r2 $r3 ; ecal id fd buf count +ecal $r4 $r1 $r2 $r3 ; ecal id fd buf count +ecal $r4 $r1 $r2 $r3 ; ecal id fd buf count ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count ecal $r2 $r0 $r1 $r3 ; ecal id fd buf count -ecal $r3 $r1 $r2 $r4 ; ecal id fd buf count +ecal $r3 $r1 $r2 $one ; ecal id fd buf count > forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg --release --asm final | grep ecal @@ -20,12 +20,12 @@ output: Building test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg Compiling library std (sway-lib-std) Compiling script dbg (test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg) - Finished debug [unoptimized + fuel] target(s) [37.368 KB] in ??? + Finished debug [unoptimized + fuel] target(s) [36.792 KB] in ??? Running 1 test, filtered 0 tests tested -- dbg - test call_main ... ok (???, 103315 gas) + test call_main ... ok (???, 97362 gas) [src/main.sw:13:13] () = () [src/main.sw:15:13] true = true [src/main.sw:16:13] false = false diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release/stdout.snap index 7aaa071e50..59733f1c6f 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release/stdout.snap @@ -6,10 +6,10 @@ ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count -ecal $r4 $r2 $r3 $r0 ; ecal id fd buf count +ecal $r0 $r2 $r3 $$retv ; ecal id fd buf count ecal $r2 $r1 $zero $zero ; ecal id fd zero zero -ecal $r3 $r0 $r1 $r2 ; ecal id fd buf count -ecal $r3 $r1 $r2 $r4 ; ecal id fd buf count +ecal $r4 $r1 $r2 $r3 ; ecal id fd buf count +ecal $r3 $r1 $r2 $one ; ecal id fd buf count > forc build --path test/src/e2e_vm_tests/test_programs/should_pass/language/intrinsics/dbg_release --release --asm final | grep ecal ecal $r4 $r5 $r2 $r3 ; ecal id fd buf count @@ -27,6 +27,6 @@ ecal $r0 $r1 $zero $zero ; ecal id fd zero zero ecal $r0 $r1 $zero $zero ; ecal id fd zero zero ecal $r0 $r1 $zero $zero ; ecal id fd zero zero ecal $r0 $r1 $zero $zero ; ecal id fd zero zero -ecal $r3 $r4 $r2 $r0 ; ecal id fd buf count +ecal $r0 $r3 $r2 $$retv ; ecal id fd buf count ecal $r3 $r4 $r1 $r2 ; ecal id fd buf count -ecal $r1 $r2 $r3 $r4 ; ecal id fd buf count +ecal $r1 $r2 $$locbase $one ; ecal id fd buf count diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_contract/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_contract/stdout.snap index 2d9dfaa83b..fc5f9abb0b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_contract/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_contract/stdout.snap @@ -8,42 +8,42 @@ output: Compiling library std (test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-core) Compiling library panicking_lib (test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib) Compiling contract panicking_contract (test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_contract) - Finished release [optimized + fuel] target(s) [8.472 KB] in ??? + Finished release [optimized + fuel] target(s) [8.208 KB] in ??? Running 11 tests, filtered 0 tests tested -- panicking_contract - test test_directly_panicking_method ... ok (???, 1786 gas) + test test_directly_panicking_method ... ok (???, 1735 gas) Decoded log value: C(true), log rb: 5503570629422409978 Revert code: ffffffff00000000 - test test_nested_panic_inlined ... ok (???, 3002 gas) + test test_nested_panic_inlined ... ok (???, 2905 gas) Decoded log value: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]), log rb: 5503570629422409978 Revert code: ffffffff00000004 - test test_nested_panic_inlined_same_revert_code ... ok (???, 3002 gas) + test test_nested_panic_inlined_same_revert_code ... ok (???, 2905 gas) Decoded log value: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]), log rb: 5503570629422409978 Revert code: ffffffff00000004 - test test_nested_panic_not_inlined ... ok (???, 3206 gas) + test test_nested_panic_not_inlined ... ok (???, 3098 gas) Decoded log value: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]), log rb: 5503570629422409978 Revert code: ffffffff00000005 - test test_nested_panic_not_inlined_same_revert_code ... ok (???, 3206 gas) + test test_nested_panic_not_inlined_same_revert_code ... ok (???, 3098 gas) Decoded log value: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]), log rb: 5503570629422409978 Revert code: ffffffff00000005 - test test_generic_panic_with_unit ... ok (???, 2133 gas) + test test_generic_panic_with_unit ... ok (???, 2055 gas) Decoded log value: (), log rb: 3330666440490685604 Revert code: ffffffff00000003 - test test_generic_panic_with_unit_same_revert_code ... ok (???, 2133 gas) + test test_generic_panic_with_unit_same_revert_code ... ok (???, 2055 gas) Decoded log value: (), log rb: 3330666440490685604 Revert code: ffffffff00000003 - test test_generic_panic_with_str ... ok (???, 2140 gas) + test test_generic_panic_with_str ... ok (???, 2068 gas) Decoded log value: AsciiString { data: "generic panic with string" }, log rb: 10098701174489624218 Revert code: ffffffff00000001 - test test_generic_panic_with_different_str_same_revert_code ... ok (???, 1815 gas) + test test_generic_panic_with_different_str_same_revert_code ... ok (???, 1761 gas) Decoded log value: AsciiString { data: "generic panic with different string" }, log rb: 10098701174489624218 Revert code: ffffffff00000001 - test test_generic_panic_with_error_type_enum ... ok (???, 1953 gas) + test test_generic_panic_with_error_type_enum ... ok (???, 1890 gas) Decoded log value: A, log rb: 5503570629422409978 Revert code: ffffffff00000002 - test test_generic_panic_with_error_type_enum_different_variant_same_revert_code ... ok (???, 2112 gas) + test test_generic_panic_with_error_type_enum_different_variant_same_revert_code ... ok (???, 2043 gas) Decoded log value: B(42), log rb: 5503570629422409978 Revert code: ffffffff00000002 diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap index d6950f8f1e..86cfba9ff5 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib/stdout.snap @@ -7,63 +7,63 @@ output: Building test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib Compiling library std (test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-core) Compiling library panicking_lib (test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib) - Finished release [optimized + fuel] target(s) [6.2 KB] in ??? + Finished release [optimized + fuel] target(s) [6.056 KB] in ??? Running 18 tests, filtered 0 tests tested -- panicking_lib - test test_nested_panic_inlined ... ok (???, 833 gas) + test test_nested_panic_inlined ... ok (???, 822 gas) Decoded log value: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]), log rb: 2721958641300806892 Revert code: ffffffff00000000 - test test_nested_panic_inlined_same_revert_code ... ok (???, 833 gas) + test test_nested_panic_inlined_same_revert_code ... ok (???, 822 gas) Decoded log value: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]), log rb: 2721958641300806892 Revert code: ffffffff00000000 - test test_nested_panic_not_inlined ... ok (???, 813 gas) + test test_nested_panic_not_inlined ... ok (???, 803 gas) Decoded log value: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]), log rb: 2721958641300806892 Revert code: ffffffff00000001 - test test_nested_panic_not_inlined_same_revert_code ... ok (???, 813 gas) + test test_nested_panic_not_inlined_same_revert_code ... ok (???, 803 gas) Decoded log value: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]), log rb: 2721958641300806892 Revert code: ffffffff00000001 - test test_generic_panic_with_unit ... ok (???, 193 gas) + test test_generic_panic_with_unit ... ok (???, 189 gas) Decoded log value: (), log rb: 3330666440490685604 Revert code: ffffffff00000002 - test test_generic_panic_with_unit_same_revert_code ... ok (???, 193 gas) + test test_generic_panic_with_unit_same_revert_code ... ok (???, 189 gas) Decoded log value: (), log rb: 3330666440490685604 Revert code: ffffffff00000002 - test test_generic_panic_with_str ... ok (???, 311 gas) + test test_generic_panic_with_str ... ok (???, 307 gas) Decoded log value: AsciiString { data: "generic panic with string" }, log rb: 10098701174489624218 Revert code: ffffffff00000003 - test test_generic_panic_with_different_str_same_revert_code ... ok (???, 311 gas) + test test_generic_panic_with_different_str_same_revert_code ... ok (???, 307 gas) Decoded log value: AsciiString { data: "generic panic different string" }, log rb: 10098701174489624218 Revert code: ffffffff00000003 - test test_generic_panic_with_error_type_enum_variant ... ok (???, 334 gas) + test test_generic_panic_with_error_type_enum_variant ... ok (???, 327 gas) Decoded log value: A, log rb: 2721958641300806892 Revert code: ffffffff00000004 - test test_generic_panic_with_error_type_enum_different_variant_same_revert_code ... ok (???, 334 gas) + test test_generic_panic_with_error_type_enum_different_variant_same_revert_code ... ok (???, 327 gas) Decoded log value: A, log rb: 2721958641300806892 Revert code: ffffffff00000004 - test test_panic_without_arg ... ok (???, 193 gas) + test test_panic_without_arg ... ok (???, 189 gas) Decoded log value: (), log rb: 3330666440490685604 Revert code: ffffffff00000005 - test test_panic_with_unit ... ok (???, 193 gas) + test test_panic_with_unit ... ok (???, 189 gas) Decoded log value: (), log rb: 3330666440490685604 Revert code: ffffffff00000006 - test test_panic_with_str ... ok (???, 311 gas) + test test_panic_with_str ... ok (???, 307 gas) Decoded log value: AsciiString { data: "panic with string" }, log rb: 10098701174489624218 Revert code: ffffffff00000007 - test test_panic_with_error_type_enum ... ok (???, 440 gas) + test test_panic_with_error_type_enum ... ok (???, 431 gas) Decoded log value: C(true), log rb: 2721958641300806892 Revert code: ffffffff00000008 - test test_panic_with_generic_error_type_enum ... ok (???, 354 gas) + test test_panic_with_generic_error_type_enum ... ok (???, 348 gas) Decoded log value: A(42), log rb: 12408470889216862137 Revert code: ffffffff00000009 - test test_panic_with_nested_generic_error_type ... ok (???, 633 gas) + test test_panic_with_nested_generic_error_type ... ok (???, 622 gas) Decoded log value: B(B(C(true))), log rb: 14988555917426256081 Revert code: ffffffff0000000a - test test_panic_with_generic_error_type_enum_with_abi_encode ... ok (???, 354 gas) + test test_panic_with_generic_error_type_enum_with_abi_encode ... ok (???, 348 gas) Decoded log value: A(42), log rb: 17388243649088655852 Revert code: ffffffff0000000b - test test_panic_with_nested_generic_error_type_enum_with_abi_encode ... ok (???, 633 gas) + test test_panic_with_nested_generic_error_type_enum_with_abi_encode ... ok (???, 622 gas) Decoded log value: B(B(C(true))), log rb: 3755100321495500961 Revert code: ffffffff0000000c diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_script/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_script/stdout.snap index 38125cb644..218f85ccf7 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_script/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_script/stdout.snap @@ -8,42 +8,42 @@ output: Compiling library std (test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-core) Compiling library panicking_lib (test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_lib) Compiling script panicking_script (test/src/e2e_vm_tests/test_programs/should_pass/language/panic_expression/panicking_script) - Finished release [optimized + fuel] target(s) [4 KB] in ??? + Finished release [optimized + fuel] target(s) [3.904 KB] in ??? Running 11 tests, filtered 0 tests tested -- panicking_script - test test_panic_in_main ... ok (???, 394 gas) + test test_panic_in_main ... ok (???, 388 gas) Decoded log value: C(true), log rb: 5503570629422409978 Revert code: ffffffff00000000 - test test_nested_panic_inlined ... ok (???, 816 gas) + test test_nested_panic_inlined ... ok (???, 806 gas) Decoded log value: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]), log rb: 5503570629422409978 Revert code: ffffffff00000001 - test test_nested_panic_inlined_same_revert_code ... ok (???, 816 gas) + test test_nested_panic_inlined_same_revert_code ... ok (???, 806 gas) Decoded log value: E([AsciiString { data: "this" }, AsciiString { data: "is not" }, AsciiString { data: "the best practice" }]), log rb: 5503570629422409978 Revert code: ffffffff00000001 - test test_nested_panic_not_inlined ... ok (???, 796 gas) + test test_nested_panic_not_inlined ... ok (???, 787 gas) Decoded log value: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]), log rb: 5503570629422409978 Revert code: ffffffff00000002 - test test_nested_panic_not_inlined_same_revert_code ... ok (???, 796 gas) + test test_nested_panic_not_inlined_same_revert_code ... ok (???, 787 gas) Decoded log value: E([AsciiString { data: "to have" }, AsciiString { data: "strings" }, AsciiString { data: "in error enum variants" }]), log rb: 5503570629422409978 Revert code: ffffffff00000002 - test test_generic_panic_with_unit ... ok (???, 193 gas) + test test_generic_panic_with_unit ... ok (???, 189 gas) Decoded log value: (), log rb: 3330666440490685604 Revert code: ffffffff00000003 - test test_generic_panic_with_unit_same_revert_code ... ok (???, 193 gas) + test test_generic_panic_with_unit_same_revert_code ... ok (???, 189 gas) Decoded log value: (), log rb: 3330666440490685604 Revert code: ffffffff00000003 - test test_generic_panic_with_str ... ok (???, 291 gas) + test test_generic_panic_with_str ... ok (???, 288 gas) Decoded log value: AsciiString { data: "generic panic with string" }, log rb: 10098701174489624218 Revert code: ffffffff00000004 - test test_generic_panic_with_different_str_same_revert_code ... ok (???, 291 gas) + test test_generic_panic_with_different_str_same_revert_code ... ok (???, 288 gas) Decoded log value: AsciiString { data: "generic panic with different string" }, log rb: 10098701174489624218 Revert code: ffffffff00000004 - test test_generic_panic_with_error_type_enum ... ok (???, 318 gas) + test test_generic_panic_with_error_type_enum ... ok (???, 312 gas) Decoded log value: A, log rb: 5503570629422409978 Revert code: ffffffff00000005 - test test_generic_panic_with_error_type_enum_different_variant_same_revert_code ... ok (???, 375 gas) + test test_generic_panic_with_error_type_enum_different_variant_same_revert_code ... ok (???, 369 gas) Decoded log value: B(42), log rb: 5503570629422409978 Revert code: ffffffff00000005 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 8b556c0638..33a992a9fb 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 @@ -9,7 +9,7 @@ { "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", "name": "SOME_U256", - "offset": 752 + "offset": 728 } ], "encodingVersion": "1", diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/panic_in_non_statement_positions/stdout.snap b/test/src/e2e_vm_tests/test_programs/should_pass/panic_in_non_statement_positions/stdout.snap index 55ae9c4002..5217e6d07a 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/panic_in_non_statement_positions/stdout.snap +++ b/test/src/e2e_vm_tests/test_programs/should_pass/panic_in_non_statement_positions/stdout.snap @@ -286,42 +286,42 @@ warning ____ Compiled library "panic_in_non_statement_positions" with 23 warnings. - Finished debug [unoptimized + fuel] target(s) [2.352 KB] in ??? + Finished debug [unoptimized + fuel] target(s) [2.272 KB] in ??? Running 16 tests, filtered 0 tests tested -- panic_in_non_statement_positions - test in_init ... ok (???, 338 gas) + test in_init ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_array ... ok (???, 338 gas) + test in_array ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_length_1_array ... ok (???, 338 gas) + test in_length_1_array ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_length_2_array_first ... ok (???, 338 gas) + test in_length_2_array_first ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_length_2_array_second ... ok (???, 338 gas) + test in_length_2_array_second ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_tuple ... ok (???, 338 gas) + test in_tuple ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_struct ... ok (???, 338 gas) + test in_struct ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_parentheses ... ok (???, 338 gas) + test in_parentheses ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_if_condition ... ok (???, 338 gas) + test in_if_condition ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_while_condition ... ok (???, 338 gas) + test in_while_condition ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_enum ... ok (???, 338 gas) + test in_enum ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_enum_multivariant ... ok (???, 338 gas) + test in_enum_multivariant ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_fun_arg ... ok (???, 338 gas) + test in_fun_arg ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_lazy_and ... ok (???, 338 gas) + test in_lazy_and ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_lazy_or ... ok (???, 338 gas) + test in_lazy_or ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 - test in_match_scrutinee ... ok (???, 338 gas) + test in_match_scrutinee ... ok (???, 332 gas) Decoded log value: E(42), log rb: 5087777005172090899 test result: OK. 16 passed; 0 failed; finished in ??? 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 83ce6763fb..9ef7a8ca80 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 = 0x878d6215fe8d406e08cb18053c97ee8bb25ba651e17e7cfe4964fc653b2f6808; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release +const CONTRACT_ID = 0x601848bef87baa5fb799e4bedab0dca3baa6da459663ca8808ceb68632db4061; // AUTO-CONTRACT-ID ../../test_contracts/array_of_structs_contract --release fn get_address() -> Option { Some(CONTRACT_ID.into()) 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 baf9826e51..e55febc6e2 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 @@ -9,12 +9,12 @@ use test_fuel_coin_abi::*; #[cfg(experimental_new_encoding = false)] const FUEL_COIN_CONTRACT_ID = 0xec2277ebe007ade87e3d797c3b1e070dcd542d5ef8f038b471f262ef9cebc87c; #[cfg(experimental_new_encoding = true)] -const FUEL_COIN_CONTRACT_ID = 0x6e8bc09f34b7eccea8cf518a38754669515084377ec13d8fd73f83da519816ad; // AUTO-CONTRACT-ID ../../test_contracts/test_fuel_coin_contract --release +const FUEL_COIN_CONTRACT_ID = 0x9c0dc897a9f6033f011b393b3c45e493e431afb7bb840ae9bd1a33c83576027a; // AUTO-CONTRACT-ID ../../test_contracts/test_fuel_coin_contract --release #[cfg(experimental_new_encoding = false)] const BALANCE_CONTRACT_ID = 0xf6cd545152ac83225e8e7df2efb5c6fa6e37bc9b9e977b5ea8103d28668925df; #[cfg(experimental_new_encoding = true)] -const BALANCE_CONTRACT_ID = 0xe78343b4ba20a65a3d012ab5f33366c0138672c71032d0c17f3f0485bd820477; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const BALANCE_CONTRACT_ID = 0xdf39b17a0e16748239c93f2520383a50e51f2519c1b087eb9139f3916fad883b; // 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 1a12e43061..b2acc6202f 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 = 0xe78343b4ba20a65a3d012ab5f33366c0138672c71032d0c17f3f0485bd820477; // AUTO-CONTRACT-ID ../../test_contracts/balance_test_contract --release +const CONTRACT_ID = 0xdf39b17a0e16748239c93f2520383a50e51f2519c1b087eb9139f3916fad883b; // 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 1562bf1999..7b97b625a7 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 = 0xe77828cc9433f3714af73bad1198b5234542eedc1e616d5c26c1643f216ebdd4; // AUTO-CONTRACT-ID ../../test_contracts/abi_with_tuples_contract --release +const CONTRACT_ID = 0x3de5658ed72a7485a686bcf83e69b29c034b7ae0445b59ba28eb513fab4dc760; // 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 e3c6ff4d00..282eb752f1 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 = 0xdda92a285d294c47fdd59cb82fedc380ed7337cbbd93593cf9dc943a2ca74072; // AUTO-CONTRACT-ID ../../test_contracts/basic_storage --release +const CONTRACT_ID = 0xf0ebf5d91c66bf07dbd76990a9dd73f32a9c0bbc58045d8389560fa0927e80df; // 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 9c3f916f83..5c2cd21bf2 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 = 0xb0899ebf2030d48330436b8025b9ca15243ac985f54024ea00d64d961b67482a; // AUTO-CONTRACT-ID ../../test_contracts/contract_with_type_aliases --release +const CONTRACT_ID = 0xce3e15c876e12191467ed399df1e678c11805395334ceb13ebf808ef69bc638a; // 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 ab95a504a9..f456a39342 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 = 0x0d25f1daa7976a7540b0e3d8ccdd30c3465693a3cf5bd55fe4aedf456aafe85b; // AUTO-CONTRACT-ID ../../test_contracts/increment_contract --release +const CONTRACT_ID = 0x67b9fcb5067d92d235ec95ce1d8359e620e90739d5bbd64b033ca8732b0f6479; // 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 e9cfbe6075..bbb255bb8f 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 = 0x9ff1242ab03642c1977b8a1d3b6fe8dd0fd2780cf039ed75e6f1503cefece8f8; // AUTO-CONTRACT-ID ../../test_contracts/storage_enum_contract --release +const CONTRACT_ID = 0x5c67778ef8e01497172df0276e3639525810297d36fe539014414cdbcd7f0b51; // 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 a4978f0c62..dbcfe95de7 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 = 0x6ab2528386b7d41c88a6dabe8a05b2f7b392984d4ec9b90be9e71a4f8815e1a8; // AUTO-CONTRACT-ID ../../test_contracts/auth_testing_contract --release +const CONTRACT_ID = 0xc0f3d199122a2c865a458b35f2d7c791f239aeb08994fb9ef018a687254ec8b6; // 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 d3916a9666..636bffd0bf 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 = 0x6dc84334725f3455666302c8570a2c5a48b17c1057f3a7b1e1b8e3845ab7e6bd; // AUTO-CONTRACT-ID ../../test_contracts/context_testing_contract --release +const CONTRACT_ID = 0x3fde98984d2360b0ecf4f23011ff057db9711c457c6cc0480cc14f65462feed2; // 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 7548740ac1..9b210886db 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 = 0x808902b1d27b2c477f3c0821e033fb7bf256060a47deb57e84881afde7ed933f; // AUTO-CONTRACT-ID ../../test_contracts/nested_struct_args_contract --release +const CONTRACT_ID = 0x8c01965f8049c5a3c1fe091c1bf0277bb3b2ddb2a858c6eab671564fd03257ef; // 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 95badb579e..765686814e 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 = 0x72c284ba7b906df994e63faf09382bfbf01aa7de8a9452665b66cdf0e3eb1978; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release +const CONTRACT_ID = 0x8d7200b20cb50676a66255fddbf2aa13565ad92ab42122e59e7868b7f74695c3; // AUTO-CONTRACT-ID ../../test_contracts/storage_access_contract --release fn main() -> bool { let caller = abi(StorageAccess, CONTRACT_ID); diff --git a/test/src/ir_generation/mod.rs b/test/src/ir_generation/mod.rs index b945d77af1..6a078a0d8e 100644 --- a/test/src/ir_generation/mod.rs +++ b/test/src/ir_generation/mod.rs @@ -10,7 +10,7 @@ use sway_core::{ compile_ir_context_to_finalized_asm, compile_to_ast, ir_generation::compile_program, namespace::{self, Package}, - BuildTarget, Engines, + BuildConfig, BuildTarget, Engines, OptLevel, }; use sway_error::handler::Handler; @@ -425,7 +425,11 @@ pub(super) async fn run( // Compile to ASM. let handler = Handler::default(); - let asm_result = compile_ir_context_to_finalized_asm(&handler, &ir, None); + let asm_result = compile_ir_context_to_finalized_asm( + &handler, + &ir, + Some(&BuildConfig::dummy_for_asm_generation().with_optimization_level(OptLevel::Opt1)) + ); let (errors, _warnings) = handler.consume(); if asm_result.is_err() || !errors.is_empty() { diff --git a/test/src/ir_generation/tests/asm_block.sw b/test/src/ir_generation/tests/asm_block.sw index 0e4302e096..1c9658963b 100644 --- a/test/src/ir_generation/tests/asm_block.sw +++ b/test/src/ir_generation/tests/asm_block.sw @@ -39,6 +39,5 @@ fn main() -> u64 { // check: ret $ret_val // The get_global_gas() function: -// check: move $(ggas_val=$REG) $$ggas -// check: move $$$$retv $ggas_val +// check: move $$$$retv $$ggas // check: jmp $$$$reta diff --git a/test/src/ir_generation/tests/fn_call.sw b/test/src/ir_generation/tests/fn_call.sw index 3e92c56563..698207b4b9 100644 --- a/test/src/ir_generation/tests/fn_call.sw +++ b/test/src/ir_generation/tests/fn_call.sw @@ -42,8 +42,7 @@ fn main() -> u64 { // // Matching fn a() here, which just returns its arg: // -// check: move $(ret_val=$REG) $$$$arg0 -// check: move $$$$retv $ret_val +// check: move $$$$retv $$$$arg0 // check: jmp $$$$reta // // Matching fn b() here, which has a local bool var, initialised to false/$zero: @@ -51,9 +50,6 @@ fn main() -> u64 { // check: move $$$$locbase $$sp // check: cfei i8 // -// check: move $REG $$$$arg0 -// check: move $REG $$$$arg1 -// // check: sb $$$$locbase $$zero i0 // ... // check: cfsi i8 diff --git a/test/src/ir_generation/tests/fn_call_noargs_nolocals.sw b/test/src/ir_generation/tests/fn_call_noargs_nolocals.sw index b26e9a1c7d..49591342ff 100644 --- a/test/src/ir_generation/tests/fn_call_noargs_nolocals.sw +++ b/test/src/ir_generation/tests/fn_call_noargs_nolocals.sw @@ -42,7 +42,5 @@ fn main() { // Function returns unit. // -// check: move $REG $$$$reta // check: move $$$$retv $$zero -// check: move $$$$reta $REG // check: jmp $$$$reta diff --git a/test/src/ir_generation/tests/fn_call_nolocals.sw b/test/src/ir_generation/tests/fn_call_nolocals.sw index 3f8b701c07..fbdb9c1f13 100644 --- a/test/src/ir_generation/tests/fn_call_nolocals.sw +++ b/test/src/ir_generation/tests/fn_call_nolocals.sw @@ -37,5 +37,4 @@ fn main() -> u64 { // check: srli $$$$reta $$$$reta i2 // check: addi $$$$reta $$$$reta i4 // check: jmpf $$zero $IMM -// check: move $(ret_val=$REG) $$$$retv -// check: ret $ret_val +// check: ret $$$$retv diff --git a/test/src/ir_generation/tests/predicate_data_mult_args.sw b/test/src/ir_generation/tests/predicate_data_mult_args.sw index 49e9efd855..1bf5ee02d7 100644 --- a/test/src/ir_generation/tests/predicate_data_mult_args.sw +++ b/test/src/ir_generation/tests/predicate_data_mult_args.sw @@ -15,12 +15,10 @@ fn main(x: u64, y: u64) -> bool { // check: gm $(r2=$REG) i3 // check: gtf $(r1=$REG) $r2 i512 // nextln: jnzf $r1 $$zero $IMM -// nextln: gtf $(r3=$REG) $r2 i524 // nextln: jmpf $$zero $IMM // nextln: movi $(r0=$REG) i2 // nextln: eq $r1 $r1 $r0 // nextln: xori $r1 $r1 i1 // nextln: jnzf $r1 $$zero $IMM -// nextln: gtf $r3 $r2 i586 // nextln: jmpf $$zero $IMM // nextln: ret $$zero diff --git a/test/src/ir_generation/tests/predicate_data_single_arg.sw b/test/src/ir_generation/tests/predicate_data_single_arg.sw index 97ab7d0cc7..4842c480f3 100644 --- a/test/src/ir_generation/tests/predicate_data_single_arg.sw +++ b/test/src/ir_generation/tests/predicate_data_single_arg.sw @@ -15,13 +15,11 @@ fn main(x: u64) -> bool { // check: gm $(r2=$REG) i3 // check: gtf $(r1=$REG) $r2 i512 // nextln: jnzf $r1 $$zero $IMM -// nextln: gtf $(r3=$REG) $r2 i524 // nextln: jmpf $$zero $IMM // nextln: movi $(r0=$REG) i2 // nextln: eq $r1 $r1 $r0 // nextln: xori $r1 $r1 i1 // nextln: jnzf $r1 $$zero $IMM -// nextln: gtf $r3 $r2 i586 // nextln: jmpf $$zero $IMM // nextln: ret $$zero diff --git a/test/src/sdk-harness/test_projects/auth/mod.rs b/test/src/sdk-harness/test_projects/auth/mod.rs index 8c8a691214..a75c3837a5 100644 --- a/test/src/sdk-harness/test_projects/auth/mod.rs +++ b/test/src/sdk-harness/test_projects/auth/mod.rs @@ -614,7 +614,7 @@ async fn can_get_predicate_address() { // Setup predicate. let hex_predicate_address: &str = - "0xffc519a06f9f53d3f6dee5eb932a1e83a6d39535e0bb1da89d53225860cf9303"; + "0xf70528e17820e36c0868d25aac804f3e0750f90f0840d9e1d68a7e4e3c9290a8"; let predicate_address = Address::from_str(hex_predicate_address).expect("failed to create Address from string"); let predicate_bech32_address = Bech32Address::from(predicate_address); @@ -629,7 +629,7 @@ async fn can_get_predicate_address() { // If this test fails, it can be that the predicate address got changed. // Uncomment the next line, get the predicate address, and update it above. - // dbg!(&predicate); + dbg!(&predicate); // Next, we lock some assets in this predicate using the first wallet: // First wallet transfers amount to predicate. @@ -695,7 +695,7 @@ async fn when_incorrect_predicate_address_passed() { // Setup predicate with incorrect address. let hex_predicate_address: &str = - "0xffc519a06f9f53d3f6dee5eb932a1e83a6d39535e0bb1da89d53225860cf9303"; + "0xf70528e17820e36c0868d25aac804f3e0750f90f0840d9e1d68a7e4e3c9290a8"; let predicate_address = Address::from_str(hex_predicate_address).expect("failed to create Address from string"); let predicate_data = AuthPredicateEncoder::default() @@ -740,7 +740,7 @@ async fn when_incorrect_predicate_address_passed() { async fn can_get_predicate_address_in_message() { // Setup predicate address. let hex_predicate_address: &str = - "0xffc519a06f9f53d3f6dee5eb932a1e83a6d39535e0bb1da89d53225860cf9303"; + "0xf70528e17820e36c0868d25aac804f3e0750f90f0840d9e1d68a7e4e3c9290a8"; let predicate_address = Address::from_str(hex_predicate_address).expect("failed to create Address from string"); let predicate_bech32_address = Bech32Address::from(predicate_address);