Skip to content

Commit 1736823

Browse files
authored
ZJIT: Implement codegen for FixnumMod (ruby#14857)
This is mostly to see what happens to the loops-times benchmark.
1 parent 6e9f797 commit 1736823

File tree

10 files changed

+25
-10
lines changed

10 files changed

+25
-10
lines changed

depend

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7382,8 +7382,10 @@ jit.$(OBJEXT): $(CCAN_DIR)/str/str.h
73827382
jit.$(OBJEXT): $(hdrdir)/ruby/ruby.h
73837383
jit.$(OBJEXT): $(top_srcdir)/internal/array.h
73847384
jit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
7385+
jit.$(OBJEXT): $(top_srcdir)/internal/bits.h
73857386
jit.$(OBJEXT): $(top_srcdir)/internal/class.h
73867387
jit.$(OBJEXT): $(top_srcdir)/internal/compilers.h
7388+
jit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
73877389
jit.$(OBJEXT): $(top_srcdir)/internal/gc.h
73887390
jit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
73897391
jit.$(OBJEXT): $(top_srcdir)/internal/namespace.h

jit.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "iseq.h"
1515
#include "internal/gc.h"
1616
#include "vm_sync.h"
17+
#include "internal/fixnum.h"
1718

1819
// Field offsets for the RObject struct
1920
enum robject_offsets {
@@ -720,3 +721,9 @@ rb_jit_icache_invalidate(void *start, void *end)
720721
#error No instruction cache clear available with this compiler on Aarch64!
721722
#endif
722723
}
724+
725+
VALUE
726+
rb_jit_fix_mod_fix(VALUE recv, VALUE obj)
727+
{
728+
return rb_fix_mod_fix(recv, obj);
729+
}

yjit.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -332,12 +332,6 @@ rb_yjit_fix_div_fix(VALUE recv, VALUE obj)
332332
return rb_fix_div_fix(recv, obj);
333333
}
334334

335-
VALUE
336-
rb_yjit_fix_mod_fix(VALUE recv, VALUE obj)
337-
{
338-
return rb_fix_mod_fix(recv, obj);
339-
}
340-
341335
// Return non-zero when `obj` is an array and its last item is a
342336
// `ruby2_keywords` hash. We don't support this kind of splat.
343337
size_t

yjit/bindgen/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ fn main() {
367367
.allowlist_function("rb_yarv_ary_entry_internal")
368368
.allowlist_function("rb_yjit_ruby2_keywords_splat_p")
369369
.allowlist_function("rb_yjit_fix_div_fix")
370-
.allowlist_function("rb_yjit_fix_mod_fix")
370+
.allowlist_function("rb_jit_fix_mod_fix")
371371
.allowlist_function("rb_FL_TEST")
372372
.allowlist_function("rb_FL_TEST_RAW")
373373
.allowlist_function("rb_RB_TYPE_P")

yjit/src/cruby.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ pub use rb_get_call_data_ci as get_call_data_ci;
199199
pub use rb_yarv_str_eql_internal as rb_str_eql_internal;
200200
pub use rb_yarv_ary_entry_internal as rb_ary_entry_internal;
201201
pub use rb_yjit_fix_div_fix as rb_fix_div_fix;
202-
pub use rb_yjit_fix_mod_fix as rb_fix_mod_fix;
202+
pub use rb_jit_fix_mod_fix as rb_fix_mod_fix;
203203
pub use rb_FL_TEST as FL_TEST;
204204
pub use rb_FL_TEST_RAW as FL_TEST_RAW;
205205
pub use rb_RB_TYPE_P as RB_TYPE_P;

yjit/src/cruby_bindings.inc.rs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

zjit/src/codegen.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
398398
Insn::FixnumGe { left, right } => gen_fixnum_ge(asm, opnd!(left), opnd!(right)),
399399
Insn::FixnumAnd { left, right } => gen_fixnum_and(asm, opnd!(left), opnd!(right)),
400400
Insn::FixnumOr { left, right } => gen_fixnum_or(asm, opnd!(left), opnd!(right)),
401+
&Insn::FixnumMod { left, right, state } => gen_fixnum_mod(jit, asm, opnd!(left), opnd!(right), &function.frame_state(state)),
401402
Insn::IsNil { val } => gen_isnil(asm, opnd!(val)),
402403
&Insn::IsMethodCfunc { val, cd, cfunc, state: _ } => gen_is_method_cfunc(jit, asm, opnd!(val), cd, cfunc),
403404
&Insn::IsBitEqual { left, right } => gen_is_bit_equal(asm, opnd!(left), opnd!(right)),
@@ -447,7 +448,6 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
447448
&Insn::LoadIvarExtended { self_val, id, index } => gen_load_ivar_extended(asm, opnd!(self_val), id, index),
448449
&Insn::ArrayMax { state, .. }
449450
| &Insn::FixnumDiv { state, .. }
450-
| &Insn::FixnumMod { state, .. }
451451
| &Insn::Throw { state, .. }
452452
=> return Err(state),
453453
};
@@ -1460,6 +1460,13 @@ fn gen_fixnum_or(asm: &mut Assembler, left: lir::Opnd, right: lir::Opnd) -> lir:
14601460
asm.or(left, right)
14611461
}
14621462

1463+
fn gen_fixnum_mod(jit: &mut JITState, asm: &mut Assembler, left: lir::Opnd, right: lir::Opnd, state: &FrameState) -> lir::Opnd {
1464+
// Check for left % 0, which raises ZeroDivisionError
1465+
asm.cmp(right, Opnd::from(VALUE::fixnum_from_usize(0)));
1466+
asm.je(side_exit(jit, state, FixnumModByZero));
1467+
asm_ccall!(asm, rb_fix_mod_fix, left, right)
1468+
}
1469+
14631470
// Compile val == nil
14641471
fn gen_isnil(asm: &mut Assembler, val: lir::Opnd) -> lir::Opnd {
14651472
asm.cmp(val, Qnil.into());

zjit/src/cruby.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ unsafe extern "C" {
134134
pub fn rb_str_setbyte(str: VALUE, index: VALUE, value: VALUE) -> VALUE;
135135
pub fn rb_str_getbyte(str: VALUE, index: VALUE) -> VALUE;
136136
pub fn rb_vm_splat_array(flag: VALUE, ary: VALUE) -> VALUE;
137+
pub fn rb_jit_fix_mod_fix(x: VALUE, y: VALUE) -> VALUE;
137138
pub fn rb_vm_concat_array(ary1: VALUE, ary2st: VALUE) -> VALUE;
138139
pub fn rb_vm_get_special_object(reg_ep: *const VALUE, value_type: vm_special_object_type) -> VALUE;
139140
pub fn rb_vm_concat_to_array(ary1: VALUE, ary2st: VALUE) -> VALUE;
@@ -219,6 +220,7 @@ pub use rb_vm_ci_kwarg as vm_ci_kwarg;
219220
pub use rb_METHOD_ENTRY_VISI as METHOD_ENTRY_VISI;
220221
pub use rb_RCLASS_ORIGIN as RCLASS_ORIGIN;
221222
pub use rb_vm_get_special_object as vm_get_special_object;
223+
pub use rb_jit_fix_mod_fix as rb_fix_mod_fix;
222224

223225
/// Helper so we can get a Rust string for insn_name()
224226
pub fn insn_name(opcode: usize) -> String {

zjit/src/hir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ pub enum SideExitReason {
468468
BlockParamProxyModified,
469469
BlockParamProxyNotIseqOrIfunc,
470470
StackOverflow,
471+
FixnumModByZero,
471472
}
472473

473474
#[derive(Debug, Clone, Copy)]

zjit/src/stats.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ make_counters! {
137137
exit_fixnum_add_overflow,
138138
exit_fixnum_sub_overflow,
139139
exit_fixnum_mult_overflow,
140+
exit_fixnum_mod_by_zero,
140141
exit_guard_type_failure,
141142
exit_guard_type_not_failure,
142143
exit_guard_bit_equals_failure,
@@ -332,6 +333,7 @@ pub fn side_exit_counter(reason: crate::hir::SideExitReason) -> Counter {
332333
FixnumAddOverflow => exit_fixnum_add_overflow,
333334
FixnumSubOverflow => exit_fixnum_sub_overflow,
334335
FixnumMultOverflow => exit_fixnum_mult_overflow,
336+
FixnumModByZero => exit_fixnum_mod_by_zero,
335337
GuardType(_) => exit_guard_type_failure,
336338
GuardTypeNot(_) => exit_guard_type_not_failure,
337339
GuardBitEquals(_) => exit_guard_bit_equals_failure,

0 commit comments

Comments
 (0)