Skip to content

Commit c110935

Browse files
authored
Add CompareResult extension trait for Instruction (#1537)
* add CompareResult extension trait * re-use CompareResult ext trait logic * remove no longer used rustfmt::skip attribute
1 parent e1cf22b commit c110935

File tree

2 files changed

+91
-39
lines changed

2 files changed

+91
-39
lines changed

crates/wasmi/src/engine/translator/comparator.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,94 @@ pub trait AllocConst {
2222
fn alloc_const<T: Into<UntypedVal>>(&mut self, value: T) -> Result<Reg, Error>;
2323
}
2424

25+
/// Extension trait to return [`Reg`] result of compare [`Instruction`]s.
26+
pub trait CompareResult {
27+
/// Returns the result [`Reg`] of the compare [`Instruction`].
28+
///
29+
/// Returns `None` if the [`Instruction`] is not a compare instruction.
30+
fn compare_result(&self) -> Option<Reg>;
31+
}
32+
33+
impl CompareResult for Instruction {
34+
fn compare_result(&self) -> Option<Reg> {
35+
use crate::ir::Instruction as I;
36+
let result = match *self {
37+
| I::I32BitAnd { result, .. }
38+
| I::I32BitAndImm16 { result, .. }
39+
| I::I32BitOr { result, .. }
40+
| I::I32BitOrImm16 { result, .. }
41+
| I::I32BitXor { result, .. }
42+
| I::I32BitXorImm16 { result, .. }
43+
| I::I32And { result, .. }
44+
| I::I32AndImm16 { result, .. }
45+
| I::I32Or { result, .. }
46+
| I::I32OrImm16 { result, .. }
47+
| I::I32Xor { result, .. }
48+
| I::I32XorImm16 { result, .. }
49+
| I::I32Nand { result, .. }
50+
| I::I32NandImm16 { result, .. }
51+
| I::I32Nor { result, .. }
52+
| I::I32NorImm16 { result, .. }
53+
| I::I32Xnor { result, .. }
54+
| I::I32XnorImm16 { result, .. }
55+
| I::I32Eq { result, .. }
56+
| I::I32EqImm16 { result, .. }
57+
| I::I32Ne { result, .. }
58+
| I::I32NeImm16 { result, .. }
59+
| I::I32LtS { result, .. }
60+
| I::I32LtSImm16Lhs { result, .. }
61+
| I::I32LtSImm16Rhs { result, .. }
62+
| I::I32LtU { result, .. }
63+
| I::I32LtUImm16Lhs { result, .. }
64+
| I::I32LtUImm16Rhs { result, .. }
65+
| I::I32LeS { result, .. }
66+
| I::I32LeSImm16Lhs { result, .. }
67+
| I::I32LeSImm16Rhs { result, .. }
68+
| I::I32LeU { result, .. }
69+
| I::I32LeUImm16Lhs { result, .. }
70+
| I::I32LeUImm16Rhs { result, .. }
71+
| I::I64And { result, .. }
72+
| I::I64AndImm16 { result, .. }
73+
| I::I64Or { result, .. }
74+
| I::I64OrImm16 { result, .. }
75+
| I::I64Xor { result, .. }
76+
| I::I64XorImm16 { result, .. }
77+
| I::I64Nand { result, .. }
78+
| I::I64NandImm16 { result, .. }
79+
| I::I64Nor { result, .. }
80+
| I::I64NorImm16 { result, .. }
81+
| I::I64Xnor { result, .. }
82+
| I::I64XnorImm16 { result, .. }
83+
| I::I64Eq { result, .. }
84+
| I::I64EqImm16 { result, .. }
85+
| I::I64Ne { result, .. }
86+
| I::I64NeImm16 { result, .. }
87+
| I::I64LtS { result, .. }
88+
| I::I64LtSImm16Lhs { result, .. }
89+
| I::I64LtSImm16Rhs { result, .. }
90+
| I::I64LtU { result, .. }
91+
| I::I64LtUImm16Lhs { result, .. }
92+
| I::I64LtUImm16Rhs { result, .. }
93+
| I::I64LeS { result, .. }
94+
| I::I64LeSImm16Lhs { result, .. }
95+
| I::I64LeSImm16Rhs { result, .. }
96+
| I::I64LeU { result, .. }
97+
| I::I64LeUImm16Lhs { result, .. }
98+
| I::I64LeUImm16Rhs { result, .. }
99+
| I::F32Eq { result, .. }
100+
| I::F32Ne { result, .. }
101+
| I::F32Lt { result, .. }
102+
| I::F32Le { result, .. }
103+
| I::F64Eq { result, .. }
104+
| I::F64Ne { result, .. }
105+
| I::F64Lt { result, .. }
106+
| I::F64Le { result, .. } => result,
107+
_ => return None,
108+
};
109+
Some(result)
110+
}
111+
}
112+
25113
pub trait NegateCmpInstr: Sized {
26114
/// Negates the compare (`cmp`) [`Instruction`].
27115
fn negate_cmp_instr(&self) -> Option<Self>;

crates/wasmi/src/engine/translator/func/instr_encoder.rs

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::{
22
core::{FuelCostsProvider, UntypedVal, ValType},
33
engine::translator::{
44
comparator::{
5+
CompareResult,
56
LogicalizeCmpInstr,
67
NegateCmpInstr,
78
TryIntoCmpBranchFallbackInstr,
@@ -1051,7 +1052,6 @@ impl InstrEncoder {
10511052
/// Try to fuse [`Instruction`] at `instr` into a branch+cmp instruction.
10521053
///
10531054
/// Returns `Ok(Some)` if successful.
1054-
#[rustfmt::skip]
10551055
fn try_fuse_branch_cmp_for_instr(
10561056
&mut self,
10571057
stack: &mut ValueStack,
@@ -1060,45 +1060,9 @@ impl InstrEncoder {
10601060
label: LabelRef,
10611061
negate: bool,
10621062
) -> Result<Option<Instruction>, Error> {
1063-
use Instruction as I;
10641063
let last_instruction = *self.instrs.get(last_instr);
1065-
let result = match last_instruction {
1066-
| I::I32BitAnd { result, .. } | I::I32BitAndImm16 { result, .. }
1067-
| I::I32BitOr { result, .. } | I::I32BitOrImm16 { result, .. }
1068-
| I::I32BitXor { result, .. } | I::I32BitXorImm16 { result, .. }
1069-
| I::I32And { result, .. } | I::I32AndImm16 { result, .. }
1070-
| I::I32Or { result, .. } | I::I32OrImm16 { result, .. }
1071-
| I::I32Xor { result, .. } | I::I32XorImm16 { result, .. }
1072-
| I::I32Nand { result, .. } | I::I32NandImm16 { result, .. }
1073-
| I::I32Nor { result, .. } | I::I32NorImm16 { result, .. }
1074-
| I::I32Xnor { result, .. } | I::I32XnorImm16 { result, .. }
1075-
| I::I32Eq { result, .. } | I::I32EqImm16 { result, .. }
1076-
| I::I32Ne { result, .. } | I::I32NeImm16 { result, .. }
1077-
| I::I32LtS { result, .. } | I::I32LtSImm16Lhs { result, .. } | I::I32LtSImm16Rhs { result, .. }
1078-
| I::I32LtU { result, .. } | I::I32LtUImm16Lhs { result, .. } | I::I32LtUImm16Rhs { result, .. }
1079-
| I::I32LeS { result, .. } | I::I32LeSImm16Lhs { result, .. } | I::I32LeSImm16Rhs { result, .. }
1080-
| I::I32LeU { result, .. } | I::I32LeUImm16Lhs { result, .. } | I::I32LeUImm16Rhs { result, .. }
1081-
| I::I64And { result, .. } | I::I64AndImm16 { result, .. }
1082-
| I::I64Or { result, .. } | I::I64OrImm16 { result, .. }
1083-
| I::I64Xor { result, .. } | I::I64XorImm16 { result, .. }
1084-
| I::I64Nand { result, .. } | I::I64NandImm16 { result, .. }
1085-
| I::I64Nor { result, .. } | I::I64NorImm16 { result, .. }
1086-
| I::I64Xnor { result, .. } | I::I64XnorImm16 { result, .. }
1087-
| I::I64Eq { result, .. } | I::I64EqImm16 { result, .. }
1088-
| I::I64Ne { result, .. } | I::I64NeImm16 { result, .. }
1089-
| I::I64LtS { result, .. } | I::I64LtSImm16Lhs { result, .. } | I::I64LtSImm16Rhs { result, .. }
1090-
| I::I64LtU { result, .. } | I::I64LtUImm16Lhs { result, .. } | I::I64LtUImm16Rhs { result, .. }
1091-
| I::I64LeS { result, .. } | I::I64LeSImm16Lhs { result, .. } | I::I64LeSImm16Rhs { result, .. }
1092-
| I::I64LeU { result, .. } | I::I64LeUImm16Lhs { result, .. } | I::I64LeUImm16Rhs { result, .. }
1093-
| I::F32Eq { result, .. }
1094-
| I::F32Ne { result, .. }
1095-
| I::F32Lt { result, .. }
1096-
| I::F32Le { result, .. }
1097-
| I::F64Eq { result, .. }
1098-
| I::F64Ne { result, .. }
1099-
| I::F64Lt { result, .. }
1100-
| I::F64Le { result, .. } => result,
1101-
_ => return Ok(None),
1064+
let Some(result) = last_instruction.compare_result() else {
1065+
return Ok(None);
11021066
};
11031067
if matches!(stack.get_register_space(result), RegisterSpace::Local) {
11041068
// We need to filter out instructions that store their result

0 commit comments

Comments
 (0)