From 6b263818d39b5de8904e6403387b7cd7dc431f4a Mon Sep 17 00:00:00 2001 From: Per Hedbor <ph@opera.com> Date: Fri, 15 Aug 2014 16:05:32 +0200 Subject: [PATCH] Removed CLEAR_2_LOCAL & CLEAR_4_LOCAL, added CLEAR_N_LOCAL This simplifies things a bit, and reduces codesize at times. The record I have seen while running the testsuite was a clear_n_local(23). --- src/code/amd64.c | 60 ++++++++++++++++----------------------- src/interpret_functions.h | 12 ++------ src/peep.in | 15 ++++------ 3 files changed, 33 insertions(+), 54 deletions(-) diff --git a/src/code/amd64.c b/src/code/amd64.c index 63be28eb1c..aa25af94e4 100644 --- a/src/code/amd64.c +++ b/src/code/amd64.c @@ -2757,42 +2757,8 @@ void ins_f_byte_with_arg(unsigned int a, INT32 b) amd64_push_svaluep(P_REG_RCX); return; - case F_CLEAR_4_LOCAL: - { - LABELS(); - ins_debug_instr_prologue(a-F_OFFSET, b, 0); - amd64_load_fp_reg(); - mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), P_REG_RBX); - add_reg_imm(P_REG_RBX, b*sizeof(struct svalue)); - mov_imm_reg(3, P_REG_R8 ); - /* need to use a saving register for the counter. */ - - LABEL_A; - amd64_free_svalue(P_REG_RBX, 0); - mov_imm_mem(PIKE_T_INT, P_REG_RBX, OFFSETOF(svalue, tu.t.type)); - mov_imm_mem(0, P_REG_RBX, OFFSETOF(svalue, u.integer)); - add_reg_imm(P_REG_RBX, sizeof(struct svalue ) ); - add_reg_imm(P_REG_R8,-1); - jnz(&label_A); - } - return; - - case F_CLEAR_2_LOCAL: case F_CLEAR_LOCAL: - ins_debug_instr_prologue(a-F_OFFSET, b, 0); - amd64_load_fp_reg(); - mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), P_REG_RBX); - add_reg_imm(P_REG_RBX, b*sizeof(struct svalue)); - amd64_free_svalue(P_REG_RBX, 0); - mov_imm_mem(PIKE_T_INT, P_REG_RBX, OFFSETOF(svalue, tu.t.type)); - mov_imm_mem(0, P_REG_RBX, OFFSETOF(svalue, u.integer)); - if( a == F_CLEAR_2_LOCAL ) - { - add_reg_imm( P_REG_RBX, sizeof(struct svalue ) ); - amd64_free_svalue(P_REG_RBX, 0); - mov_imm_mem(PIKE_T_INT, P_REG_RBX, OFFSETOF(svalue, tu.t.type)); - mov_imm_mem(0, P_REG_RBX, OFFSETOF(svalue, u.integer)); - } + ins_f_byte_with_2_args( F_CLEAR_N_LOCAL, b, 1 ); return; case F_INC_LOCAL_AND_POP: @@ -3097,6 +3063,30 @@ void ins_f_byte_with_2_args(unsigned int a, INT32 b, INT32 c) ins_f_byte(F_MARK); ins_f_byte_with_2_args(F_EXTERNAL, b, c); return; + + case F_CLEAR_N_LOCAL: + { + LABELS(); + ins_debug_instr_prologue(a-F_OFFSET, b, 0); + amd64_load_fp_reg(); + mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), P_REG_RBX); + add_reg_imm(P_REG_RBX, b*sizeof(struct svalue)); + if( c > 1 ) + add_reg_imm_reg(P_REG_RBX, c*sizeof(struct svalue), P_REG_RBP ); + + LABEL_A; + amd64_free_svalue(P_REG_RBX, 0); + mov_imm_mem(PIKE_T_INT, P_REG_RBX, OFFSETOF(svalue, tu.t.type)); + mov_imm_mem(0, P_REG_RBX, OFFSETOF(svalue, u.integer)); + if( c > 1 ) + { + add_reg_imm(P_REG_RBX, sizeof(struct svalue ) ); + cmp_reg_reg( P_REG_RBX, P_REG_RBP ); + jne(&label_A); + } + } + return; + case F_LOCAL_LOCAL_INDEX: { LABELS(); diff --git a/src/interpret_functions.h b/src/interpret_functions.h index 6d9630e9e0..3540740c7c 100644 --- a/src/interpret_functions.h +++ b/src/interpret_functions.h @@ -549,17 +549,11 @@ OPCODE1(F_ARRAY_LVALUE, "[ lvalues ]", I_UPDATE_SP, { Pike_sp++; }); -OPCODE1(F_CLEAR_2_LOCAL, "clear 2 local", 0, { - free_mixed_svalues(Pike_fp->locals + arg1, 2); - SET_SVAL(Pike_fp->locals[arg1], PIKE_T_INT, NUMBER_NUMBER, integer, 0); - SET_SVAL(Pike_fp->locals[arg1+1], PIKE_T_INT, NUMBER_NUMBER, integer, 0); -}); - -OPCODE1(F_CLEAR_4_LOCAL, "clear 4 local", 0, { +OPCODE2(F_CLEAR_N_LOCAL, "clear n local", 0, { struct svalue *locals = Pike_fp->locals; int e; - free_mixed_svalues(locals + arg1, 4); - for(e = 0; e < 4; e++) + free_mixed_svalues(locals + arg1, arg2); + for(e = 0; e < arg2; e++) { SET_SVAL(locals[arg1+e], PIKE_T_INT, NUMBER_NUMBER, integer, 0); } diff --git a/src/peep.in b/src/peep.in index b306aca1f6..640719b265 100644 --- a/src/peep.in +++ b/src/peep.in @@ -95,21 +95,16 @@ CONST_1 ASSIGN_GLOBAL_AND_POP : ASSIGN_GLOBAL_NUMBER_AND_POP($2a,-1) // Remove clearing of locals from the beginning of functions // But don't remove clearing of arguments! BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0) -BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_2_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0) -BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_4_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0) +BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_N_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0) BYTE ENTRY START_FUNCTION CLEAR_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION -BYTE ENTRY START_FUNCTION CLEAR_2_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION -BYTE ENTRY START_FUNCTION CLEAR_4_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION +BYTE ENTRY START_FUNCTION CLEAR_N_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION CLEAR_LOCAL CLEAR_LOCAL($1a) : CLEAR_LOCAL($1a) -CLEAR_LOCAL CLEAR_LOCAL($1a+1) : CLEAR_2_LOCAL($1a) -CLEAR_2_LOCAL CLEAR_2_LOCAL($1a+2) : CLEAR_4_LOCAL($1a) +CLEAR_LOCAL CLEAR_LOCAL($1a+1) : CLEAR_N_LOCAL($1a,2) -// Attempt to make the above trigger more often. -CLEAR_LOCAL CLEAR_2_LOCAL($1a+1) : CLEAR_2_LOCAL($1a) CLEAR_LOCAL($2a+1) -CLEAR_LOCAL CLEAR_4_LOCAL($1a+1) : CLEAR_4_LOCAL($1a) CLEAR_LOCAL($2a+3) -CLEAR_2_LOCAL CLEAR_4_LOCAL($1a+2) : CLEAR_4_LOCAL($1a) CLEAR_2_LOCAL($2a+2) +CLEAR_LOCAL CLEAR_N_LOCAL($1a+1) : CLEAR_N_LOCAL($1a,$2b+1) +CLEAR_N_LOCAL CLEAR_LOCAL($1a+$1b) : CLEAR_N_LOCAL($1a,$1b+1) // Attempt to de-interleave clearing of locals. CONST0 CLEAR_LOCAL : CLEAR_LOCAL($2a) CONST0 -- GitLab