ruby-changes:73275
From: Takashi <ko1@a...>
Date: Tue, 30 Aug 2022 01:07:31 +0900 (JST)
Subject: [ruby-changes:73275] 49c9f893f8 (master): Port expandarray to the new backend IR (https://github.com/Shopify/ruby/pull/376)
https://git.ruby-lang.org/ruby.git/commit/?id=49c9f893f8 From 49c9f893f863108f741b6b6535dc53126733ded0 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun <takashikkbn@g...> Date: Tue, 9 Aug 2022 10:01:20 -0700 Subject: Port expandarray to the new backend IR (https://github.com/Shopify/ruby/pull/376) * Port expandarray to the new backend IR * More use of into() * Break out live ranges * Refactor the code further * Reuse registers more --- yjit/src/codegen.rs | 104 ++++++++++++++++++++++++---------------------------- 1 file changed, 47 insertions(+), 57 deletions(-) diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index b8f4b84285..491eec0aeb 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -1285,50 +1285,43 @@ fn gen_newrange( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L1285 KeepCompiling } -/* fn guard_object_is_heap( - cb: &mut CodeBlock, - object_opnd: X86Opnd, - _ctx: &mut Context, + asm: &mut Assembler, + object_opnd: Opnd, side_exit: CodePtr, ) { - add_comment(cb, "guard object is heap"); + asm.comment("guard object is heap"); // Test that the object is not an immediate - test(cb, object_opnd, uimm_opnd(RUBY_IMMEDIATE_MASK as u64)); - jnz_ptr(cb, side_exit); + asm.test(object_opnd, (RUBY_IMMEDIATE_MASK as u64).into()); + asm.jnz(side_exit.into()); // Test that the object is not false or nil - cmp(cb, object_opnd, uimm_opnd(Qnil.into())); - jbe_ptr(cb, side_exit); + asm.cmp(object_opnd, Qnil.into()); + asm.jbe(side_exit.into()); } fn guard_object_is_array( - cb: &mut CodeBlock, - object_opnd: X86Opnd, - flags_opnd: X86Opnd, - _ctx: &mut Context, + asm: &mut Assembler, + object_opnd: Opnd, side_exit: CodePtr, ) { - add_comment(cb, "guard object is array"); + asm.comment("guard object is array"); // Pull out the type mask - mov( - cb, - flags_opnd, - mem_opnd( - 8 * SIZEOF_VALUE as u8, - object_opnd, - RUBY_OFFSET_RBASIC_FLAGS, - ), + let flags_opnd = Opnd::mem( + 8 * SIZEOF_VALUE as u8, + object_opnd, + RUBY_OFFSET_RBASIC_FLAGS, ); - and(cb, flags_opnd, uimm_opnd(RUBY_T_MASK as u64)); + let flags_opnd = asm.and(flags_opnd, (RUBY_T_MASK as u64).into()); // Compare the result with T_ARRAY - cmp(cb, flags_opnd, uimm_opnd(RUBY_T_ARRAY as u64)); - jne_ptr(cb, side_exit); + asm.cmp(flags_opnd, (RUBY_T_ARRAY as u64).into()); + asm.jne(side_exit.into()); } +/* fn guard_object_is_string( cb: &mut CodeBlock, object_reg: X86Opnd, @@ -1353,12 +1346,13 @@ fn guard_object_is_string( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L1346 cmp(cb, flags_reg, uimm_opnd(RUBY_T_STRING as u64)); jne_ptr(cb, side_exit); } +*/ // push enough nils onto the stack to fill out an array fn gen_expandarray( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, ocb: &mut OutlinedCb, ) -> CodegenStatus { let flag = jit_get_arg(jit, 1); @@ -1366,13 +1360,13 @@ fn gen_expandarray( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L1360 // If this instruction has the splat flag, then bail out. if flag_value & 0x01 != 0 { - incr_counter!(expandarray_splat); + gen_counter_incr!(asm, expandarray_splat); return CantCompile; } // If this instruction has the postarg flag, then bail out. if flag_value & 0x02 != 0 { - incr_counter!(expandarray_postarg); + gen_counter_incr!(asm, expandarray_postarg); return CantCompile; } @@ -1389,24 +1383,21 @@ fn gen_expandarray( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L1383 // push N nils onto the stack for _i in 0..(num.into()) { let push_opnd = ctx.stack_push(Type::Nil); - mov(cb, push_opnd, uimm_opnd(Qnil.into())); + asm.mov(push_opnd, Qnil.into()); } return KeepCompiling; } // Move the array from the stack into REG0 and check that it's an array. - mov(cb, REG0, array_opnd); + let array_reg = asm.load(array_opnd); guard_object_is_heap( - cb, - REG0, - ctx, + asm, + array_reg, counted_exit!(ocb, side_exit, expandarray_not_array), ); guard_object_is_array( - cb, - REG0, - REG1, - ctx, + asm, + array_reg, counted_exit!(ocb, side_exit, expandarray_not_array), ); @@ -1416,52 +1407,51 @@ fn gen_expandarray( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L1407 } // Pull out the embed flag to check if it's an embedded array. - let flags_opnd = mem_opnd((8 * SIZEOF_VALUE) as u8, REG0, RUBY_OFFSET_RBASIC_FLAGS); - mov(cb, REG1, flags_opnd); + let flags_opnd = Opnd::mem((8 * SIZEOF_VALUE) as u8, array_reg, RUBY_OFFSET_RBASIC_FLAGS); // Move the length of the embedded array into REG1. - and(cb, REG1, uimm_opnd(RARRAY_EMBED_LEN_MASK as u64)); - shr(cb, REG1, uimm_opnd(RARRAY_EMBED_LEN_SHIFT as u64)); + let emb_len_opnd = asm.and(flags_opnd, (RARRAY_EMBED_LEN_MASK as u64).into()); + let emb_len_opnd = asm.rshift(emb_len_opnd, (RARRAY_EMBED_LEN_SHIFT as u64).into()); // Conditionally move the length of the heap array into REG1. - test(cb, flags_opnd, uimm_opnd(RARRAY_EMBED_FLAG as u64)); - let array_len_opnd = mem_opnd( + let flags_opnd = Opnd::mem((8 * SIZEOF_VALUE) as u8, array_reg, RUBY_OFFSET_RBASIC_FLAGS); + asm.test(flags_opnd, (RARRAY_EMBED_FLAG as u64).into()); + let array_len_opnd = Opnd::mem( (8 * size_of::<std::os::raw::c_long>()) as u8, - REG0, + asm.load(array_opnd), RUBY_OFFSET_RARRAY_AS_HEAP_LEN, ); - cmovz(cb, REG1, array_len_opnd); + let array_len_opnd = asm.csel_nz(emb_len_opnd, array_len_opnd); // Only handle the case where the number of values in the array is greater // than or equal to the number of values requested. - cmp(cb, REG1, uimm_opnd(num.into())); - jl_ptr(cb, counted_exit!(ocb, side_exit, expandarray_rhs_too_small)); + asm.cmp(array_len_opnd, num.into()); + asm.jo(counted_exit!(ocb, side_exit, expandarray_rhs_too_small).into()); // Load the address of the embedded array into REG1. // (struct RArray *)(obj)->as.ary - let ary_opnd = mem_opnd((8 * SIZEOF_VALUE) as u8, REG0, RUBY_OFFSET_RARRAY_AS_ARY); - lea(cb, REG1, ary_opnd); + let array_reg = asm.load(array_opnd); + let ary_opnd = asm.lea(Opnd::mem((8 * SIZEOF_VALUE) as u8, array_reg, RUBY_OFFSET_RARRAY_AS_ARY)); // Conditionally load the address of the heap array into REG1. // (struct RArray *)(obj)->as.heap.ptr - test(cb, flags_opnd, uimm_opnd(RARRAY_EMBED_FLAG as u64)); - let heap_ptr_opnd = mem_opnd( + let flags_opnd = Opnd::mem((8 * SIZEOF_VALUE) as u8, array_reg, RUBY_OFFSET_RBASIC_FLAGS); + asm.test(flags_opnd, Opnd::UImm(RARRAY_EMBED_FLAG as u64)); + let heap_ptr_opnd = Opnd::mem( (8 * size_of::<usize>()) as u8, - REG0, + asm.load(array_opnd), RUBY_OFFSET_RARRAY_AS_HEAP_PTR, ); - cmovz(cb, REG1, heap_ptr_opnd); + let ary_opnd = asm.csel_nz(ary_opnd, heap_ptr_opnd); // Loop backward through the array and push each element onto the stack. for i in (0..(num.as_i32())).rev() { let top = ctx.stack_push(Type::Unknown); - mov(cb, REG0, mem_opnd(64, REG1, i * (SIZEOF_VALUE as i32))); - mov(cb, top, REG0); + asm.mov(top, Opnd::mem(64, ary_opnd, i * (SIZEOF_VALUE as i32))); } KeepCompiling } -*/ fn gen_getlocal_wc0( jit: &mut JITState, @@ -5927,7 +5917,7 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> { https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L5917 YARVINSN_splatarray => Some(gen_splatarray), YARVINSN_newrange => Some(gen_newrange), YARVINSN_putstring => Some(gen_putstring), - //YARVINSN_expandarray => Some(gen_expandarray), + YARVINSN_expandarray => Some(gen_expandarray), YARVINSN_defined => Some(gen_defined), YARVINSN_checkkeyword => Some(gen_checkkeyword), YARVINSN_concatstrings => Some(gen_concatstrings), -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/