mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 20:19:19 +00:00
ZJIT: Implement codegen for FixnumMod (#14857)
This is mostly to see what happens to the loops-times benchmark.
This commit is contained in:
parent
6e9f7974df
commit
17368234bf
Notes:
git
2025-10-20 21:31:27 +00:00
Merged-By: tekknolagi <donotemailthisaddress@bernsteinbear.com>
2
depend
2
depend
@ -7382,8 +7382,10 @@ jit.$(OBJEXT): $(CCAN_DIR)/str/str.h
|
||||
jit.$(OBJEXT): $(hdrdir)/ruby/ruby.h
|
||||
jit.$(OBJEXT): $(top_srcdir)/internal/array.h
|
||||
jit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
|
||||
jit.$(OBJEXT): $(top_srcdir)/internal/bits.h
|
||||
jit.$(OBJEXT): $(top_srcdir)/internal/class.h
|
||||
jit.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||
jit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
||||
jit.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||
jit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||
jit.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||
|
||||
7
jit.c
7
jit.c
@ -14,6 +14,7 @@
|
||||
#include "iseq.h"
|
||||
#include "internal/gc.h"
|
||||
#include "vm_sync.h"
|
||||
#include "internal/fixnum.h"
|
||||
|
||||
// Field offsets for the RObject struct
|
||||
enum robject_offsets {
|
||||
@ -720,3 +721,9 @@ rb_jit_icache_invalidate(void *start, void *end)
|
||||
#error No instruction cache clear available with this compiler on Aarch64!
|
||||
#endif
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_jit_fix_mod_fix(VALUE recv, VALUE obj)
|
||||
{
|
||||
return rb_fix_mod_fix(recv, obj);
|
||||
}
|
||||
|
||||
6
yjit.c
6
yjit.c
@ -332,12 +332,6 @@ rb_yjit_fix_div_fix(VALUE recv, VALUE obj)
|
||||
return rb_fix_div_fix(recv, obj);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_yjit_fix_mod_fix(VALUE recv, VALUE obj)
|
||||
{
|
||||
return rb_fix_mod_fix(recv, obj);
|
||||
}
|
||||
|
||||
// Return non-zero when `obj` is an array and its last item is a
|
||||
// `ruby2_keywords` hash. We don't support this kind of splat.
|
||||
size_t
|
||||
|
||||
@ -367,7 +367,7 @@ fn main() {
|
||||
.allowlist_function("rb_yarv_ary_entry_internal")
|
||||
.allowlist_function("rb_yjit_ruby2_keywords_splat_p")
|
||||
.allowlist_function("rb_yjit_fix_div_fix")
|
||||
.allowlist_function("rb_yjit_fix_mod_fix")
|
||||
.allowlist_function("rb_jit_fix_mod_fix")
|
||||
.allowlist_function("rb_FL_TEST")
|
||||
.allowlist_function("rb_FL_TEST_RAW")
|
||||
.allowlist_function("rb_RB_TYPE_P")
|
||||
|
||||
@ -199,7 +199,7 @@ pub use rb_get_call_data_ci as get_call_data_ci;
|
||||
pub use rb_yarv_str_eql_internal as rb_str_eql_internal;
|
||||
pub use rb_yarv_ary_entry_internal as rb_ary_entry_internal;
|
||||
pub use rb_yjit_fix_div_fix as rb_fix_div_fix;
|
||||
pub use rb_yjit_fix_mod_fix as rb_fix_mod_fix;
|
||||
pub use rb_jit_fix_mod_fix as rb_fix_mod_fix;
|
||||
pub use rb_FL_TEST as FL_TEST;
|
||||
pub use rb_FL_TEST_RAW as FL_TEST_RAW;
|
||||
pub use rb_RB_TYPE_P as RB_TYPE_P;
|
||||
|
||||
@ -1142,7 +1142,6 @@ extern "C" {
|
||||
pub fn rb_ary_unshift_m(argc: ::std::os::raw::c_int, argv: *mut VALUE, ary: VALUE) -> VALUE;
|
||||
pub fn rb_yjit_rb_ary_subseq_length(ary: VALUE, beg: ::std::os::raw::c_long) -> VALUE;
|
||||
pub fn rb_yjit_fix_div_fix(recv: VALUE, obj: VALUE) -> VALUE;
|
||||
pub fn rb_yjit_fix_mod_fix(recv: VALUE, obj: VALUE) -> VALUE;
|
||||
pub fn rb_yjit_ruby2_keywords_splat_p(obj: VALUE) -> usize;
|
||||
pub fn rb_yjit_splat_varg_checks(
|
||||
sp: *mut VALUE,
|
||||
@ -1275,4 +1274,5 @@ extern "C" {
|
||||
start: *mut ::std::os::raw::c_void,
|
||||
end: *mut ::std::os::raw::c_void,
|
||||
);
|
||||
pub fn rb_jit_fix_mod_fix(recv: VALUE, obj: VALUE) -> VALUE;
|
||||
}
|
||||
|
||||
@ -398,6 +398,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
|
||||
Insn::FixnumGe { left, right } => gen_fixnum_ge(asm, opnd!(left), opnd!(right)),
|
||||
Insn::FixnumAnd { left, right } => gen_fixnum_and(asm, opnd!(left), opnd!(right)),
|
||||
Insn::FixnumOr { left, right } => gen_fixnum_or(asm, opnd!(left), opnd!(right)),
|
||||
&Insn::FixnumMod { left, right, state } => gen_fixnum_mod(jit, asm, opnd!(left), opnd!(right), &function.frame_state(state)),
|
||||
Insn::IsNil { val } => gen_isnil(asm, opnd!(val)),
|
||||
&Insn::IsMethodCfunc { val, cd, cfunc, state: _ } => gen_is_method_cfunc(jit, asm, opnd!(val), cd, cfunc),
|
||||
&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
|
||||
&Insn::LoadIvarExtended { self_val, id, index } => gen_load_ivar_extended(asm, opnd!(self_val), id, index),
|
||||
&Insn::ArrayMax { state, .. }
|
||||
| &Insn::FixnumDiv { state, .. }
|
||||
| &Insn::FixnumMod { state, .. }
|
||||
| &Insn::Throw { state, .. }
|
||||
=> return Err(state),
|
||||
};
|
||||
@ -1460,6 +1460,13 @@ fn gen_fixnum_or(asm: &mut Assembler, left: lir::Opnd, right: lir::Opnd) -> lir:
|
||||
asm.or(left, right)
|
||||
}
|
||||
|
||||
fn gen_fixnum_mod(jit: &mut JITState, asm: &mut Assembler, left: lir::Opnd, right: lir::Opnd, state: &FrameState) -> lir::Opnd {
|
||||
// Check for left % 0, which raises ZeroDivisionError
|
||||
asm.cmp(right, Opnd::from(VALUE::fixnum_from_usize(0)));
|
||||
asm.je(side_exit(jit, state, FixnumModByZero));
|
||||
asm_ccall!(asm, rb_fix_mod_fix, left, right)
|
||||
}
|
||||
|
||||
// Compile val == nil
|
||||
fn gen_isnil(asm: &mut Assembler, val: lir::Opnd) -> lir::Opnd {
|
||||
asm.cmp(val, Qnil.into());
|
||||
|
||||
@ -134,6 +134,7 @@ unsafe extern "C" {
|
||||
pub fn rb_str_setbyte(str: VALUE, index: VALUE, value: VALUE) -> VALUE;
|
||||
pub fn rb_str_getbyte(str: VALUE, index: VALUE) -> VALUE;
|
||||
pub fn rb_vm_splat_array(flag: VALUE, ary: VALUE) -> VALUE;
|
||||
pub fn rb_jit_fix_mod_fix(x: VALUE, y: VALUE) -> VALUE;
|
||||
pub fn rb_vm_concat_array(ary1: VALUE, ary2st: VALUE) -> VALUE;
|
||||
pub fn rb_vm_get_special_object(reg_ep: *const VALUE, value_type: vm_special_object_type) -> VALUE;
|
||||
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;
|
||||
pub use rb_METHOD_ENTRY_VISI as METHOD_ENTRY_VISI;
|
||||
pub use rb_RCLASS_ORIGIN as RCLASS_ORIGIN;
|
||||
pub use rb_vm_get_special_object as vm_get_special_object;
|
||||
pub use rb_jit_fix_mod_fix as rb_fix_mod_fix;
|
||||
|
||||
/// Helper so we can get a Rust string for insn_name()
|
||||
pub fn insn_name(opcode: usize) -> String {
|
||||
|
||||
@ -468,6 +468,7 @@ pub enum SideExitReason {
|
||||
BlockParamProxyModified,
|
||||
BlockParamProxyNotIseqOrIfunc,
|
||||
StackOverflow,
|
||||
FixnumModByZero,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
||||
@ -137,6 +137,7 @@ make_counters! {
|
||||
exit_fixnum_add_overflow,
|
||||
exit_fixnum_sub_overflow,
|
||||
exit_fixnum_mult_overflow,
|
||||
exit_fixnum_mod_by_zero,
|
||||
exit_guard_type_failure,
|
||||
exit_guard_type_not_failure,
|
||||
exit_guard_bit_equals_failure,
|
||||
@ -332,6 +333,7 @@ pub fn side_exit_counter(reason: crate::hir::SideExitReason) -> Counter {
|
||||
FixnumAddOverflow => exit_fixnum_add_overflow,
|
||||
FixnumSubOverflow => exit_fixnum_sub_overflow,
|
||||
FixnumMultOverflow => exit_fixnum_mult_overflow,
|
||||
FixnumModByZero => exit_fixnum_mod_by_zero,
|
||||
GuardType(_) => exit_guard_type_failure,
|
||||
GuardTypeNot(_) => exit_guard_type_not_failure,
|
||||
GuardBitEquals(_) => exit_guard_bit_equals_failure,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user