Skip to content

Commit

Permalink
Port opt_minus, opt_or, and opt_and to the new IR (#364)
Browse files Browse the repository at this point in the history
* Port opt_minus, opt_or, and opt_and to the new IR

* Fix the Op::Or issue with push_insn

* Prefer asm.store for clarity
  • Loading branch information
k0kubun committed Aug 26, 2022
1 parent 1d92fa4 commit 58fe689
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 29 deletions.
42 changes: 42 additions & 0 deletions bootstraptest/test_yjit_new_backend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,48 @@ def foo(foo: 1+1)
[foo, foo(foo: 5)]
}

# opt_minus
assert_equal '1', %q{
def foo
2 - 1
end
foo
}
assert_equal '[1]', %q{
def foo
[1, 2] - [2]
end
foo
}

# opt_and
assert_equal '1', %q{
def foo
3 & 1
end
foo
}
assert_equal '[2]', %q{
def foo
[1, 2] & [2]
end
foo
}

# opt_or
assert_equal '3', %q{
def foo
2 | 1
end
foo
}
assert_equal '[1, 2, 3]', %q{
def foo
[1, 2] | [2, 3]
end
foo
}

# putobject, getlocal, newhash
assert_equal '{:a=>777}', %q{
def foo(n)
Expand Down
6 changes: 3 additions & 3 deletions yjit/src/backend/arm64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,17 +181,17 @@ impl Assembler
Op::And | Op::Or => {
match (opnds[0], opnds[1]) {
(Opnd::Reg(_), Opnd::Reg(_)) => {
asm.and(opnds[0], opnds[1]);
asm.push_insn(op, vec![opnds[0], opnds[1]], target, text, pos_marker);
},
(reg_opnd @ Opnd::Reg(_), other_opnd) |
(other_opnd, reg_opnd @ Opnd::Reg(_)) => {
let opnd1 = split_bitmask_immediate(asm, other_opnd);
asm.and(reg_opnd, opnd1);
asm.push_insn(op, vec![reg_opnd, opnd1], target, text, pos_marker);
},
_ => {
let opnd0 = asm.load(opnds[0]);
let opnd1 = split_bitmask_immediate(asm, opnds[1]);
asm.and(opnd0, opnd1);
asm.push_insn(op, vec![opnd0, opnd1], target, text, pos_marker);
}
}
},
Expand Down
47 changes: 21 additions & 26 deletions yjit/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2809,16 +2809,17 @@ fn gen_opt_aset(
gen_opt_send_without_block(jit, ctx, cb, ocb)
}
}
*/

fn gen_opt_and(
jit: &mut JITState,
ctx: &mut Context,
cb: &mut CodeBlock,
asm: &mut Assembler,
ocb: &mut OutlinedCb,
) -> CodegenStatus {
// Defer compilation so we can specialize on a runtime `self`
if !jit_at_current_insn(jit) {
defer_compilation(jit, ctx, cb, ocb);
defer_compilation(jit, ctx, asm, ocb);
return EndBlock;
}

Expand All @@ -2835,36 +2836,35 @@ fn gen_opt_and(
}

// Check that both operands are fixnums
guard_two_fixnums(ctx, cb, side_exit);
guard_two_fixnums(ctx, asm, side_exit);

// Get the operands and destination from the stack
let arg1 = ctx.stack_pop(1);
let arg0 = ctx.stack_pop(1);

// Do the bitwise and arg0 & arg1
mov(cb, REG0, arg0);
and(cb, REG0, arg1);
let val = asm.and(arg0, arg1);

// Push the output on the stack
let dst = ctx.stack_push(Type::Fixnum);
mov(cb, dst, REG0);
asm.store(dst, val);

KeepCompiling
} else {
// Delegate to send, call the method on the recv
gen_opt_send_without_block(jit, ctx, cb, ocb)
gen_opt_send_without_block(jit, ctx, asm, ocb)
}
}

fn gen_opt_or(
jit: &mut JITState,
ctx: &mut Context,
cb: &mut CodeBlock,
asm: &mut Assembler,
ocb: &mut OutlinedCb,
) -> CodegenStatus {
// Defer compilation so we can specialize on a runtime `self`
if !jit_at_current_insn(jit) {
defer_compilation(jit, ctx, cb, ocb);
defer_compilation(jit, ctx, asm, ocb);
return EndBlock;
}

Expand All @@ -2881,36 +2881,35 @@ fn gen_opt_or(
}

// Check that both operands are fixnums
guard_two_fixnums(ctx, cb, side_exit);
guard_two_fixnums(ctx, asm, side_exit);

// Get the operands and destination from the stack
let arg1 = ctx.stack_pop(1);
let arg0 = ctx.stack_pop(1);

// Do the bitwise or arg0 | arg1
mov(cb, REG0, arg0);
or(cb, REG0, arg1);
let val = asm.or(arg0, arg1);

// Push the output on the stack
let dst = ctx.stack_push(Type::Fixnum);
mov(cb, dst, REG0);
asm.store(dst, val);

KeepCompiling
} else {
// Delegate to send, call the method on the recv
gen_opt_send_without_block(jit, ctx, cb, ocb)
gen_opt_send_without_block(jit, ctx, asm, ocb)
}
}

fn gen_opt_minus(
jit: &mut JITState,
ctx: &mut Context,
cb: &mut CodeBlock,
asm: &mut Assembler,
ocb: &mut OutlinedCb,
) -> CodegenStatus {
// Defer compilation so we can specialize on a runtime `self`
if !jit_at_current_insn(jit) {
defer_compilation(jit, ctx, cb, ocb);
defer_compilation(jit, ctx, asm, ocb);
return EndBlock;
}

Expand All @@ -2927,29 +2926,27 @@ fn gen_opt_minus(
}

// Check that both operands are fixnums
guard_two_fixnums(ctx, cb, side_exit);
guard_two_fixnums(ctx, asm, side_exit);

// Get the operands and destination from the stack
let arg1 = ctx.stack_pop(1);
let arg0 = ctx.stack_pop(1);

// Subtract arg0 - arg1 and test for overflow
mov(cb, REG0, arg0);
sub(cb, REG0, arg1);
jo_ptr(cb, side_exit);
add(cb, REG0, imm_opnd(1));
let val_untag = asm.sub(arg0, arg1);
asm.jo(side_exit.into());
let val = asm.add(val_untag, Opnd::Imm(1));

// Push the output on the stack
let dst = ctx.stack_push(Type::Fixnum);
mov(cb, dst, REG0);
asm.store(dst, val);

KeepCompiling
} else {
// Delegate to send, call the method on the recv
gen_opt_send_without_block(jit, ctx, cb, ocb)
gen_opt_send_without_block(jit, ctx, asm, ocb)
}
}
*/

fn gen_opt_mult(
jit: &mut JITState,
Expand Down Expand Up @@ -5957,11 +5954,9 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
YARVINSN_setlocal_WC_0 => Some(gen_setlocal_wc0),
YARVINSN_setlocal_WC_1 => Some(gen_setlocal_wc1),
YARVINSN_opt_plus => Some(gen_opt_plus),
/*
YARVINSN_opt_minus => Some(gen_opt_minus),
YARVINSN_opt_and => Some(gen_opt_and),
YARVINSN_opt_or => Some(gen_opt_or),
*/
YARVINSN_newhash => Some(gen_newhash),
YARVINSN_duphash => Some(gen_duphash),
YARVINSN_newarray => Some(gen_newarray),
Expand Down

0 comments on commit 58fe689

Please sign in to comment.