Skip to content

Commit d737d7f

Browse files
authored
Optimize call_indirect operators for (table 0) (#2019)
* add Table0 type to wasmi_ir * add FieldTy::is_unit helper * add FieldTy::Table0 * add specialized call_indirect variants for table 0 * adjust expected generated file sizes * add table0 to InstanceEntityHeader * add LoadEntity trait and impls * make executor use new trait and impls for tables * remove unused load_table helper * add execution helpers for new table 0 variants * add support for new table0 variants in the translator * move return exec handler in front of call_{imported,indirect} * remove unused handle of table0 cache * remove old load utils from executor * fix broken doc link
1 parent 919d0e4 commit d737d7f

22 files changed

Lines changed: 284 additions & 92 deletions

File tree

crates/ir/build/display/constructors.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use crate::build::{
2121
UnaryOp,
2222
V128ExtractLaneOp,
2323
},
24-
ty::FieldTy,
2524
};
2625
use core::fmt::{self, Display};
2726

@@ -56,17 +55,15 @@ impl<'a, T> DisplayConstructor<&'a T> {
5655
fields
5756
.iter()
5857
.filter_map(Option::as_ref)
59-
.filter(|field| !field.ty.is_reg() && !matches!(field.ty, FieldTy::Local(_))),
58+
.filter(|field| !field.ty.is_reg() && !field.ty.is_unit()),
6059
);
6160
let struct_params = DisplaySequence::new(
6261
", ",
6362
fields
6463
.iter()
6564
.filter_map(Option::as_ref)
6665
.map(|param| match param.ty {
67-
FieldTy::RegInt | FieldTy::RegF32 | FieldTy::RegF64 | FieldTy::Local(_) => {
68-
DisplayConstructorInit::Default(*param)
69-
}
66+
ty if ty.is_unit() => DisplayConstructorInit::Default(*param),
7067
_ => DisplayConstructorInit::Param(param.ident),
7168
}),
7269
);

crates/ir/build/display/decode.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,11 @@ impl Display for DisplayDecode<&'_ CallIndirectOp> {
260260
let op = self.value;
261261
let camel_ident = DisplayIdent::camel(op);
262262
let index_ty = op.index_field().ty;
263-
writeln!(f, "pub type {camel_ident} = CallIndirect<{index_ty}>;")
263+
let table = FieldTy::from(op.table);
264+
writeln!(
265+
f,
266+
"pub type {camel_ident} = CallIndirect<{table}, {index_ty}>;"
267+
)
264268
}
265269
}
266270

crates/ir/build/display/ident.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::build::{
1919
SelectOp,
2020
StoreOp,
2121
TableGetOp,
22+
TableOperand,
2223
TableSetOp,
2324
TernaryOp,
2425
UnaryOp,
@@ -525,8 +526,13 @@ impl Display for DisplayIdent<&'_ CallIndirectOp> {
525526
CallKind::Tail => Some(DisplayConcat((return_ident, sep))),
526527
}
527528
.display_maybe();
529+
let table_suffix = match op.table {
530+
TableOperand::Table0 => Some(DisplayConcat((sep, case.wrap(Ident::Table0)))),
531+
TableOperand::Table => None,
532+
}
533+
.display_maybe();
528534
let index_suffix = case.wrap(Suffix(op.index));
529-
write!(f, "{prefix}{ident}_{index_suffix}")
535+
write!(f, "{prefix}{ident}{table_suffix}_{index_suffix}")
530536
}
531537
}
532538

crates/ir/build/ident.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ define_ident!(
140140
Reinterpret: reinterpret,
141141

142142
Table: table,
143+
Table0: table0,
143144
Memory: memory,
144145
Func: func,
145146
FuncType: func_type,

crates/ir/build/isa.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use crate::build::{
2424
StoreKind,
2525
StoreOp,
2626
TableGetOp,
27+
TableOperand,
2728
TableSetOp,
2829
TernaryOp,
2930
TernaryOpKind,
@@ -623,10 +624,6 @@ fn add_call_ops(isa: &mut Isa) {
623624
Field::new(Ident::Func, FieldTy::FuncAddr),
624625
],
625626
)),
626-
Op::from(CallIndirectOp::new(CallKind::Nested, OperandKind::Reg)),
627-
Op::from(CallIndirectOp::new(CallKind::Nested, OperandKind::Slot)),
628-
Op::from(CallIndirectOp::new(CallKind::Tail, OperandKind::Reg)),
629-
Op::from(CallIndirectOp::new(CallKind::Tail, OperandKind::Slot)),
630627
Op::from(GenericOp::new(
631628
Ident::ReturnCallInternal,
632629
[
@@ -643,6 +640,14 @@ fn add_call_ops(isa: &mut Isa) {
643640
)),
644641
];
645642
isa.push_ops(ops);
643+
// call_indirect ops
644+
for call_kind in [CallKind::Nested, CallKind::Tail] {
645+
for index in [OperandKind::Reg, OperandKind::Slot] {
646+
for table in [TableOperand::Table0, TableOperand::Table] {
647+
isa.push_op(CallIndirectOp::new(call_kind, index, table));
648+
}
649+
}
650+
}
646651
}
647652

648653
fn add_global_ops(isa: &mut Isa) {

crates/ir/build/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub fn generate_code(config: &Config) -> Result<(), Error> {
7878
fn generate_op_rs(config: &Config, isa: &Isa, contents: &mut String) -> Result<(), Error> {
7979
let expected_size = match config.simd {
8080
true => 505_000,
81-
false => 385_000,
81+
false => 390_000,
8282
};
8383
write_to_buffer(contents, expected_size, |buffer| {
8484
write!(

crates/ir/build/op.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -863,19 +863,38 @@ pub enum CallKind {
863863
pub struct CallIndirectOp {
864864
pub kind: CallKind,
865865
pub index: OperandKind,
866+
pub table: TableOperand,
867+
}
868+
869+
/// The table operand kind.
870+
#[derive(Copy, Clone)]
871+
pub enum TableOperand {
872+
/// Always uses `(table 0)`.
873+
Table0,
874+
/// Encodes a 32-bit table address.
875+
Table,
876+
}
877+
878+
impl From<TableOperand> for FieldTy {
879+
fn from(value: TableOperand) -> Self {
880+
match value {
881+
TableOperand::Table0 => FieldTy::Table0,
882+
TableOperand::Table => FieldTy::TableAddr,
883+
}
884+
}
866885
}
867886

868887
impl CallIndirectOp {
869-
pub fn new(kind: CallKind, index: OperandKind) -> Self {
870-
Self { kind, index }
888+
pub fn new(kind: CallKind, index: OperandKind, table: TableOperand) -> Self {
889+
Self { kind, index, table }
871890
}
872891

873892
pub fn func_type_field(&self) -> Field {
874893
Field::new(Ident::FuncType, FieldTy::FuncType)
875894
}
876895

877896
pub fn table_field(&self) -> Field {
878-
Field::new(Ident::Table, FieldTy::TableAddr)
897+
Field::new(Ident::Table, self.table.into())
879898
}
880899

881900
pub fn params_field(&self) -> Field {

crates/ir/build/ty.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ pub enum FieldTy {
196196
Offset,
197197
Offset16,
198198
BranchOffset,
199+
Table0,
199200
MemoryAddr,
200201
TableAddr,
201202
GlobalAddr,
@@ -222,6 +223,15 @@ impl FieldTy {
222223
pub fn is_reg(&self) -> bool {
223224
matches!(self, Self::RegInt | Self::RegF32 | Self::RegF64)
224225
}
226+
227+
/// Returns `true` if the field type is like a unit type and
228+
/// doesn't need to provide a value for construction.
229+
pub fn is_unit(&self) -> bool {
230+
matches!(
231+
self,
232+
Self::Local(_) | Self::Table0 | Self::RegInt | Self::RegF32 | Self::RegF64
233+
)
234+
}
225235
}
226236

227237
impl From<Ty> for FieldTy {
@@ -297,6 +307,7 @@ impl Display for FieldTy {
297307
Self::Offset => "Offset",
298308
Self::Offset16 => "Offset16",
299309
Self::BranchOffset => "BranchOffset",
310+
Self::Table0 => "Table0",
300311
Self::MemoryAddr => "MemoryAddr",
301312
Self::TableAddr => "TableAddr",
302313
Self::GlobalAddr => "GlobalAddr",

crates/ir/src/decode/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ use crate::{
4747
Slot,
4848
SlotAndReg,
4949
SlotSpan,
50+
Table0,
5051
core::{ShiftAmount, TrapCode},
5152
index::{
5253
DataAddr,
@@ -266,6 +267,13 @@ impl<const N: u16> Decode for Local<N> {
266267
}
267268
}
268269

270+
impl Decode for Table0 {
271+
#[inline]
272+
fn decode<D: Decoder>(_decoder: &mut D) -> Result<Self, DecodeError> {
273+
Ok(Self::default())
274+
}
275+
}
276+
269277
impl<T> Decode for SlotAndReg<T> {
270278
#[inline]
271279
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {

crates/ir/src/decode/op.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,14 +376,14 @@ impl<I: Decode, V: Decode> Decode for TableSet<I, V> {
376376
}
377377

378378
#[derive(Copy, Clone)]
379-
pub struct CallIndirect<I> {
380-
pub table: TableAddr,
379+
pub struct CallIndirect<Table, Idx> {
380+
pub table: Table,
381381
pub func_type: FuncType,
382382
pub params: BoundedSlotSpan,
383-
pub index: I,
383+
pub index: Idx,
384384
}
385385

386-
impl<I: Decode> Decode for CallIndirect<I> {
386+
impl<Table: Decode, Idx: Decode> Decode for CallIndirect<Table, Idx> {
387387
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
388388
Ok(Self {
389389
table: Decode::decode(decoder)?,

0 commit comments

Comments
 (0)