[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[dotgnu-pnet-commits] libjit ChangeLog jit/jit-function.c jit/jit-reg...
From: |
Aleksey Demakov |
Subject: |
[dotgnu-pnet-commits] libjit ChangeLog jit/jit-function.c jit/jit-reg... |
Date: |
Sun, 11 Feb 2007 23:28:44 +0000 |
CVSROOT: /sources/dotgnu-pnet
Module name: libjit
Changes by: Aleksey Demakov <avd> 07/02/11 23:28:44
Modified files:
. : ChangeLog
jit : jit-function.c jit-reg-alloc.h jit-reg-alloc.c
Log message:
more correctly handle compilation restart
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/libjit/ChangeLog?cvsroot=dotgnu-pnet&r1=1.302&r2=1.303
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-function.c?cvsroot=dotgnu-pnet&r1=1.28&r2=1.29
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-reg-alloc.h?cvsroot=dotgnu-pnet&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-reg-alloc.c?cvsroot=dotgnu-pnet&r1=1.52&r2=1.53
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/ChangeLog,v
retrieving revision 1.302
retrieving revision 1.303
diff -u -b -r1.302 -r1.303
--- ChangeLog 11 Feb 2007 22:54:25 -0000 1.302
+++ ChangeLog 11 Feb 2007 23:28:44 -0000 1.303
@@ -3,6 +3,18 @@
* jit/jit-dump.c (jit_dump_function): flush the output stream upon
dumping the function.
+ * jit/jit-function.c (cleanup_on_restart, reset_value): add new
+ functions to clean up the compilation state on restart.
+ (compile): replace the code that did cleanup on restart with a call
+ to cleanup_on_restart() which does this job more thoroughly.
+
+ * jit/jit-reg-alloc.h, jit/jit-reg-alloc.c: remove _jit_regs_abort()
+ function as the new cleanup-on-restart code makes it superflows.
+
+ * jit/jit-reg-alloc.c (is_register_occupied): add new function;
+ (clobbers_register, spill_clobbered_register, _jit_regs_gen): fix
+ a problem that shows up with the new cleanup method.
+
2007-02-10 Klaus Treichel <address@hidden>
* jit/jit-function.c: Use the on-demand compilation driver in
Index: jit/jit-function.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-function.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -b -r1.28 -r1.29
--- jit/jit-function.c 10 Feb 2007 19:12:29 -0000 1.28
+++ jit/jit-function.c 11 Feb 2007 23:28:44 -0000 1.29
@@ -625,6 +625,85 @@
}
/*
+ * Reset value on restart.
+ */
+static void
+reset_value(jit_value_t value)
+{
+ value->reg = -1;
+ value->in_register = 0;
+ value->in_global_register = 0;
+ value->in_frame = 0;
+}
+
+/*
+ * Clean up the compilation state on restart.
+ */
+static void
+cleanup_on_restart(jit_gencode_t gen, jit_function_t func)
+{
+ jit_block_t block;
+ jit_insn_iter_t iter;
+ jit_insn_t insn;
+
+#ifdef _JIT_COMPILE_DEBUG
+ printf("\n*** Restart compilation ***\n\n");
+#endif
+
+ block = 0;
+ while((block = jit_block_next(func, block)) != 0)
+ {
+ /* Clear the block addresses and fixup lists */
+ block->address = 0;
+ block->fixup_list = 0;
+ block->fixup_absolute_list = 0;
+
+ /* Reset values referred to by block instructions */
+ jit_insn_iter_init(&iter, block);
+ while((insn = jit_insn_iter_next(&iter)) != 0)
+ {
+ if(insn->dest && (insn->flags &
JIT_INSN_DEST_OTHER_FLAGS) == 0)
+ {
+ reset_value(insn->dest);
+ }
+ if(insn->value1 && (insn->flags &
JIT_INSN_VALUE1_OTHER_FLAGS) == 0)
+ {
+ reset_value(insn->value1);
+ }
+ if(insn->value2 && (insn->flags &
JIT_INSN_VALUE2_OTHER_FLAGS) == 0)
+ {
+ reset_value(insn->value2);
+ }
+ }
+ }
+
+ /* Reset values referred to by builder */
+ if(func->builder->setjmp_value)
+ {
+ reset_value(func->builder->setjmp_value);
+ }
+ if(func->builder->parent_frame)
+ {
+ reset_value(func->builder->parent_frame);
+ }
+
+ /* Reset the "touched" registers mask. The first time compilation
+ might have followed wrong code paths and thus allocated wrong
+ registers. */
+ if(func->builder->has_tail_call)
+ {
+ /* For functions with tail calls _jit_regs_alloc_global()
+ does not allocate any global registers. The "permanent"
+ mask has all global registers set to prevent their use. */
+ gen->touched = jit_regused_init;
+ }
+ else
+ {
+ gen->touched = gen->permanent;
+ }
+}
+
+/*
* Compile a function and return its entry point.
*/
static int
@@ -764,17 +843,11 @@
/* End the function's output process */
result = _jit_cache_end_method(&(gen.posn));
- /* If we need to restart on a different cache page, then clear
- the block addresses and fixup lists */
+ /* If we need to restart on a different cache page, then clean
up
+ the compilation state */
if(result == JIT_CACHE_END_RESTART)
{
- block = 0;
- while((block = jit_block_next(func, block)) != 0)
- {
- block->address = 0;
- block->fixup_list = 0;
- block->fixup_absolute_list = 0;
- }
+ cleanup_on_restart(&gen, func);
}
}
while(result == JIT_CACHE_END_RESTART);
Index: jit/jit-reg-alloc.h
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-reg-alloc.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- jit/jit-reg-alloc.h 17 Jan 2007 07:38:47 -0000 1.21
+++ jit/jit-reg-alloc.h 11 Feb 2007 23:28:44 -0000 1.22
@@ -175,7 +175,6 @@
int _jit_regs_select(_jit_regs_t *regs);
#endif
void _jit_regs_commit(jit_gencode_t gen, _jit_regs_t *regs);
-void _jit_regs_abort(jit_gencode_t gen, _jit_regs_t *regs);
int _jit_regs_get_dest(_jit_regs_t *regs);
int _jit_regs_get_value1(_jit_regs_t *regs);
Index: jit/jit-reg-alloc.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-reg-alloc.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -b -r1.52 -r1.53
--- jit/jit-reg-alloc.c 28 Jan 2007 20:14:57 -0000 1.52
+++ jit/jit-reg-alloc.c 11 Feb 2007 23:28:44 -0000 1.53
@@ -88,6 +88,8 @@
#define CLOBBER_OTHER_REG 4
#ifdef JIT_REG_DEBUG
+#include <stdlib.h>
+
static void dump_regs(jit_gencode_t gen, const char *name)
{
int reg, index;
@@ -208,6 +210,9 @@
return 0;
}
+/*
+ * Exchange the content of two value descriptors.
+ */
static void
swap_values(_jit_regdesc_t *desc1, _jit_regdesc_t *desc2)
{
@@ -367,6 +372,44 @@
}
/*
+ * Check if the register contains any values either dead or alive
+ * that may need to be evicted from it.
+ */
+static int
+is_register_occupied(jit_gencode_t gen, _jit_regs_t *regs, int reg)
+{
+ if(reg < 0)
+ {
+ return 0;
+ }
+
+ /* Assume that a global register is always alive unless it is to be
+ computed right away. */
+ if(jit_reg_is_used(gen->permanent, reg))
+ {
+ if(!regs->ternary
+ && regs->descs[0].value
+ && regs->descs[0].value->has_global_register
+ && regs->descs[0].value->global_reg == reg)
+ {
+ return 0;
+ }
+ return 1;
+ }
+
+ if(gen->contents[reg].is_long_end)
+ {
+ reg = get_long_pair_start(reg);
+ }
+ if(gen->contents[reg].num_values)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
* Determine the effect of using a register for a value. This includes the
* following:
* - whether the value is clobbered by the instruction;
@@ -439,11 +482,11 @@
}
flags = CLOBBER_NONE;
- if(is_register_alive(gen, regs, reg))
+ if(is_register_occupied(gen, regs, reg))
{
flags |= CLOBBER_REG;
}
- if(is_register_alive(gen, regs, other_reg))
+ if(is_register_occupied(gen, regs, other_reg))
{
flags |= CLOBBER_OTHER_REG;
}
@@ -492,11 +535,11 @@
}
}
- if(is_register_alive(gen, regs, reg))
+ if(is_register_occupied(gen, regs, reg))
{
flags |= CLOBBER_REG;
}
- if(is_register_alive(gen, regs, other_reg))
+ if(is_register_occupied(gen, regs, other_reg))
{
flags |= CLOBBER_OTHER_REG;
}
@@ -1729,6 +1772,14 @@
still_in_frame = 0;
}
+#ifdef JIT_REG_DEBUG
+ if(gen->contents[reg].num_values == JIT_MAX_REG_VALUES)
+ {
+ printf("*** Too many values for one register! ***\n");
+ abort();
+ }
+#endif
+
gen->contents[reg].values[gen->contents[reg].num_values] = value;
++(gen->contents[reg].num_values);
gen->contents[reg].age = gen->current_age;
@@ -2073,6 +2124,77 @@
printf("spill_clobbered_register(reg = %d)\n", reg);
#endif
+#ifdef JIT_REG_STACK
+ /* For a stack register spill it in two passes. First drop values that
+ reqiure neither spilling nor a generation of the free instruction.
+ Then lazily exchange the register with the top and spill or free it
+ as necessary. This approach might save a exch/free instructions in
+ certain cases. */
+ if(IS_STACK_REG(reg))
+ {
+ for(index = gen->contents[reg].num_values - 1; index >= 0;
--index)
+ {
+ if(gen->contents[reg].num_values == 1)
+ {
+ break;
+ }
+
+ value = gen->contents[reg].values[index];
+ usage = value_usage(regs, value);
+ if((usage & VALUE_INPUT) != 0)
+ {
+ continue;
+ }
+ if((usage & VALUE_DEAD) != 0 || value->in_frame)
+ {
+ unbind_value(gen, value, reg, -1);
+ }
+ }
+ for(index = gen->contents[reg].num_values - 1; index >= 0;
--index)
+ {
+ int top;
+
+ value = gen->contents[reg].values[index];
+ usage = value_usage(regs, value);
+ if((usage & VALUE_INPUT) != 0)
+ {
+ if((usage & VALUE_DEAD) != 0 || value->in_frame)
+ {
+ continue;
+ }
+
+ top = gen->reg_stack_top - 1;
+ if(reg != top)
+ {
+ exch_stack_top(gen, reg, 0);
+ reg = top;
+ }
+
+ save_value(gen, value, reg, -1, 0);
+ }
+ else
+ {
+ top = gen->reg_stack_top - 1;
+ if(reg != top)
+ {
+ exch_stack_top(gen, reg, 0);
+ reg = top;
+ }
+
+ if((usage & VALUE_DEAD) != 0 || value->in_frame)
+ {
+ free_value(gen, value, reg, -1, 0);
+ }
+ else
+ {
+ save_value(gen, value, reg, -1, 1);
+ }
+ }
+ }
+ }
+ else
+#endif
+ {
/* Find the other register in a long pair */
if(gen->contents[reg].is_long_start)
{
@@ -2088,24 +2210,6 @@
other_reg = -1;
}
- /* Spill register contents in two passes. First free values that
- do not reqiure spilling then spill those that do. This approach
- is only useful in case a stack register contains both kinds of
- values and the last value is one that does not require spilling.
- This way we may save one free instruction. */
- if(IS_STACK_REG(reg))
- {
- for(index = gen->contents[reg].num_values - 1; index >= 0;
--index)
- {
- value = gen->contents[reg].values[index];
- usage = value_usage(regs, value);
- if((usage & VALUE_INPUT) == 0
- && ((usage & VALUE_DEAD) != 0 || value->in_frame))
- {
- free_value(gen, value, reg, other_reg, 0);
- }
- }
- }
for(index = gen->contents[reg].num_values - 1; index >= 0; --index)
{
value = gen->contents[reg].values[index];
@@ -2129,6 +2233,7 @@
}
}
}
+ }
}
static void
@@ -2352,43 +2457,6 @@
}
#endif
-static void
-abort_input_value(jit_gencode_t gen, _jit_regs_t *regs, int index)
-{
- _jit_regdesc_t *desc;
- int reg, other_reg;
-
-#ifdef JIT_REG_DEBUG
- printf("abort_input_value(%d)\n", index);
-#endif
-
- desc = ®s->descs[index];
- if(!desc->value || desc->duplicate)
- {
- return;
- }
-
- if(desc->load && desc->value->in_register)
- {
- reg = desc->value->reg;
- if(gen->contents[reg].is_long_start)
- {
- other_reg = OTHER_REG(reg);
- }
- else
- {
- other_reg = -1;
- }
- unbind_value(gen, desc->value, reg, other_reg);
-#ifdef JIT_REG_STACK
- if(IS_STACK_REG(reg))
- {
- --(gen->reg_stack_top);
- }
-#endif
- }
-}
-
#ifdef JIT_REG_STACK
static void
pop_input_value(jit_gencode_t gen, _jit_regs_t *regs, int index)
@@ -3437,28 +3505,20 @@
if(IS_STACK_REG(reg))
{
int top = gen->reg_stack_top - 1;
-
/* spill top registers if there are any that needs to
be */
- for(; top > reg && jit_reg_is_used(regs->clobber, top);
top--)
+ for(; top >= reg && jit_reg_is_used(regs->clobber,
top); top--)
{
spill_clobbered_register(gen, regs, top);
/* If an input value is on the top then it
stays there
- and the top does not change. */
+ and the top position does not change. */
if(gen->contents[top].num_values > 0)
{
break;
}
}
- /* If the top register was not spilled then exchange it
with
- the current register. */
if(top > reg)
{
- exch_stack_top(gen, reg, 0);
- }
- /* Finally spill the register */
- if(top >= JIT_REG_STACK_START)
- {
- spill_clobbered_register(gen, regs, top);
+ spill_clobbered_register(gen, regs, reg);
}
}
else
@@ -3694,17 +3754,6 @@
#endif
}
-void
-_jit_regs_abort(jit_gencode_t gen, _jit_regs_t *regs)
-{
- abort_input_value(gen, regs, 2);
- abort_input_value(gen, regs, 1);
- if(regs->ternary)
- {
- abort_input_value(gen, regs, 0);
- }
-}
-
unsigned char *
_jit_regs_inst_ptr(jit_gencode_t gen, int space)
{
@@ -3723,8 +3772,6 @@
unsigned char *
_jit_regs_begin(jit_gencode_t gen, _jit_regs_t *regs, int space)
{
- unsigned char *inst;
-
if(!_jit_regs_assign(gen, regs))
{
return 0;
@@ -3734,13 +3781,7 @@
return 0;
}
- inst = _jit_regs_inst_ptr(gen, space);
- if(!inst)
- {
- _jit_regs_abort(gen, regs);
- }
-
- return inst;
+ return _jit_regs_inst_ptr(gen, space);
}
void
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [dotgnu-pnet-commits] libjit ChangeLog jit/jit-function.c jit/jit-reg...,
Aleksey Demakov <=