]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Optimize the x86 function epilog when we are certain that the
authorRhys Weatherley <rweather@southern-storm.com.au>
Fri, 11 Jun 2004 03:48:00 +0000 (03:48 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Fri, 11 Jun 2004 03:48:00 +0000 (03:48 +0000)
stack height doesn't change between entry and exit (i.e. the
function is a leaf and there are no alloca's).

ChangeLog
jit/jit-rules-x86.c
jit/jit-rules-x86.sel
jit/jit-rules.h

index 964f22005c643ed4520fe3e053dabc531bf718c1..201d0c2296a2953692ede1d4882f14a3f8be4d6f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        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  <rweather@southern-storm.com.au>
 
        * jit/jit-apply-arm.c, jit/jit-gen-arm.c, jit/jit-gen-arm.h,
index bbe9a607b176cf666a7ec27aa79ec6ba92e0f128..a5f210d64053a649e2d5f5f80e192a771b6c61f4 100644 (file)
@@ -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 */
index 3da10d6d2852da7839a610a0c6677cb7b541b22e..8a5adc86a47f9b01a98db75ceeab2688e89542cc 100644 (file)
@@ -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;
        }
index 3a70175a61cffc4174ad00a65a80628b10102b03..fad16009bd536e9e3d9b59abacf1797f20b50a0f 100644 (file)
@@ -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 */
 };
 
 /*