From 3872aa0130746d1de6cf9cb35f0039a1c6bfd2fe Mon Sep 17 00:00:00 2001 From: Aleksey Demakov Date: Sat, 28 Mar 2009 00:11:38 +0000 Subject: [PATCH] make register pair handling more flexible --- ChangeLog | 11 ++- jit/jit-reg-alloc.c | 182 ++++++++++++----------------------------- jit/jit-reg-alloc.h | 2 - jit/jit-rules-arm.c | 22 +++++ jit/jit-rules-interp.c | 15 ++++ jit/jit-rules-x86.c | 14 ++++ jit/jit-rules.h | 27 +++++- 7 files changed, 137 insertions(+), 136 deletions(-) diff --git a/ChangeLog b/ChangeLog index e58df7f..846e839 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,14 @@ 2009-03-28 Aleksey Demakov - * jit/jit-reg-alloc.c, jit/jit-reg-alloc.c (_jit_regs_get_cpu): - remove unused function. + * jit/jit-rules.h (jit_reg_name, jit_reg_flags, jit_reg_code); add + convenience macros for register info access. + * jit/jit-rules.h, jit/jit-rules-interp.c, jit/jit-rules-x86.c, + * jit/jit-rules-arm.c (_jit_reg_get_pair, jit_reg_get_pair): add + function and macro for finding register pair. + * jit/jit-reg-alloc.c: replace use of _jit_regs_needs_long_pair with + jit_reg_get_pair(). + * jit/jit-reg-alloc.h, jit/jit-reg-alloc.c (_jit_regs_get_cpu) + (_jit_regs_needs_long_pair): remove unused functions. 2009-03-25 Michele Tartara diff --git a/jit/jit-reg-alloc.c b/jit/jit-reg-alloc.c index 15eb4b7..696cf7c 100644 --- a/jit/jit-reg-alloc.c +++ b/jit/jit-reg-alloc.c @@ -139,7 +139,7 @@ static void dump_regs(jit_gencode_t gen, const char *name) #endif /* - * Find the start register of a long pair given the end register. + * Find the start register of a register pair given the end register. */ static int get_long_pair_start(int other_reg) @@ -155,43 +155,6 @@ get_long_pair_start(int other_reg) return -1; } -/* - * Determine the type of register that we need. - */ -static int -get_register_type(jit_value_t value, int need_pair) -{ - switch(jit_type_normalize(value->type)->kind) - { - case JIT_TYPE_SBYTE: - case JIT_TYPE_UBYTE: - case JIT_TYPE_SHORT: - case JIT_TYPE_USHORT: - case JIT_TYPE_INT: - case JIT_TYPE_UINT: - case JIT_TYPE_NINT: - case JIT_TYPE_NUINT: - case JIT_TYPE_SIGNATURE: - case JIT_TYPE_PTR: - return JIT_REG_WORD; - - case JIT_TYPE_LONG: - case JIT_TYPE_ULONG: - return need_pair ? JIT_REG_LONG : JIT_REG_WORD; - - case JIT_TYPE_FLOAT32: - return JIT_REG_FLOAT32; - - case JIT_TYPE_FLOAT64: - return JIT_REG_FLOAT64; - - case JIT_TYPE_NFLOAT: - return JIT_REG_NFLOAT; - } - - return 0; -} - /* * Check if two values are known to be equal. */ @@ -1139,7 +1102,6 @@ static int choose_output_register(jit_gencode_t gen, _jit_regs_t *regs) { _jit_regclass_t *regclass; - int need_pair; int reg_index, reg, other_reg; int use_cost; int suitable_reg, suitable_other_reg; @@ -1151,7 +1113,6 @@ choose_output_register(jit_gencode_t gen, _jit_regs_t *regs) #endif regclass = regs->descs[0].regclass; - need_pair = _jit_regs_needs_long_pair(regs->descs[0].value->type); suitable_reg = -1; suitable_other_reg = -1; @@ -1165,17 +1126,10 @@ choose_output_register(jit_gencode_t gen, _jit_regs_t *regs) continue; } - if(need_pair) - { - other_reg = jit_reg_other_reg(reg); - if(jit_reg_is_used(gen->inhibit, other_reg)) - { - continue; - } - } - else + other_reg = jit_reg_get_pair(regs->descs[0].value->type, reg); + if(other_reg >= 0 && jit_reg_is_used(gen->inhibit, other_reg)) { - other_reg = -1; + continue; } if(jit_reg_is_used(gen->permanent, reg)) @@ -1377,7 +1331,6 @@ choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index) _jit_regclass_t *regclass; _jit_regdesc_t *desc; _jit_regdesc_t *desc2; - int need_pair; int reg_index, reg, other_reg; int use_cost; int suitable_reg, suitable_other_reg; @@ -1396,7 +1349,6 @@ choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index) } regclass = regs->descs[index].regclass; - need_pair = _jit_regs_needs_long_pair(desc->value->type); if(index == regs->dest_input_index) { @@ -1419,17 +1371,10 @@ choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index) continue; } - if(need_pair) - { - other_reg = jit_reg_other_reg(reg); - if(jit_reg_is_used(regs->assigned, other_reg)) - { - continue; - } - } - else + other_reg = jit_reg_get_pair(desc->value->type, reg); + if(other_reg >= 0 && jit_reg_is_used(regs->assigned, other_reg)) { - other_reg = -1; + continue; } if((desc->value->in_global_register && desc->value->global_reg == reg) @@ -2677,29 +2622,6 @@ _jit_regs_lookup(char *name) return -1; } -/*@ - * @deftypefun int _jit_regs_needs_long_pair (jit_type_t type) - * Determine if a type requires a long register pair. - * @end deftypefun -@*/ -int _jit_regs_needs_long_pair(jit_type_t type) -{ -#if defined(JIT_NATIVE_INT32) && !defined(JIT_BACKEND_INTERP) - type = jit_type_normalize(type); - if(type) - { - if(type->kind == JIT_TYPE_LONG || type->kind == JIT_TYPE_ULONG) - { - return 1; - } - } - return 0; -#else - /* We don't register pairs on 64-bit platforms or the interpreter */ - return 0; -#endif -} - /*@ * @deftypefun void _jit_regs_alloc_global (jit_gencode_t gen, jit_function_t func) * Perform global register allocation on the values in @code{func}. @@ -2890,15 +2812,8 @@ _jit_regs_set_incoming(jit_gencode_t gen, int reg, jit_value_t value) { int other_reg; - /* Find the other register in a long pair */ - if(_jit_regs_needs_long_pair(value->type)) - { - other_reg = jit_reg_other_reg(reg); - } - else - { - other_reg = -1; - } + /* Find the other register in a register pair */ + other_reg = jit_reg_get_pair(value->type, reg); /* avd: It's too late to spill here, if there was any value it is already cloberred by the incoming value. @@ -2956,15 +2871,9 @@ _jit_regs_set_outgoing(jit_gencode_t gen, int reg, jit_value_t value) } } #else - if(_jit_regs_needs_long_pair(value->type)) - { - other_reg = jit_reg_other_reg(reg); - } - else - { - other_reg = -1; - } + other_reg = jit_reg_get_pair(value->type, reg); #endif + if(value->in_register && value->reg == reg) { /* The value is already in the register, but we may need to spill @@ -2998,11 +2907,15 @@ _jit_regs_set_outgoing(jit_gencode_t gen, int reg, jit_value_t value) } } +/* TODO: remove this function */ /*@ * @deftypefun void _jit_regs_force_out (jit_gencode_t gen, jit_value_t value, int is_dest) * If @code{value} is currently in a register, then force its value out * into the stack frame. The @code{is_dest} flag indicates that the value * will be a destination, so we don't care about the original value. + * + * This function is deprecated and going to be removed soon. + * * @end deftypefun @*/ void _jit_regs_force_out(jit_gencode_t gen, jit_value_t value, int is_dest) @@ -3011,16 +2924,7 @@ void _jit_regs_force_out(jit_gencode_t gen, jit_value_t value, int is_dest) if(value->in_register) { reg = value->reg; - - /* Find the other register in a long pair */ - if(_jit_regs_needs_long_pair(value->type)) - { - other_reg = jit_reg_other_reg(reg); - } - else - { - other_reg = -1; - } + other_reg = jit_reg_get_pair(value->type, reg); if(is_dest) { @@ -3033,6 +2937,7 @@ void _jit_regs_force_out(jit_gencode_t gen, jit_value_t value, int is_dest) } } +/* TODO: remove this function */ /*@ * @deftypefun int _jit_regs_load_value (jit_gencode_t gen, jit_value_t value, int destroy, int used_again) * Load a value into any register that is suitable and return that register. @@ -3045,12 +2950,15 @@ void _jit_regs_force_out(jit_gencode_t gen, jit_value_t value, int is_dest) * * If @code{used_again} is non-zero, then it indicates that the value is * used again further down the block. + * + * This function is deprecated and going to be removed soon. + * * @end deftypefun @*/ int _jit_regs_load_value(jit_gencode_t gen, jit_value_t value, int destroy, int used_again) { - int type, need_pair; + int type; int reg, other_reg; int spill_cost; int suitable_reg, suitable_other_reg; @@ -3065,30 +2973,46 @@ _jit_regs_load_value(jit_gencode_t gen, jit_value_t value, int destroy, int used return value->global_reg; } - need_pair = _jit_regs_needs_long_pair(value->type); - /* If the value is already in a register, then try to use that register */ if(value->in_register && (!destroy || !used_again)) { reg = value->reg; if(!used_again) { - if(need_pair) - { - other_reg = jit_reg_other_reg(reg); - } - else - { - other_reg = -1; - } + other_reg = jit_reg_get_pair(value->type, reg); free_value(gen, value, reg, other_reg, 1); } return reg; } - type = get_register_type(value, need_pair); - if(!type) + switch(jit_type_normalize(value->type)->kind) { + case JIT_TYPE_SBYTE: + case JIT_TYPE_UBYTE: + case JIT_TYPE_SHORT: + case JIT_TYPE_USHORT: + case JIT_TYPE_INT: + case JIT_TYPE_UINT: + case JIT_TYPE_NINT: + case JIT_TYPE_NUINT: + case JIT_TYPE_SIGNATURE: + case JIT_TYPE_PTR: + type = JIT_REG_WORD; + break; + case JIT_TYPE_LONG: + case JIT_TYPE_ULONG: + type = JIT_REG_LONG; + break; + case JIT_TYPE_FLOAT32: + type = JIT_REG_FLOAT32; + break; + case JIT_TYPE_FLOAT64: + type = JIT_REG_FLOAT64; + break; + case JIT_TYPE_NFLOAT: + type = JIT_REG_NFLOAT; + break; + default: return 0; } @@ -3111,9 +3035,9 @@ _jit_regs_load_value(jit_gencode_t gen, jit_value_t value, int destroy, int used continue; } - if(need_pair) + other_reg = jit_reg_get_pair(value->type, reg); + if(other_reg >= 0) { - other_reg = jit_reg_other_reg(reg); if(jit_reg_is_used(gen->inhibit, other_reg)) { continue; @@ -3123,10 +3047,6 @@ _jit_regs_load_value(jit_gencode_t gen, jit_value_t value, int destroy, int used continue; } } - else - { - other_reg = -1; - } spill_cost = compute_spill_cost(gen, 0, reg, other_reg); diff --git a/jit/jit-reg-alloc.h b/jit/jit-reg-alloc.h index 416e227..483b5c6 100644 --- a/jit/jit-reg-alloc.h +++ b/jit/jit-reg-alloc.h @@ -141,8 +141,6 @@ typedef struct } _jit_regs_t; int _jit_regs_lookup(char *name); -int _jit_regs_needs_long_pair(jit_type_t type); - void _jit_regs_alloc_global(jit_gencode_t gen, jit_function_t func); void _jit_regs_init_for_block(jit_gencode_t gen); void _jit_regs_spill_all(jit_gencode_t gen); diff --git a/jit/jit-rules-arm.c b/jit/jit-rules-arm.c index 2461f61..b1e9654 100644 --- a/jit/jit-rules-arm.c +++ b/jit/jit-rules-arm.c @@ -1407,4 +1407,26 @@ void _jit_gen_return_to_float(jit_gencode_t gen, jit_value_t value, int reg) } } + +int +_jit_reg_get_pair(jit_type_t type, int reg) +{ + type = jit_type_normalize(type); + if(type) + { + if(type->kind == JIT_TYPE_LONG || type->kind == JIT_TYPE_ULONG) + { + return jit_reg_other_reg(reg); + } + else if(type->kind == JIT_TYPE_FLOAT64 || type->kind == JIT_TYPE_NFLOAT) + { + if(reg == JIT_REG_R0) + { + return jit_reg_other_reg(reg); + } + } + } + return -1; +} + #endif /* JIT_BACKEND_ARM */ diff --git a/jit/jit-rules-interp.c b/jit/jit-rules-interp.c index 683f579..24a4b29 100644 --- a/jit/jit-rules-interp.c +++ b/jit/jit-rules-interp.c @@ -1643,4 +1643,19 @@ int _jit_gen_is_global_candidate(jit_type_t type) return 0; } +/*@ + * @deftypefun int _jit_reg_get_pair (jit_type_t @var{type}, int @var{reg}) + * Determine if a type requires a register pair. If so then for the specified + * register @var{reg} return the other register of the corresponding pair. + * Return -1 if no pair is required. + * + * This function is used only for native 32-bit backends. + * @end deftypefun +@*/ +int _jit_reg_get_pair(jit_type_t type, int reg) +{ + /* We don't register pairs on 64-bit platforms or the interpreter */ + return -1; +} + #endif /* JIT_BACKEND_INTERP */ diff --git a/jit/jit-rules-x86.c b/jit/jit-rules-x86.c index a79e3bf..abac940 100644 --- a/jit/jit-rules-x86.c +++ b/jit/jit-rules-x86.c @@ -1522,4 +1522,18 @@ int _jit_gen_is_global_candidate(jit_type_t type) return 0; } +int +_jit_reg_get_pair(jit_type_t type, int reg) +{ + type = jit_type_normalize(type); + if(type) + { + if(type->kind == JIT_TYPE_LONG || type->kind == JIT_TYPE_ULONG) + { + return jit_reg_other_reg(reg); + } + } + return -1; +} + #endif /* JIT_BACKEND_X86 */ diff --git a/jit/jit-rules.h b/jit/jit-rules.h index 3ca8ef9..3093cdd 100644 --- a/jit/jit-rules.h +++ b/jit/jit-rules.h @@ -110,10 +110,30 @@ typedef struct extern jit_reginfo_t const _jit_reg_info[JIT_NUM_REGS]; /* - * Given the first register of a long pair get the other register. + * Macros for getting register information */ + +/* Get register name. */ +#define jit_reg_name(reg) (_jit_reg_info[reg].name) + +/* Get register flags. */ +#define jit_reg_flags(reg) (_jit_reg_info[reg].flags) + +/* Get CPU register number for machine instruction encoding. */ +#define jit_reg_code(reg) (_jit_reg_info[reg].cpu_reg) + +/* Given the first register of a register pair get the other one. */ #define jit_reg_other_reg(reg) (_jit_reg_info[reg].other_reg) +/* Given a register find if a value of the specified type requires + * a register pair. Return the other register of the pair if it is + * required and return -1 otherwise. */ +#if defined(JIT_NATIVE_INT32) && !defined(JIT_BACKEND_INTERP) +# define jit_reg_get_pair(type,reg) _jit_reg_get_pair(type, reg) +#else +# define jit_reg_get_pair(type,reg) (-1) +#endif + /* * Manipulate register usage masks. The backend may override these * definitions if it has more registers than can fit in a "jit_uint". @@ -196,6 +216,7 @@ struct jit_elf_info /* * External function defintions. */ + void _jit_init_backend(void); void _jit_gen_get_elf_info(jit_elf_info_t *info); int _jit_create_entry_insns(jit_function_t func); @@ -230,6 +251,10 @@ void _jit_gen_start_block(jit_gencode_t gen, jit_block_t block); void _jit_gen_end_block(jit_gencode_t gen, jit_block_t block); int _jit_gen_is_global_candidate(jit_type_t type); +#if defined(JIT_NATIVE_INT32) && !defined(JIT_BACKEND_INTERP) +int _jit_reg_get_pair(jit_type_t type, int reg); +#endif + /* * Determine the byte number within a "jit_int" where the low * order byte can be found. -- 2.47.3