dotgnu-pnet-commits
[Top][All Lists]
Advanced

[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.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]