]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Don't over-allocate x86 stack frames if EBX, ESI, and EDI don't need to
authorRhys Weatherley <rweather@southern-storm.com.au>
Thu, 10 Jun 2004 03:06:07 +0000 (03:06 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Thu, 10 Jun 2004 03:06:07 +0000 (03:06 +0000)
be saved; don't perform global register allocation on stacked parameters
because it confuses the register spill logic.

ChangeLog
include/jit/jit-plus.h
include/jit/jit-value.h
jit/jit-insn.c
jit/jit-internal.h
jit/jit-reg-alloc.c
jit/jit-rules-x86.c
jit/jit-value.c

index 3fade0d756e0da822396b1b092be0141d79076c2..002bf3a8525359651d4bd4131e60492c44bfe37f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        the overhead of function calls that involve stacked arguments
        on non-x86 platforms; use parameter areas in the ARM back end.
 
+       * include/jit/jit-plus.h, include/jit/jit-value.h, jit/jit-insn.c,
+       jit/jit-internal.h, jit/jit-reg-alloc.c, jit/jit-rules-x86.c,
+       jit/jit-value.c: don't over-allocate x86 stack frames if
+       EBX, ESI, and EDI don't need to be saved; don't perform global
+       register allocation on stacked parameters because it confuses
+       the register spill logic.
+
 2004-06-09  Rhys Weatherley  <rweather@southern-storm.com.au>
 
        * jit/jit-rules-arm.c (flush_constants): update the instruction
index e6ad1a7f9945a910385d0ccd3a4823ba3c55a6e4..d8cb174857b86ad1e54125008e406f7af044b906 100644 (file)
@@ -42,6 +42,7 @@ public:
        int is_temporary() const { return jit_value_is_temporary(value); }
        int is_local() const { return jit_value_is_local(value); }
        int is_constant() const { return jit_value_is_constant(value); }
+       int is_parameter() const { return jit_value_is_parameter(value); }
 
        void set_volatile() { jit_value_set_volatile(value); }
        int is_volatile() const { return jit_value_is_volatile(value); }
index 81e7c560e3321d37cc1de2737f8a214f338407d0..9568a15a38b9d3a8a990879964dba975cfd45321 100644 (file)
@@ -75,6 +75,7 @@ jit_value_t jit_value_get_struct_pointer(jit_function_t func) JIT_NOTHROW;
 int jit_value_is_temporary(jit_value_t value) JIT_NOTHROW;
 int jit_value_is_local(jit_value_t value) JIT_NOTHROW;
 int jit_value_is_constant(jit_value_t value) JIT_NOTHROW;
+int jit_value_is_parameter(jit_value_t value) JIT_NOTHROW;
 void jit_value_ref(jit_function_t func, jit_value_t value) JIT_NOTHROW;
 void jit_value_set_volatile(jit_value_t value) JIT_NOTHROW;
 int jit_value_is_volatile(jit_value_t value) JIT_NOTHROW;
index 46235ec1aa927b0488cc4e9708da97a851e1e4bd..19f56baec88f192108e5b02ec1100fb1dce75151 100644 (file)
@@ -5685,6 +5685,10 @@ jit_value_t jit_insn_call_intrinsic
 @*/
 int jit_insn_incoming_reg(jit_function_t func, jit_value_t value, int reg)
 {
+       if(value && value->is_parameter)
+       {
+               value->is_reg_parameter = 1;
+       }
        return create_note(func, JIT_OP_INCOMING_REG, value,
                                           jit_value_create_nint_constant
                                                        (func, jit_type_int, (jit_nint)reg));
index db56d07ef714b01b112fe47aba45f2b5c6c3d5a6..8ec50ca33bc251f4879a6096385487539041d5dd 100644 (file)
@@ -201,6 +201,8 @@ struct _jit_value
        int                                     is_addressable : 1;
        int                                     is_constant : 1;
        int                                     is_nint_constant : 1;
+       int                                     is_parameter : 1;
+       int                                     is_reg_parameter : 1;
        int                                     has_address : 1;
        int                                     free_address : 1;
        int                                     in_register : 1;
index 465cf556bb415d6493829f2ba95d644b0b9e7656..75011901576f699837e0ea85f51a85032c45f2de 100644 (file)
@@ -1460,7 +1460,8 @@ void _jit_regs_alloc_global(jit_gencode_t gen, jit_function_t func)
                        value = (jit_value_t)(block->data + posn *
                                                                  sizeof(struct _jit_value));
                        if(value->global_candidate && value->usage_count >= JIT_MIN_USED &&
-                          !(value->is_addressable) && !(value->is_volatile))
+                          !(value->is_addressable) && !(value->is_volatile) &&
+                          (!(value->is_parameter) || value->is_reg_parameter))
                        {
                                /* Insert this candidate into the list, ordered on count */
                                index = 0;
index 435723a91e856e7264a28959a4bf78fc589dfe4e..3a09e832edfd492cdd71e7af16eedbfee3c00a7a 100644 (file)
@@ -163,9 +163,8 @@ int _jit_create_entry_insns(jit_function_t func)
        unsigned int size;
        unsigned int num_stack_words;
 
-       /* Reset the frame size for this function.  We start by assuming
-          that ESI, EDI, and EBX need to be saved in the local frame */
-       func->builder->frame_size = 3 * sizeof(void *);
+       /* Reset the local variable frame size for this function */
+       func->builder->frame_size = 0;
 
        /* Determine the number of registers to allocate to parameters */
 #if JIT_APPLY_X86_FASTCALL == 1
@@ -690,7 +689,6 @@ void *_jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf)
        unsigned char prolog[JIT_PROLOG_SIZE];
        unsigned char *inst = prolog;
        int reg;
-       unsigned int saved;
 
        /* Push ebp onto the stack */
        x86_push_reg(inst, X86_EBP);
@@ -698,26 +696,23 @@ void *_jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf)
        /* Initialize EBP for the current frame */
        x86_mov_reg_reg(inst, X86_EBP, X86_ESP, sizeof(void *));
 
+       /* Allocate space for the local variable frame */
+       if(func->builder->frame_size > 0)
+       {
+               x86_alu_reg_imm(inst, X86_SUB, X86_ESP,
+                                               (int)(func->builder->frame_size));
+       }
+
        /* Save registers that we need to preserve */
-       saved = 0;
        for(reg = 0; reg <= 7; ++reg)
        {
                if(jit_reg_is_used(gen->touched, reg) &&
                   (_jit_reg_info[reg].flags & JIT_REG_CALL_USED) == 0)
                {
                        x86_push_reg(inst, _jit_reg_info[reg].cpu_reg);
-                       saved += sizeof(void *);
                }
        }
 
-       /* Allocate space for the local variable frame.  Subtract off
-          the space for the registers that we just saved */
-       if((func->builder->frame_size - saved) > 0)
-       {
-               x86_alu_reg_imm(inst, X86_SUB, X86_ESP,
-                                               (int)(func->builder->frame_size - saved));
-       }
-
        /* Copy the prolog into place and return the adjusted entry position */
        reg = (int)(inst - prolog);
        jit_memcpy(((unsigned char *)buf) + JIT_PROLOG_SIZE - reg, prolog, reg);
@@ -727,14 +722,14 @@ void *_jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf)
 void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func)
 {
        jit_nint pop_bytes = 0;
-       int num_regs, reg;
+       int reg, offset;
        unsigned char *inst;
        int struct_return_offset = 0;
        void **fixup;
        void **next;
 
        /* Bail out if there is insufficient space for the epilog */
-       if(!jit_cache_check_for_n(&(gen->posn), 32))
+       if(!jit_cache_check_for_n(&(gen->posn), 48))
        {
                jit_cache_mark_full(&(gen->posn));
                return;
@@ -823,38 +818,21 @@ void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func)
                x86_mov_reg_membase(inst, X86_EAX, X86_EBP, struct_return_offset, 4);
        }
 
-       /* Determine the number of callee save registers on the stack */
-       num_regs = 0;
-       for(reg = 7; reg >= 0; --reg)
-       {
-               if(jit_reg_is_used(gen->touched, reg) &&
-                  (_jit_reg_info[reg].flags & JIT_REG_CALL_USED) == 0)
-               {
-                       ++num_regs;
-               }
-       }
-
-       /* Pop the local stack frame, and get back to the callee save regs */
-       if(num_regs == 0)
-       {
-               x86_mov_reg_reg(inst, X86_ESP, X86_EBP, sizeof(void *));
-       }
-       else
-       {
-               x86_lea_membase(inst, X86_ESP, X86_EBP, -(sizeof(void *) * num_regs));
-       }
-
-       /* Pop the callee save registers that we used */
-       for(reg = 7; reg >= 0; --reg)
+       /* Restore the callee save registers that we used */
+       offset = -(func->builder->frame_size);
+       for(reg = 0; reg <= 7; ++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);
+                       offset -= sizeof(void *);
+                       x86_mov_reg_membase(inst, _jit_reg_info[reg].cpu_reg,
+                                                               X86_EBP, offset, sizeof(void *));
                }
        }
 
-       /* Pop the saved copy of ebp */
+       /* Pop the stack frame and restore the saved copy of ebp */
+       x86_mov_reg_reg(inst, X86_ESP, X86_EBP, sizeof(void *));
        x86_pop_reg(inst, X86_EBP);
 
        /* Return from the current function */
index 1e4852bcc7e856e3200ed44b2db1858ca39563f4..f5c1d866fea02fe3a963393a59c39282ab396ddf 100644 (file)
@@ -505,6 +505,7 @@ jit_value_t jit_value_get_param(jit_function_t func, unsigned int param)
                        /* The value belongs to the entry block, no matter
                           where it happens to be created */
                        values[current]->block = func->builder->entry;
+                       values[current]->is_parameter = 1;
                }
        }
 
@@ -546,6 +547,7 @@ jit_value_t jit_value_get_struct_pointer(jit_function_t func)
                                        /* The value belongs to the entry block, no matter
                                           where it happens to be created */
                                        value->block = func->builder->entry;
+                                       value->is_parameter = 1;
                                }
                                jit_type_free(type);
                        }
@@ -587,6 +589,16 @@ int jit_value_is_constant(jit_value_t value)
        return value->is_constant;
 }
 
+/*@
+ * @deftypefun int jit_value_is_parameter (jit_value_t value)
+ * Determine if a value is a function parameter.
+ * @end deftypefun
+@*/
+int jit_value_is_parameter(jit_value_t value)
+{
+       return value->is_parameter;
+}
+
 /*@
  * @deftypefun void jit_value_ref (jit_function_t func, jit_value_t value)
  * Create a reference to the specified @code{value} from the current