ruby-changes:68576
From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:09:49 +0900 (JST)
Subject: [ruby-changes:68576] 8a5ced8eb5 (master): Chain compilation of adjacent instructions
https://git.ruby-lang.org/ruby.git/commit/?id=8a5ced8eb5 From 8a5ced8eb5ed96ba3d806b2a30790c87c453a9a0 Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...> Date: Wed, 16 Sep 2020 13:52:35 -0400 Subject: Chain compilation of adjacent instructions --- ujit_compile.c | 65 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/ujit_compile.c b/ujit_compile.c index bd2d8697eb..60dc6a0927 100644 --- a/ujit_compile.c +++ b/ujit_compile.c @@ -109,40 +109,61 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L109 uint8_t *code_ptr = &cb->mem_block[cb->write_pos]; //printf("write pos: %ld\n", cb->write_pos); - int insn = (int)iseq->body->iseq_encoded[insn_idx]; - int len = insn_len(insn); - //const char* name = insn_name(insn); - //printf("%s\n", name); - - // Lookup the codegen function for this instruction - st_data_t st_gen_fn; - int found = rb_st_lookup(gen_fns, insn, &st_gen_fn); - - if (!found) - return 0; - - codegen_fn gen_fn = (codegen_fn)st_gen_fn; - - // Write the pre call bytes - ujit_instr_entry(cb); + // Get the first opcode in the sequence + int first_opcode = (int)iseq->body->iseq_encoded[insn_idx]; // Create codegen context ctx_t ctx; - // Set the current PC - ctx.pc = &iseq->body->iseq_encoded[insn_idx]; + // For each instruction to compile + size_t num_instrs; + for (num_instrs = 0;; ++num_instrs) + { + // Set the current PC + ctx.pc = &iseq->body->iseq_encoded[insn_idx]; + + // Get the current opcode + int opcode = ctx_get_opcode(&ctx); + //const char* name = insn_name(insn); + //printf("%s\n", name); + + // Lookup the codegen function for this instruction + st_data_t st_gen_fn; + int found = rb_st_lookup(gen_fns, opcode, &st_gen_fn); + + if (!found) + { + break; + } + + // Write the pre call bytes before the first instruction + if (num_instrs == 0) + { + ujit_instr_entry(cb); + } + + // Call the code generation function + codegen_fn gen_fn = (codegen_fn)st_gen_fn; + gen_fn(cb, &ctx); + + // Move to the next instruction + insn_idx += insn_len(opcode); + } - // Call the code generation function - gen_fn(cb, &ctx); + // If no instructions were compiled + if (num_instrs == 0) + { + return NULL; + } // Directly return the next PC, which is a constant - void *next_pc = &iseq->body->iseq_encoded[insn_idx + len]; + void *next_pc = &iseq->body->iseq_encoded[insn_idx]; mov(cb, RAX, const_ptr_opnd(next_pc)); // Write the post call bytes ujit_instr_exit(cb); - addr2insn_bookkeeping(code_ptr, insn); + addr2insn_bookkeeping(code_ptr, first_opcode); return code_ptr; } -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/