From: Rhys Weatherley Date: Fri, 11 Jun 2004 03:48:00 +0000 (+0000) Subject: Optimize the x86 function epilog when we are certain that the X-Git-Tag: r.0.0.4~17 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=4b1a2d8f4c86b27e2adc9768e9ed352d2ce6551e;p=francis%2Flibjit.git Optimize the x86 function epilog when we are certain that the stack height doesn't change between entry and exit (i.e. the function is a leaf and there are no alloca's). --- diff --git a/ChangeLog b/ChangeLog index 964f220..201d0c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,11 @@ jit/jit-rules-interp.c, jit/jit-rules-x86.c, jit/jit-rules.h: implement global register allocation for parameters in stack slots. + * jit/jit-rules-x86.c, jit/jit-rules-x86.sel, jit/jit-rules.h: + optimize the x86 function epilog when we are certain that the + stack height doesn't change between entry and exit (i.e. the + function is a leaf and there are no alloca's). + 2004-06-10 Rhys Weatherley * jit/jit-apply-arm.c, jit/jit-gen-arm.c, jit/jit-gen-arm.h, diff --git a/jit/jit-rules-x86.c b/jit/jit-rules-x86.c index bbe9a60..a5f210d 100644 --- a/jit/jit-rules-x86.c +++ b/jit/jit-rules-x86.c @@ -819,20 +819,37 @@ void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func) } /* Restore the callee save registers that we used */ - offset = -(func->builder->frame_size); - for(reg = 0; reg <= 7; ++reg) + if(gen->stack_changed) { - if(jit_reg_is_used(gen->touched, reg) && - (_jit_reg_info[reg].flags & JIT_REG_CALL_USED) == 0) + offset = -(func->builder->frame_size); + for(reg = 0; reg <= 7; ++reg) { - offset -= sizeof(void *); - x86_mov_reg_membase(inst, _jit_reg_info[reg].cpu_reg, - X86_EBP, offset, sizeof(void *)); + if(jit_reg_is_used(gen->touched, reg) && + (_jit_reg_info[reg].flags & JIT_REG_CALL_USED) == 0) + { + offset -= sizeof(void *); + x86_mov_reg_membase(inst, _jit_reg_info[reg].cpu_reg, + X86_EBP, offset, sizeof(void *)); + } + } + } + else + { + for(reg = 7; reg >= 0; --reg) + { + if(jit_reg_is_used(gen->touched, reg) && + (_jit_reg_info[reg].flags & JIT_REG_CALL_USED) == 0) + { + x86_pop_reg(inst, _jit_reg_info[reg].cpu_reg); + } } } /* Pop the stack frame and restore the saved copy of ebp */ - x86_mov_reg_reg(inst, X86_ESP, X86_EBP, sizeof(void *)); + if(gen->stack_changed || func->builder->frame_size > 0) + { + x86_mov_reg_reg(inst, X86_ESP, X86_EBP, sizeof(void *)); + } x86_pop_reg(inst, X86_EBP); /* Return from the current function */ diff --git a/jit/jit-rules-x86.sel b/jit/jit-rules-x86.sel index 3da10d6..8a5adc8 100644 --- a/jit/jit-rules-x86.sel +++ b/jit/jit-rules-x86.sel @@ -1708,12 +1708,15 @@ JIT_OP_RETURN_REG: manual JIT_OP_PUSH_INT: unary_note [imm] -> { x86_push_imm(inst, $1); + gen->stack_changed = 1; } [local] -> { x86_push_membase(inst, X86_EBP, $1); + gen->stack_changed = 1; } [reg] -> { x86_push_reg(inst, $1); + gen->stack_changed = 1; } JIT_OP_PUSH_LONG: spill_before @@ -1732,20 +1735,24 @@ JIT_OP_PUSH_LONG: spill_before x86_push_membase(inst, X86_EBP, offset + 4); x86_push_membase(inst, X86_EBP, offset); } + gen->stack_changed = 1; } JIT_OP_PUSH_FLOAT32: unary_note, stack [imm] -> { jit_int *ptr = (jit_int *)($1); x86_push_imm(inst, ptr[0]); + gen->stack_changed = 1; } [local] -> { x86_push_membase(inst, X86_EBP, $1); + gen->stack_changed = 1; } [reg] -> { x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float32)); x86_fst_membase(inst, X86_ESP, 0, 0, 1); _jit_regs_free_reg(gen, reg, 1); + gen->stack_changed = 1; } JIT_OP_PUSH_FLOAT64: unary_note, stack @@ -1753,15 +1760,18 @@ JIT_OP_PUSH_FLOAT64: unary_note, stack jit_int *ptr = (jit_int *)($1); x86_push_imm(inst, ptr[1]); x86_push_imm(inst, ptr[0]); + gen->stack_changed = 1; } [local] -> { x86_push_membase(inst, X86_EBP, $1 + 4); x86_push_membase(inst, X86_EBP, $1); + gen->stack_changed = 1; } [reg] -> { x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float64)); x86_fst_membase(inst, X86_ESP, 0, 1, 1); _jit_regs_free_reg(gen, reg, 1); + gen->stack_changed = 1; } JIT_OP_PUSH_NFLOAT: unary_note, stack @@ -1773,6 +1783,7 @@ JIT_OP_PUSH_NFLOAT: unary_note, stack } x86_push_imm(inst, ptr[1]); x86_push_imm(inst, ptr[0]); + gen->stack_changed = 1; } [local] -> { if(sizeof(jit_nfloat) != sizeof(jit_float64)) @@ -1781,6 +1792,7 @@ JIT_OP_PUSH_NFLOAT: unary_note, stack } x86_push_membase(inst, X86_EBP, $1 + 4); x86_push_membase(inst, X86_EBP, $1); + gen->stack_changed = 1; } [freg] -> { if(sizeof(jit_nfloat) != sizeof(jit_float64)) @@ -1794,17 +1806,20 @@ JIT_OP_PUSH_NFLOAT: unary_note, stack x86_fst_membase(inst, X86_ESP, 0, 1, 1); } _jit_regs_free_reg(gen, reg, 1); + gen->stack_changed = 1; } JIT_OP_PUSH_STRUCT: unary_note [reg] -> { /* TODO */ TODO(); + gen->stack_changed = 1; } JIT_OP_POP_STACK: [] -> { x86_alu_reg_imm(inst, X86_ADD, X86_ESP, insn->value1->address); + gen->stack_changed = 1; } JIT_OP_FLUSH_SMALL_STRUCT: @@ -2451,4 +2466,5 @@ JIT_OP_ALLOCA: unary x86_alu_reg_imm(inst, X86_AND, $1, ~15); x86_alu_reg_reg(inst, X86_SUB, X86_ESP, $1); x86_mov_reg_reg(inst, $1, X86_ESP, 4); + gen->stack_changed = 1; } diff --git a/jit/jit-rules.h b/jit/jit-rules.h index 3a70175..fad1600 100644 --- a/jit/jit-rules.h +++ b/jit/jit-rules.h @@ -147,6 +147,7 @@ struct jit_gencode jit_extra_gen_state; /* CPU-specific extra information */ #endif void *epilog_fixup; /* Fixup list for function epilogs */ + int stack_changed; /* Stack top changed since entry */ }; /*