From ac8c42942889e39ec3f366e01ecd32e98de7eb91 Mon Sep 17 00:00:00 2001 From: Aleksey Demakov Date: Sun, 26 Nov 2006 12:05:02 +0000 Subject: [PATCH] fix global register use cost computation; mark a few x86 instruction selection rules as commutative; --- ChangeLog | 9 +++ jit/jit-reg-alloc.c | 125 ++++++++++++++++++++++++------------------ jit/jit-rules-x86.ins | 18 +++--- 3 files changed, 91 insertions(+), 61 deletions(-) diff --git a/ChangeLog b/ChangeLog index 68c2456..df1ec09 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-11-26 Aleksey Demakov + + * jit/jit-reg-alloc.c (choose_output_register): fix global register + use cost computation. + + * jit/jit-rules-x86.ins: mark as commutative JIT_OP_IADD, + JIT_OP_IMUL, JIT_OP_LADD, JIT_OP_IAND, JIT_OP_IOR, JIT_OP_IXOR, + JIT_OP_LAND, JIT_OP_LOR, JIT_OP_XOR rules. + 2006-11-25 Aleksey Demakov * jit/jit-reg-alloc.c (exch_stack_top, free_value): fix freeing diff --git a/jit/jit-reg-alloc.c b/jit/jit-reg-alloc.c index 8a444e8..829c0f2 100644 --- a/jit/jit-reg-alloc.c +++ b/jit/jit-reg-alloc.c @@ -984,7 +984,7 @@ static int choose_scratch_register(jit_gencode_t gen, _jit_regs_t *regs, int index) { int reg, type; - int use_cost, spill_cost; + int use_cost; int suitable_reg; int suitable_cost; int suitable_age; @@ -1042,14 +1042,15 @@ choose_scratch_register(jit_gencode_t gen, _jit_regs_t *regs, int index) use_cost += COST_THRASH; } - spill_cost = compute_spill_cost(gen, regs, reg, -1); + use_cost += compute_spill_cost(gen, regs, reg, -1); - if((use_cost + spill_cost) < suitable_cost - || (spill_cost > 0 && (use_cost + spill_cost) == suitable_cost + if(use_cost < suitable_cost + || (use_cost == suitable_cost + && gen->contents[reg].num_values > 0 && gen->contents[reg].age < suitable_age)) { suitable_reg = reg; - suitable_cost = use_cost + spill_cost; + suitable_cost = use_cost; suitable_age = gen->contents[reg].age; } } @@ -1068,7 +1069,7 @@ choose_output_register(jit_gencode_t gen, _jit_regs_t *regs) { int type, need_pair; int reg, other_reg; - int use_cost, spill_cost; + int use_cost; int suitable_reg, suitable_other_reg; int suitable_cost; int suitable_age; @@ -1112,18 +1113,45 @@ choose_output_register(jit_gencode_t gen, _jit_regs_t *regs) other_reg = -1; } - /* It is not allowed to assign an output value to a global register - unless it is the very value the global register contains. */ if(jit_reg_is_used(gen->permanent, reg)) { - if(regs->descs[0].value->has_global_register - && regs->descs[0].value->global_reg == reg) + if(!regs->descs[0].value->has_global_register + || regs->descs[0].value->global_reg != reg) + { + /* It is not allowed to assign an output value to a global + register unless it is the very value the global register + contains. */ + continue; + } + if(regs->free_dest) { use_cost = 0; } + else if(regs->descs[0].value->in_global_register) + { + if(regs->descs[0].value == regs->descs[1].value) + { + use_cost = 0; + } + else if(regs->descs[0].value == regs->descs[2].value) + { + if(regs->commutative) + { + use_cost = 0; + } + else + { + continue; + } + } + else + { + use_cost = COST_COPY; + } + } else { - continue; + use_cost = COST_COPY; } } else @@ -1132,53 +1160,49 @@ choose_output_register(jit_gencode_t gen, _jit_regs_t *regs) { continue; } - if(regs->descs[0].value->has_global_register) + if(regs->free_dest) { - use_cost = COST_GLOBAL_BIAS; + use_cost = 0; } - else + else if(regs->descs[1].value + && regs->descs[1].value->in_register + && regs->descs[1].value->reg == reg) { use_cost = 0; } - } - - if(regs->free_dest) - { - /* noop */ - } - else if(regs->descs[1].value - && regs->descs[1].value->in_register - && regs->descs[1].value->reg == reg) - { - /* noop */ - } - else if(regs->descs[2].value - && regs->descs[2].value->in_register - && regs->descs[2].value->reg == reg) - { - if(regs->commutative || regs->x87_arith) + else if(regs->descs[2].value + && regs->descs[2].value->in_register + && regs->descs[2].value->reg == reg) { - /* noop */ + if(regs->commutative || regs->x87_arith) + { + use_cost = 0; + } + else + { + use_cost = COST_THRASH; + } } else { - use_cost += COST_THRASH; + use_cost = COST_COPY; + } + if(regs->descs[0].value->has_global_register) + { + use_cost += COST_GLOBAL_BIAS; } - } - else - { - use_cost += COST_COPY; } - spill_cost = compute_spill_cost(gen, regs, reg, other_reg); + use_cost += compute_spill_cost(gen, regs, reg, other_reg); - if((use_cost + spill_cost) < suitable_cost - || (spill_cost > 0 && (use_cost + spill_cost) == suitable_cost + if(use_cost < suitable_cost + || (use_cost == suitable_cost + && gen->contents[reg].num_values > 0 && gen->contents[reg].age < suitable_age)) { suitable_reg = reg; suitable_other_reg = other_reg; - suitable_cost = use_cost + spill_cost; + suitable_cost = use_cost; suitable_age = gen->contents[reg].age; } } @@ -1281,7 +1305,7 @@ choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index) _jit_regdesc_t *desc2; int type, need_pair; int reg, other_reg; - int use_cost, spill_cost; + int use_cost; int suitable_reg, suitable_other_reg; int suitable_cost; int suitable_age; @@ -1394,32 +1418,29 @@ choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index) if(jit_reg_is_used(regs->clobber, reg) || (other_reg >= 0 && jit_reg_is_used(regs->clobber, other_reg))) { - spill_cost = 0; + /* noop */ } else { - spill_cost = compute_spill_cost(gen, regs, reg, other_reg); + use_cost += compute_spill_cost(gen, regs, reg, other_reg); } #if ALLOW_CLOBBER_GLOBAL if(other_reg >= 0 && jit_reg_is_used(gen->permanent, other_reg)) { - spill_cost += COST_CLOBBER_GLOBAL; + use_cost += COST_CLOBBER_GLOBAL; } #endif } - else - { - spill_cost = 0; - } - if((use_cost + spill_cost) < suitable_cost - || (spill_cost > 0 && (use_cost + spill_cost) == suitable_cost + if(use_cost < suitable_cost + || (use_cost == suitable_cost + && gen->contents[reg].num_values > 0 && gen->contents[reg].age < suitable_age)) { /* This is the oldest suitable register of this type */ suitable_reg = reg; suitable_other_reg = other_reg; - suitable_cost = use_cost + spill_cost; + suitable_cost = use_cost; suitable_age = gen->contents[reg].age; } } diff --git a/jit/jit-rules-x86.ins b/jit/jit-rules-x86.ins index 3395d2b..f69d9f5 100644 --- a/jit/jit-rules-x86.ins +++ b/jit/jit-rules-x86.ins @@ -213,7 +213,7 @@ JIT_OP_FLOAT32_TO_NFLOAT, JIT_OP_FLOAT64_TO_NFLOAT: copy, stack * Arithmetic opcodes. */ -JIT_OP_IADD: binary +JIT_OP_IADD: commutative [reg, imm] -> { x86_alu_reg_imm(inst, X86_ADD, $1, $2); } @@ -235,7 +235,7 @@ JIT_OP_ISUB: binary x86_alu_reg_reg(inst, X86_SUB, $1, $2); } -JIT_OP_IMUL: binary +JIT_OP_IMUL: commutative [reg, imm] -> { /* Handle special cases of immediate multiplies */ switch($2) @@ -674,7 +674,7 @@ JIT_OP_INEG: unary x86_neg_reg(inst, $1); } -JIT_OP_LADD: binary +JIT_OP_LADD: commutative [lreg, imm] -> { jit_int value1 = ((jit_int *)($2))[0]; jit_int value2 = ((jit_int *)($2))[1]; @@ -788,7 +788,7 @@ JIT_OP_FNEG, JIT_OP_DNEG, JIT_OP_NFNEG: unary, stack * Bitwise opcodes. */ -JIT_OP_IAND: binary +JIT_OP_IAND: commutative [reg, imm] -> { x86_alu_reg_imm(inst, X86_AND, $1, $2); } @@ -799,7 +799,7 @@ JIT_OP_IAND: binary x86_alu_reg_reg(inst, X86_AND, $1, $2); } -JIT_OP_IOR: binary +JIT_OP_IOR: commutative [reg, imm] -> { x86_alu_reg_imm(inst, X86_OR, $1, $2); } @@ -810,7 +810,7 @@ JIT_OP_IOR: binary x86_alu_reg_reg(inst, X86_OR, $1, $2); } -JIT_OP_IXOR: binary +JIT_OP_IXOR: commutative [reg, imm] -> { x86_alu_reg_imm(inst, X86_XOR, $1, $2); } @@ -850,7 +850,7 @@ JIT_OP_ISHR_UN: binary inst = shift_reg(inst, X86_SHR, $1, $2); } -JIT_OP_LAND: binary +JIT_OP_LAND: commutative [lreg, imm] -> { jit_int value1 = ((jit_int *)($2))[0]; jit_int value2 = ((jit_int *)($2))[1]; @@ -866,7 +866,7 @@ JIT_OP_LAND: binary x86_alu_reg_reg(inst, X86_AND, %1, %2); } -JIT_OP_LOR: binary +JIT_OP_LOR: commutative [lreg, imm] -> { jit_int value1 = ((jit_int *)($2))[0]; jit_int value2 = ((jit_int *)($2))[1]; @@ -882,7 +882,7 @@ JIT_OP_LOR: binary x86_alu_reg_reg(inst, X86_OR, %1, %2); } -JIT_OP_LXOR: binary +JIT_OP_LXOR: commutative [lreg, imm] -> { jit_int value1 = ((jit_int *)($2))[0]; jit_int value2 = ((jit_int *)($2))[1]; -- 2.47.3