[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[dotgnu-pnet-commits] libjit ChangeLog include/jit/jit-block.h jit/ji...
From: |
Aleksey Demakov |
Subject: |
[dotgnu-pnet-commits] libjit ChangeLog include/jit/jit-block.h jit/ji... |
Date: |
Sat, 09 May 2009 21:54:33 +0000 |
CVSROOT: /sources/dotgnu-pnet
Module name: libjit
Changes by: Aleksey Demakov <avd> 09/05/09 21:54:33
Modified files:
. : ChangeLog
include/jit : jit-block.h
jit : jit-block.c jit-dump.c jit-function.c
jit-insn.c jit-internal.h
Log message:
allow multiple labels for single block
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/libjit/ChangeLog?cvsroot=dotgnu-pnet&r1=1.430&r2=1.431
http://cvs.savannah.gnu.org/viewcvs/libjit/include/jit/jit-block.h?cvsroot=dotgnu-pnet&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-block.c?cvsroot=dotgnu-pnet&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-dump.c?cvsroot=dotgnu-pnet&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-function.c?cvsroot=dotgnu-pnet&r1=1.42&r2=1.43
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-insn.c?cvsroot=dotgnu-pnet&r1=1.69&r2=1.70
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-internal.h?cvsroot=dotgnu-pnet&r1=1.35&r2=1.36
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/ChangeLog,v
retrieving revision 1.430
retrieving revision 1.431
diff -u -b -r1.430 -r1.431
--- ChangeLog 8 May 2009 23:33:41 -0000 1.430
+++ ChangeLog 9 May 2009 21:54:31 -0000 1.431
@@ -1,3 +1,16 @@
+2009-05-10 Aleksey Demakov <address@hidden>
+
+ * jit/jit-internal.h (struct _jit_label_info): add srtuct.
+ (struct _jit_builder): replace label_blocks with label_info.
+
+ * jit/jit-block.c (_jit_block_record_label):
+ * jit/jit-dump.c (jit_dump_function):
+ * jit/jit-insn.c (jit_insn_label): allow more than one label per
+ basic block.
+
+ * include/jit/jit-block.h:
+ * jit/jit-block.c (jit_block_get_next_label): add function.
+
2009-05-09 Aleksey Demakov <address@hidden>
* jit/jit-internal.h, jit/jit-block.c, jit/jit-insn.c,
Index: include/jit/jit-block.h
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/include/jit/jit-block.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- include/jit/jit-block.h 24 Jan 2008 20:12:49 -0000 1.5
+++ include/jit/jit-block.h 9 May 2009 21:54:32 -0000 1.6
@@ -30,12 +30,14 @@
jit_function_t jit_block_get_function(jit_block_t block) JIT_NOTHROW;
jit_context_t jit_block_get_context(jit_block_t block) JIT_NOTHROW;
jit_label_t jit_block_get_label(jit_block_t block) JIT_NOTHROW;
-jit_block_t jit_block_next
- (jit_function_t func, jit_block_t previous) JIT_NOTHROW;
-jit_block_t jit_block_previous
- (jit_function_t func, jit_block_t previous) JIT_NOTHROW;
-jit_block_t jit_block_from_label
- (jit_function_t func, jit_label_t label) JIT_NOTHROW;
+jit_label_t jit_block_get_next_label(jit_block_t block,
+ jit_label_t label) JIT_NOTHROW;
+jit_block_t jit_block_next(jit_function_t func,
+ jit_block_t previous) JIT_NOTHROW;
+jit_block_t jit_block_previous(jit_function_t func,
+ jit_block_t previous) JIT_NOTHROW;
+jit_block_t jit_block_from_label(jit_function_t func,
+ jit_label_t label) JIT_NOTHROW;
int jit_block_set_meta(jit_block_t block, int type, void *data,
jit_meta_free_func free_data)
JIT_NOTHROW;
void *jit_block_get_meta(jit_block_t block, int type) JIT_NOTHROW;
Index: jit/jit-block.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-block.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- jit/jit-block.c 8 May 2009 23:33:41 -0000 1.12
+++ jit/jit-block.c 9 May 2009 21:54:32 -0000 1.13
@@ -36,51 +36,6 @@
int index;
} _jit_block_stack_entry_t;
-static jit_block_t
-create_block(jit_function_t func)
-{
- jit_block_t block;
-
- /* Allocate memory for the block */
- block = jit_cnew(struct _jit_block);
- if(!block)
- {
- return 0;
- }
-
- /* Initialize the block */
- block->func = func;
- block->label = jit_label_undefined;
-
- return block;
-}
-
-static void
-free_block(jit_block_t block)
-{
- jit_meta_destroy(&block->meta);
- jit_free(block->succs);
- jit_free(block->preds);
- jit_free(block->insns);
- jit_free(block);
-}
-
-/* Block may not be deleted right when it was found useless from
- the control flow perspective as it might be referenced from
- elsewhere, for instance, from some jit_value_t */
-static void
-delete_block(jit_block_t block)
-{
- jit_free(block->succs);
- block->succs = 0;
- jit_free(block->preds);
- block->preds = 0;
- jit_free(block->insns);
- block->insns = 0;
-
- block->next = block->func->builder->deleted_blocks;
- block->func->builder->deleted_blocks = block->next;
-}
static int
create_edge(jit_function_t func, jit_block_t src, jit_block_t dst, int flags,
int create)
@@ -332,6 +287,32 @@
return 1;
}
+/* Delete edge along with references to it */
+static void
+delete_edge(jit_function_t func, _jit_edge_t edge)
+{
+ detach_edge_src(edge);
+ detach_edge_dst(edge);
+ jit_memory_pool_dealloc(&func->builder->edge_pool, edge);
+}
+
+/* Block may not be deleted right when it was found useless from
+ the control flow perspective as it might be referenced from
+ elsewhere, for instance, from some jit_value_t */
+static void
+delete_block(jit_block_t block)
+{
+ jit_free(block->succs);
+ block->succs = 0;
+ jit_free(block->preds);
+ block->preds = 0;
+ jit_free(block->insns);
+ block->insns = 0;
+
+ block->next = block->func->builder->deleted_blocks;
+ block->func->builder->deleted_blocks = block->next;
+}
+
/* The block is empty if it contains nothing apart from an unconditional
branch */
static int
is_empty_block(jit_block_t block)
@@ -352,6 +333,23 @@
return 1;
}
+static void
+merge_labels(jit_function_t func, jit_block_t block, jit_label_t label)
+{
+ _jit_label_info_t *info;
+ jit_label_t alias;
+
+ while(label != jit_label_undefined)
+ {
+ info = &func->builder->label_info[label];
+ alias = info->alias;
+ info->block = block;
+ info->alias = block->label;
+ block->label = label;
+ label = alias;
+ }
+}
+
/* Merge empty block with its successor */
static int
merge_empty(jit_function_t func, jit_block_t block, int *changed)
@@ -364,23 +362,8 @@
succ_edge = block->succs[0];
succ_block = succ_edge->dst;
- /* Retarget label to the successor block. */
- if(block->label != jit_label_undefined)
- {
- func->builder->label_blocks[block->label] = succ_block;
- if(succ_block->label == jit_label_undefined)
- {
- succ_block->label = block->label;
- }
- else
- {
- /* FIXME: If both blocks have labels then this results
- into a duplicate label which is not recorded in the
- target block. This shouldn't cause big problems now
- but perhaps some sort of block-to-label-list mappings
- might be useful someday. */
- }
- }
+ /* Retarget labels bound to this block to the successor block. */
+ merge_labels(func, succ_block, block->label);
/* Retarget all incoming edges except a fallthrough edge */
fallthru_edge = 0;
@@ -435,15 +418,6 @@
return 1;
}
-/* Delete edge along with references to it */
-static void
-delete_edge(jit_function_t func, _jit_edge_t edge)
-{
- detach_edge_src(edge);
- detach_edge_dst(edge);
- jit_memory_pool_dealloc(&func->builder->edge_pool, edge);
-}
-
/* Delete block along with references to it */
static void
eliminate_block(jit_block_t block)
@@ -553,13 +527,13 @@
int
_jit_block_init(jit_function_t func)
{
- func->builder->entry_block = create_block(func);
+ func->builder->entry_block = _jit_block_create(func);
if(!func->builder->entry_block)
{
return 0;
}
- func->builder->exit_block = create_block(func);
+ func->builder->exit_block = _jit_block_create(func);
if(!func->builder->exit_block)
{
return 0;
@@ -581,7 +555,7 @@
while(block)
{
next = block->next;
- free_block(block);
+ _jit_block_destroy(block);
block = next;
}
@@ -589,7 +563,7 @@
while(block)
{
next = block->next;
- free_block(block);
+ _jit_block_destroy(block);
block = next;
}
@@ -792,42 +766,41 @@
}
jit_block_t
-_jit_block_create(jit_function_t func, jit_label_t *label)
+_jit_block_create(jit_function_t func)
{
jit_block_t block;
- /* Create the block */
- block = create_block(func);
+ /* Allocate memory for the block */
+ block = jit_cnew(struct _jit_block);
if(!block)
{
return 0;
}
- /* Set the block label */
- if(label)
- {
- if(*label == jit_label_undefined)
- {
- *label = (func->builder->next_label)++;
- }
- block->label = *label;
- if(!_jit_block_record_label(block))
- {
- jit_free(block);
- return 0;
- }
- }
-
- /* Add the block to the end of the function's list */
- block->next = func->builder->exit_block;
- block->prev = func->builder->exit_block->prev;
- block->next->prev = block;
- block->prev->next = block;
+ /* Initialize the block */
+ block->func = func;
+ block->label = jit_label_undefined;
return block;
}
void
+_jit_block_destroy(jit_block_t block)
+{
+ /* Free all the memory owned by the block. CFG edges are not freed
+ because each edge is shared between two blocks so the ownership
+ of the edge is ambiguous. Sometimes an edge may be redirected to
+ another block rather than freed. Therefore edges are freed (or
+ not freed) separately. However succs and preds arrays are freed,
+ these contain pointers to edges, not edges themselves. */
+ jit_meta_destroy(&block->meta);
+ jit_free(block->succs);
+ jit_free(block->preds);
+ jit_free(block->insns);
+ jit_free(block);
+}
+
+void
_jit_block_detach(jit_block_t first, jit_block_t last)
{
last->next->prev = first->prev;
@@ -853,34 +826,42 @@
}
int
-_jit_block_record_label(jit_block_t block)
+_jit_block_record_label(jit_block_t block, jit_label_t label)
{
- jit_builder_t builder = block->func->builder;
+ jit_builder_t builder;
jit_label_t num;
- jit_block_t *blocks;
- if(block->label >= builder->max_label_blocks)
+ _jit_label_info_t *info;
+
+ builder = block->func->builder;
+ if(label >= builder->max_label_info)
{
- num = builder->max_label_blocks;
+ num = builder->max_label_info;
if(num < 64)
{
num = 64;
}
- while(num <= block->label)
+ while(num <= label)
{
num *= 2;
}
- blocks = (jit_block_t *)jit_realloc(builder->label_blocks,
- num * sizeof(jit_block_t));
- if(!blocks)
+
+ info = (_jit_label_info_t *) jit_realloc(builder->label_info,
+ num *
sizeof(_jit_label_info_t));
+ if(!info)
{
return 0;
}
- jit_memzero(blocks + builder->max_label_blocks,
- sizeof(jit_block_t) * (num -
builder->max_label_blocks));
- builder->label_blocks = blocks;
- builder->max_label_blocks = num;
+
+ jit_memzero(info + builder->max_label_info,
+ sizeof(_jit_label_info_t) * (num -
builder->max_label_info));
+ builder->label_info = info;
+ builder->max_label_info = num;
}
- builder->label_blocks[block->label] = block;
+
+ builder->label_info[label].block = block;
+ builder->label_info[label].alias = block->label;
+ block->label = label;
+
return 1;
}
@@ -986,10 +967,33 @@
{
return block->label;
}
- else
- {
return jit_label_undefined;
+}
+
+/*@
+ * @deftypefun jit_label_t jit_block_get_next_label (jit_block_t @var{block,
jit_label_t @var{label}})
+ * Get the next label associated with a block.
+ * @end deftypefun
address@hidden/
+jit_label_t
+jit_block_get_next_label(jit_block_t block, jit_label_t label)
+{
+ jit_builder_t builder;
+ if(block)
+ {
+ if(label == jit_label_undefined)
+ {
+ return block->label;
}
+ builder = block->func->builder;
+ if(builder
+ && label < builder->max_label_info
+ && block == builder->label_info[label].block)
+ {
+ return builder->label_info[label].alias;
+ }
+ }
+ return jit_label_undefined;
}
/*@
@@ -1049,9 +1053,9 @@
jit_block_t
jit_block_from_label(jit_function_t func, jit_label_t label)
{
- if(func && func->builder && label < func->builder->max_label_blocks)
+ if(func && func->builder && label < func->builder->max_label_info)
{
- return func->builder->label_blocks[label];
+ return func->builder->label_info[label].block;
}
else
{
Index: jit/jit-dump.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-dump.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- jit/jit-dump.c 21 Apr 2009 14:34:34 -0000 1.20
+++ jit/jit-dump.c 9 May 2009 21:54:32 -0000 1.21
@@ -25,14 +25,14 @@
#include <jit/jit-dump.h>
#include <config.h>
#ifdef HAVE_STDLIB_H
- #include <stdlib.h>
+# include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
- #include <unistd.h>
+# include <unistd.h>
#endif
#if defined(JIT_BACKEND_INTERP)
- #include "jit-interp.h"
+# include "jit-interp.h"
#endif
/*@
@@ -763,11 +763,11 @@
jit_block_t block;
jit_insn_iter_t iter;
jit_insn_t insn;
- int prev_block;
jit_type_t signature;
unsigned int param;
unsigned int num_params;
jit_value_t value;
+ jit_label_t label;
/* Bail out if we don't have sufficient information to dump */
if(!stream || !func)
@@ -847,20 +847,30 @@
{
/* Output each of the three address blocks in turn */
block = 0;
- prev_block = 0;
while((block = jit_block_next(func, block)) != 0)
{
- /* Output the block's label, if it has one */
+ /* Output the block's labels, if it has any */
+ label = jit_block_get_label(block);
if(block->label != jit_label_undefined)
{
- fprintf(stream, ".L%ld:\n",
(long)(block->label));
+ for(;;)
+ {
+ fprintf(stream, ".L%ld:", (long) label);
+ label = jit_block_get_next_label(block,
label);
+ if(label == jit_label_undefined)
+ {
+ fprintf(stream, "\n");
+ break;
+ }
+ fprintf(stream, " ");
+ }
}
- else if (prev_block && _jit_block_get_last(block) != 0)
+ else if (block != func->builder->entry_block
+ /*&& _jit_block_get_last(block) != 0*/)
{
/* A new block was started, but it doesn't have
a label yet */
fprintf(stream, ".L:\n");
}
- prev_block = 1;
/* Dump the instructions in the block */
jit_insn_iter_init(&iter, block);
Index: jit/jit-function.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-function.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -b -r1.42 -r1.43
--- jit/jit-function.c 8 May 2009 23:33:41 -0000 1.42
+++ jit/jit-function.c 9 May 2009 21:54:32 -0000 1.43
@@ -212,8 +212,7 @@
func->builder->init_block = func->builder->current_block;
/* Start first block for function body */
- func->builder->current_block = _jit_block_create(func, 0);
- if(!func->builder->current_block)
+ if(!jit_insn_new_block(func))
{
_jit_function_free_builder(func);
return 0;
@@ -232,7 +231,7 @@
jit_memory_pool_free(&(func->builder->value_pool),
_jit_value_free);
jit_memory_pool_free(&(func->builder->meta_pool),
_jit_meta_free_one);
jit_free(func->builder->param_values);
- jit_free(func->builder->label_blocks);
+ jit_free(func->builder->label_info);
jit_free(func->builder);
func->builder = 0;
}
Index: jit/jit-insn.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-insn.c,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -b -r1.69 -r1.70
--- jit/jit-insn.c 8 May 2009 23:33:41 -0000 1.69
+++ jit/jit-insn.c 9 May 2009 21:54:32 -0000 1.70
@@ -1072,17 +1072,20 @@
/*@
* @deftypefun void jit_insn_label (jit_function_t @var{func}, jit_label_t
address@hidden)
- * Start a new block within the function @var{func} and give it the
- * specified @var{label}. Returns zero if out of memory.
+ * Start a new basic block within the function @var{func} and give it the
+ * specified @var{label}. If the call is made when a new block was just
+ * created by any previous call then that block is reused, no new block
+ * is created. Returns zero if out of memory.
*
* If the contents of @var{label} are @code{jit_label_undefined}, then this
* function will allocate a new label for this block. Otherwise it will
* reuse the specified label from a previous branch instruction.
* @end deftypefun
@*/
-int jit_insn_label(jit_function_t func, jit_label_t *label)
+int
+jit_insn_label(jit_function_t func, jit_label_t *label)
{
- jit_block_t current;
+ jit_block_t block;
if(!_jit_function_ensure_builder(func))
{
@@ -1093,33 +1096,36 @@
return 0;
}
- current = func->builder->current_block;
- if(current->label == jit_label_undefined &&
!_jit_block_get_last(current))
- {
- /* We just started a new block after a branch instruction,
- so don't bother creating another new block */
- if(*label == jit_label_undefined)
+ /* Create a new block if the current one is not empty */
+ block = func->builder->current_block;
+ if(_jit_block_get_last(block))
{
- *label = (func->builder->next_label)++;
- }
- current->label = *label;
- if(!_jit_block_record_label(current))
+ block = _jit_block_create(func);
+ if(!block)
{
return 0;
}
}
- else
+
+ /* Record the label */
+ if(*label == jit_label_undefined)
{
- /* Create a new block */
- jit_block_t block = _jit_block_create(func, label);
- if(!block)
+ *label = (func->builder->next_label)++;
+ }
+ if(!_jit_block_record_label(block, *label))
{
+ _jit_block_destroy(block);
return 0;
}
- /* Set the new block as the current one */
+ /* If the block is newly created then insert it to the end of
+ the function's block list */
+ if(block != func->builder->current_block)
+ {
+ _jit_block_attach_before(func->builder->exit_block, block,
block);
func->builder->current_block = block;
}
+
return 1;
}
@@ -1128,14 +1134,22 @@
* Start a new basic block, without giving it an explicit label.
* @end deftypefun
@*/
-int jit_insn_new_block(jit_function_t func)
+int
+jit_insn_new_block(jit_function_t func)
{
- jit_block_t block = _jit_block_create(func, 0);
+ jit_block_t block;
+
+ /* Create a new block */
+ block = _jit_block_create(func);
if(!block)
{
return 0;
}
+
+ /* Insert the block to the end of the function's block list */
+ _jit_block_attach_before(func->builder->exit_block, block, block);
func->builder->current_block = block;
+
return 1;
}
Index: jit/jit-internal.h
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-internal.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- jit/jit-internal.h 8 May 2009 23:33:41 -0000 1.35
+++ jit/jit-internal.h 9 May 2009 21:54:33 -0000 1.36
@@ -314,6 +314,22 @@
#define JIT_INSN_DEST_IS_VALUE 0x1000
/*
+ * Information about each label associated with a function.
+ *
+ * Multiple labels may belong to the same basic block. Such labels are
+ * linked into list.
+ */
+typedef struct _jit_label_info _jit_label_info_t;
+struct _jit_label_info
+{
+ /* Block the label assigned to */
+ jit_block_t block;
+
+ /* Next label that might belong to the same block */
+ jit_label_t alias;
+};
+
+/*
* Information that is associated with a function for building
* the instructions and values. This structure can be discarded
* once the function has been fully compiled.
@@ -344,8 +360,8 @@
jit_label_t next_label;
/* Mapping from label numbers to blocks */
- jit_block_t *label_blocks;
- jit_label_t max_label_blocks;
+ _jit_label_info_t *label_info;
+ jit_label_t max_label_info;
/* Exception handling definitions for the function */
jit_value_t setjmp_value;
@@ -600,7 +616,12 @@
/*
* Create a new block and associate it with a function.
*/
-jit_block_t _jit_block_create(jit_function_t func, jit_label_t *label);
+jit_block_t _jit_block_create(jit_function_t func);
+
+/*
+ * Destroy a block.
+ */
+void _jit_block_destroy(jit_block_t block);
/*
* Detach blocks from their current position in a function.
@@ -620,7 +641,7 @@
/*
* Record the label mapping for a block.
*/
-int _jit_block_record_label(jit_block_t block);
+int _jit_block_record_label(jit_block_t block, jit_label_t label);
/*
* Add an instruction to a block.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [dotgnu-pnet-commits] libjit ChangeLog include/jit/jit-block.h jit/ji...,
Aleksey Demakov <=