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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET Just In Time compiler (l


From: Aleksey Demakov
Subject: [dotgnu-pnet-commits] [SCM] DotGNU Portable.NET Just In Time compiler (libjit) branch, master, updated. 9ede4692bdb2318789cfaeff30cec2be361af864
Date: Wed, 09 Dec 2009 13:56:05 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "DotGNU Portable.NET Just In Time compiler (libjit)".

The branch, master has been updated
       via  9ede4692bdb2318789cfaeff30cec2be361af864 (commit)
      from  aa33f283974ab15bb38ebcc1d772d098c421836a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/libjit.git/commit/?id=9ede4692bdb2318789cfaeff30cec2be361af864

commit 9ede4692bdb2318789cfaeff30cec2be361af864
Author: Aleksey Demakov <address@hidden>
Date:   Wed Dec 9 19:55:08 2009 +0600

    fix block clean problems

diff --git a/ChangeLog b/ChangeLog
index 1aea39c..5727866 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2009-12-09  Aleksey Demakov  <address@hidden>
+
+       * jit/jit-block.c (merge_empty): fix label merging.
+
+       * jit/jit-internal.h, jit/jit-insn.c (jit_insn_address_of_label)
+       * jit/jit-block.c (_jit_block_record_label_flags): flag labels that
+       are taken address of.
+
+       * jit/jit-block.c (eliminate_unreachable, _jit_block_clean_cfg):
+       do not optimize away blocks with labels flagged as being taken
+       address of.
+
 2009-11-01  Aleksey Demakov  <address@hidden>
 
        * jit/jit-block.c (_jit_block_clean_cfg): implement the "combine" part
diff --git a/jit/jit-block.c b/jit/jit-block.c
index 23c2f58..1f68a12 100644
--- a/jit/jit-block.c
+++ b/jit/jit-block.c
@@ -254,7 +254,7 @@ detach_edge_dst(_jit_edge_t edge)
        }
 }
 
-static int
+static void
 attach_edge_dst(_jit_edge_t edge, jit_block_t block)
 {
        _jit_edge_t *preds;
@@ -262,14 +262,12 @@ attach_edge_dst(_jit_edge_t edge, jit_block_t block)
        preds = jit_realloc(block->preds, (block->num_preds + 1) * 
sizeof(_jit_edge_t));
        if(!preds)
        {
-               return 0;
+               jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
        }
 
        preds[block->num_preds++] = edge;
        block->preds = preds;
        edge->dst = block;
-
-       return 1;
 }
 
 /* Delete edge along with references to it */
@@ -318,12 +316,32 @@ is_empty_block(jit_block_t block)
        return 1;
 }
 
+#ifdef _JIT_BLOCK_DEBUG
+static void
+label_loop_check(jit_function_t func, jit_block_t block, jit_label_t label)
+{
+       jit_label_t block_label = block->label;
+       while (block_label != jit_label_undefined)
+       {
+               if (block_label == label)
+               {
+                       abort();
+               }
+               block_label = func->builder->label_info[block_label].alias;
+       }
+}
+#endif
+
 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;
 
+#ifdef _JIT_BLOCK_DEBUG
+       label_loop_check(func, block, label);
+#endif
+
        while(label != jit_label_undefined)
        {
                info = &func->builder->label_info[label];
@@ -349,6 +367,7 @@ merge_empty(jit_function_t func, jit_block_t block, int 
*changed)
 
        /* Retarget labels bound to this block to the successor block. */
        merge_labels(func, succ_block, block->label);
+       block->label = jit_label_undefined;
 
        /* Retarget all incoming edges except a fallthrough edge */
        fallthru_edge = 0;
@@ -362,10 +381,7 @@ merge_empty(jit_function_t func, jit_block_t block, int 
*changed)
                else
                {
                        *changed = 1;
-                       if(!attach_edge_dst(pred_edge, succ_block))
-                       {
-                               jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
-                       }
+                       attach_edge_dst(pred_edge, succ_block);
                }
        }
 
@@ -377,10 +393,7 @@ merge_empty(jit_function_t func, jit_block_t block, int 
*changed)
                if(succ_edge->flags == _JIT_EDGE_FALLTHRU)
                {
                        *changed = 1;
-                       if(!attach_edge_dst(fallthru_edge, succ_block))
-                       {
-                               jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
-                       }
+                       attach_edge_dst(fallthru_edge, succ_block);
                        fallthru_edge = 0;
                }
                else if (block->num_preds > 1)
@@ -479,6 +492,22 @@ combine_block(jit_function_t func, jit_block_t block, int 
*changed)
        merge_empty(func, block, changed);
 }
 
+/* Mark blocks that might be taken address of */
+static void
+set_address_of(jit_function_t func)
+{
+       int index;
+
+       for(index = 0; index < func->builder->max_label_info; index++)
+       {
+               if((func->builder->label_info[index].flags & 
JIT_LABEL_ADDRESS_OF) != 0
+                  && func->builder->label_info[index].block)
+               {
+                       func->builder->label_info[index].block->address_of = 1;
+               }
+       }
+}
+
 /* Delete block along with references to it */
 static void
 eliminate_block(jit_block_t block)
@@ -537,13 +566,16 @@ eliminate_unreachable(jit_function_t func)
        while(block != func->builder->exit_block)
        {
                next_block = block->next;
-               if(block->visited)
-               {
-                       block->visited = 0;
-               }
-               else
+               if(!block->address_of)
                {
-                       eliminate_block(block);
+                       if(block->visited)
+                       {
+                               block->visited = 0;
+                       }
+                       else
+                       {
+                               eliminate_block(block);
+                       }
                }
                block = next_block;
        }
@@ -652,6 +684,8 @@ _jit_block_clean_cfg(jit_function_t func)
        jit_block_t block;
        jit_insn_t insn;
 
+       set_address_of(func);
+
        /*
         * The code below is based on the Clean algorithm described in
         * "Engineering a Compiler" by Keith D. Cooper and Linda Torczon,
@@ -683,7 +717,7 @@ _jit_block_clean_cfg(jit_function_t func)
 
                /* Take care of redundant branches that is, if possible, either
                   replace a branch with NOP turning it to a fall-through case
-                  or conditional branch reduce to unconditional */
+                  or reduce a conditional branch to unconditional */
                if(block->succs[0]->flags == _JIT_EDGE_BRANCH)
                {
                        insn = _jit_block_get_last(block);
@@ -702,12 +736,18 @@ _jit_block_clean_cfg(jit_function_t func)
                                        /* For conditional branch delete the 
branch
                                           edge while leaving the fallthough 
edge
                                           intact */
+#ifdef _JIT_BLOCK_DEBUG
+                                       printf("%d cbranch->fallthru %d\n", 
index, block->label);
+#endif
                                        delete_edge(func, block->succs[0]);
                                }
                                else
                                {
                                        /* For unconditional branch replace the 
branch
                                           edge with a fallthrough edge */
+#ifdef _JIT_BLOCK_DEBUG
+                                       printf("%d ubranch->fallthru %d\n", 
index, block->label);
+#endif
                                        block->ends_in_dead = 0;
                                        block->succs[0]->flags = 
_JIT_EDGE_FALLTHRU;
                                }
@@ -722,6 +762,9 @@ _jit_block_clean_cfg(jit_function_t func)
                                   that has the same target make the first 
branch
                                   unconditional too, remove the fallthough 
edge while
                                   leaving the branch edge intact */
+#ifdef _JIT_BLOCK_DEBUG
+                               printf("%d cbranch->ubranch %d\n", index, 
block->label);
+#endif
                                changed = 1;
                                insn->opcode = JIT_OP_BR;
                                block->ends_in_dead = 1;
@@ -738,12 +781,19 @@ _jit_block_clean_cfg(jit_function_t func)
                        if(is_empty_block(block))
                        {
                                /* Remove empty block */
+#ifdef _JIT_BLOCK_DEBUG
+                               printf("%d merge_empty %d\n", index, 
block->label);
+#endif
                                merge_empty(func, block, &changed);
                        }
-                       else if(block->succs[0]->dst->num_preds == 1)
+                       else if(block->succs[0]->dst->num_preds == 1
+                               && block->succs[0]->dst->address_of == 0)
                        {
                                /* Combine with the successor block if it has
                                   only one predecessor */
+#ifdef _JIT_BLOCK_DEBUG
+                               printf("%d combine_block %d\n", index, 
block->label);
+#endif
                                combine_block(func, block, &changed);
                        }
 
@@ -896,17 +946,16 @@ _jit_block_attach_before(jit_block_t block, jit_block_t 
first, jit_block_t last)
        block->prev = last;
 }
 
-int
-_jit_block_record_label(jit_block_t block, jit_label_t label)
+/* Make space for the label in the label info table */
+static int
+ensure_label_table(jit_function_t func, jit_label_t label)
 {
-       jit_builder_t builder;
        jit_label_t num;
        _jit_label_info_t *info;
 
-       builder = block->func->builder;
-       if(label >= builder->max_label_info)
+       if(label >= func->builder->max_label_info)
        {
-               num = builder->max_label_info;
+               num = func->builder->max_label_info;
                if(num < 64)
                {
                        num = 64;
@@ -916,19 +965,41 @@ _jit_block_record_label(jit_block_t block, jit_label_t 
label)
                        num *= 2;
                }
 
-               info = (_jit_label_info_t *) jit_realloc(builder->label_info,
+               info = (_jit_label_info_t *) 
jit_realloc(func->builder->label_info,
                                                         num * 
sizeof(_jit_label_info_t));
                if(!info)
                {
                        return 0;
                }
 
-               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;
+               jit_memzero(info + func->builder->max_label_info,
+                           sizeof(_jit_label_info_t) * (num - 
func->builder->max_label_info));
+               func->builder->label_info = info;
+               func->builder->max_label_info = num;
        }
 
+       return 1;
+}
+
+int
+_jit_block_record_label(jit_block_t block, jit_label_t label)
+{
+       jit_builder_t builder;
+
+       if(!ensure_label_table(block->func, label))
+       {
+               return 0;
+       }
+
+       builder = block->func->builder;
+
+       /* Bail out on previously recorded label */
+       if(builder->label_info[label].block)
+       {
+               abort();
+       }
+
+       /* Record label info to the table */
        builder->label_info[label].block = block;
        builder->label_info[label].alias = block->label;
        block->label = label;
@@ -936,6 +1007,18 @@ _jit_block_record_label(jit_block_t block, jit_label_t 
label)
        return 1;
 }
 
+int
+_jit_block_record_label_flags(jit_function_t func, jit_label_t label, int 
flags)
+{
+       if(!ensure_label_table(func, label))
+       {
+               return 0;
+       }
+
+       func->builder->label_info[label].flags = flags;
+       return 1;
+}
+
 jit_insn_t
 _jit_block_add_insn(jit_block_t block)
 {
diff --git a/jit/jit-insn.c b/jit/jit-insn.c
index dad6b5d..de82973 100644
--- a/jit/jit-insn.c
+++ b/jit/jit-insn.c
@@ -1138,6 +1138,9 @@ int
 jit_insn_new_block(jit_function_t func)
 {
        jit_block_t block;
+#ifdef _JIT_BLOCK_DEBUG
+       jit_label_t label;
+#endif
 
        /* Create a new block */
        block = _jit_block_create(func);
@@ -1146,6 +1149,15 @@ jit_insn_new_block(jit_function_t func)
                return 0;
        }
 
+#ifdef _JIT_BLOCK_DEBUG
+       label = (func->builder->next_label)++;
+       if(!_jit_block_record_label(block, label))
+       {
+               _jit_block_destroy(block);
+               return 0;
+       }
+#endif
+
        /* 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;
@@ -4120,6 +4132,11 @@ jit_value_t jit_insn_address_of_label(jit_function_t 
func, jit_label_t *label)
        {
                *label = (func->builder->next_label)++;
        }
+       if(!_jit_block_record_label_flags(func, *label, JIT_LABEL_ADDRESS_OF))
+       {
+               return 0;
+       }
+
        insn = _jit_block_add_insn(func->builder->current_block);
        if(!insn)
        {
diff --git a/jit/jit-internal.h b/jit/jit-internal.h
index 1eaf0c6..35961ab 100644
--- a/jit/jit-internal.h
+++ b/jit/jit-internal.h
@@ -31,6 +31,7 @@ extern        "C" {
 
 /*
 #define _JIT_COMPILE_DEBUG     1
+#define _JIT_BLOCK_DEBUG       1
 */
 
 /*
@@ -224,6 +225,7 @@ struct _jit_block
        /* Control flow flags */
        unsigned                visited : 1;
        unsigned                ends_in_dead : 1;
+       unsigned                address_of : 1;
 
        /* Metadata */
        jit_meta_t              meta;
@@ -327,8 +329,14 @@ struct _jit_label_info
 
        /* Next label that might belong to the same block */
        jit_label_t             alias;
+
+       /* Label flags */
+       int                     flags;
 };
 
+#define JIT_LABEL_ADDRESS_OF           0x0001
+
+
 /*
  * Information that is associated with a function for building
  * the instructions and values.  This structure can be discarded
@@ -645,6 +653,11 @@ void _jit_block_attach_before(jit_block_t block, 
jit_block_t first, jit_block_t
 int _jit_block_record_label(jit_block_t block, jit_label_t label);
 
 /*
+ * Record the label flags.
+ */
+int _jit_block_record_label_flags(jit_function_t func, jit_label_t label, int 
flags);
+
+/*
  * Add an instruction to a block.
  */
 jit_insn_t _jit_block_add_insn(jit_block_t block);

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog          |   12 ++++
 jit/jit-block.c    |  145 +++++++++++++++++++++++++++++++++++++++++-----------
 jit/jit-insn.c     |   17 ++++++
 jit/jit-internal.h |   13 +++++
 4 files changed, 156 insertions(+), 31 deletions(-)


hooks/post-receive
-- 
DotGNU Portable.NET Just In Time compiler (libjit)




reply via email to

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