]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Rename "jit_insn_move_blocks" to "jit_insn_move_blocks_to_end" and
authorRhys Weatherley <rweather@southern-storm.com.au>
Fri, 21 May 2004 23:32:32 +0000 (23:32 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Fri, 21 May 2004 23:32:32 +0000 (23:32 +0000)
add a new function "jit_insn_move_blocks_to_start" for creating
initialization code.

ChangeLog
dpas/dpas-parser.y
include/jit/jit-insn.h
jit/jit-function.c
jit/jit-insn.c
jit/jit-internal.h

index 5434c108c59ce3e3dee370a40f7d80ecc5b22da9..f84a9ba023c80eff445b0db804f358afb2d200e0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,11 @@
        conditional branches to cross an exception context boundary,
        because doing so will violate "finally" semantics.
 
+       * dpas/dpas-parser.y, include/jit/jit-insn.h, jit/jit-function.c,
+       jit/jit-insn.c, jit/jit-internal.h: rename "jit_insn_move_blocks"
+       to "jit_insn_move_blocks_to_end" and add a new function
+       "jit_insn_move_blocks_to_start" for creating initialization code.
+
 2004-05-21  Rhys Weatherley  <rweather@southern-storm.com.au>
 
        * jit/jit-gen-arm.c, jit/jit-gen-arm.h: modify the ARM codegen
index 6e9fba7b94e1cfd313dc2f757c6d308ea16854ee..426b7a045ba400ad52e434a2f28466d8a35375c5 100644 (file)
@@ -1857,7 +1857,7 @@ WhileStatement
                        } Statement                     {
 
                                /* Move the expression blocks down to this point */
-                               jit_insn_move_blocks
+                               jit_insn_move_blocks_to_end
                                        (dpas_current_function(),
                                         loop_stack[loop_stack_size - 1].expr_label,
                                         loop_stack[loop_stack_size - 1].top_label);
index 692c7810f10172f01f474edc0e167f2273716474..43318bf1579bf6f4c6c4a1f1378e39e57f26f018 100644 (file)
@@ -282,7 +282,9 @@ int jit_insn_memset
 jit_value_t jit_insn_alloca
        (jit_function_t func, jit_value_t size) JIT_NOTHROW;
 
-int jit_insn_move_blocks
+int jit_insn_move_blocks_to_end
+       (jit_function_t func, jit_label_t from_label, jit_label_t to_label);
+int jit_insn_move_blocks_to_start
        (jit_function_t func, jit_label_t from_label, jit_label_t to_label);
 
 void jit_insn_iter_init(jit_insn_iter_t *iter, jit_block_t block) JIT_NOTHROW;
index d4fe2b26658c3737927a5c2991ba614a4c7994d6..5ca05050b2449fbc1aaa7f377bc140e38eb8a420 100644 (file)
@@ -149,6 +149,11 @@ int _jit_function_ensure_builder(jit_function_t func)
                return 0;
        }
 
+       /* The current position is where initialization code will be
+          inserted by "jit_insn_move_blocks_to_start" */
+       func->builder->init_block = func->builder->current_block;
+       func->builder->init_insn = func->builder->current_block->last_insn + 1;
+
        /* The builder is ready to go */
        return 1;
 }
index 190f1e3c96faf01d30d384977367d6b1b9ef4148..8781aaadb7a868211e7b56e6d48d51036205f5b7 100644 (file)
@@ -6649,8 +6649,60 @@ jit_value_t jit_insn_alloca(jit_function_t func, jit_value_t size)
        return apply_unary(func, JIT_OP_ALLOCA, size, jit_type_void_ptr);
 }
 
+/*
+ * Detach a block from its current position in a function.
+ */
+static void detach_block(jit_block_t block)
+{
+       if(block->next)
+       {
+               block->next->prev = block->prev;
+       }
+       else
+       {
+               block->func->builder->last_block = block->prev;
+       }
+       if(block->prev)
+       {
+               block->prev->next = block->next;
+       }
+       else
+       {
+               block->func->builder->first_block = block->next;
+       }
+}
+
+/*
+ * Attach a block to a function after a specific position.
+ */
+static void attach_block_after(jit_block_t block, jit_block_t after)
+{
+       if(after)
+       {
+               block->next = after->next;
+               block->prev = after;
+               if(after->next)
+               {
+                       after->next->prev = block;
+               }
+               else
+               {
+                       block->func->builder->last_block = block;
+               }
+               after->next = block;
+       }
+       else
+       {
+               /* Can only happen if the block list is empty */
+               block->next = 0;
+               block->prev = 0;
+               block->func->builder->first_block = block;
+               block->func->builder->last_block = block;
+       }
+}
+
 /*@
- * @deftypefun int jit_insn_move_blocks (jit_function_t func, jit_label_t from_label, jit_label_t to_label)
+ * @deftypefun int jit_insn_move_blocks_to_end (jit_function_t func, jit_label_t from_label, jit_label_t to_label)
  * Move all of the blocks between @code{from_label} (inclusive) and
  * @code{to_label} (exclusive) to the end of the current function.
  * This is typically used to move the expression in a @code{while}
@@ -6658,7 +6710,7 @@ jit_value_t jit_insn_alloca(jit_function_t func, jit_value_t size)
  * efficiently.
  * @end deftypefun
 @*/
-int jit_insn_move_blocks
+int jit_insn_move_blocks_to_end
        (jit_function_t func, jit_label_t from_label, jit_label_t to_label)
 {
        jit_block_t first_block;
@@ -6677,33 +6729,8 @@ int jit_insn_move_blocks
        while(block != 0 && block->label != to_label)
        {
                next = block->next;
-               if(block->next != 0)
-               {
-                       block->next->prev = block->prev;
-               }
-               else
-               {
-                       func->builder->last_block = block->prev;
-               }
-               if(block->prev != 0)
-               {
-                       block->prev->next = block->next;
-               }
-               else
-               {
-                       func->builder->first_block = block->next;
-               }
-               block->next = 0;
-               block->prev = func->builder->last_block;
-               if(func->builder->last_block)
-               {
-                       func->builder->last_block->next = block;
-               }
-               else
-               {
-                       func->builder->first_block = block;
-               }
-               func->builder->last_block = block;
+               detach_block(block);
+               attach_block_after(block, func->builder->last_block);
                block = next;
        }
        func->builder->current_block = func->builder->last_block;
@@ -6715,6 +6742,86 @@ int jit_insn_move_blocks
        return jit_insn_label(func, 0);
 }
 
+/*@
+ * @deftypefun int jit_insn_move_blocks_to_start (jit_function_t func, jit_label_t from_label, jit_label_t to_label)
+ * Move all of the blocks between @code{from_label} (inclusive) and
+ * @code{to_label} (exclusive) to the start of the current function.
+ * This is typically used to move initialization code to the head
+ * of the function.
+ * @end deftypefun
+@*/
+int jit_insn_move_blocks_to_start
+       (jit_function_t func, jit_label_t from_label, jit_label_t to_label)
+{
+       jit_block_t first_block;
+       jit_block_t init_block;
+       jit_block_t block;
+       jit_block_t next;
+       int move_current;
+
+       /* Find the first block that needs to be moved */
+       first_block = jit_block_from_label(func, from_label);
+       if(!first_block)
+       {
+               return 0;
+       }
+
+       /* If this is the first time that we have done this, we may need to
+          split the function's entry block just after the arguments are set up */
+       init_block = func->builder->init_block;
+       if(func->builder->init_insn >= 0)
+       {
+               if(func->builder->init_insn <= init_block->last_insn)
+               {
+                       block = _jit_block_create(func, 0);
+                       if(!block)
+                       {
+                               return 0;
+                       }
+                       block->entered_via_top = 1;
+                       block->first_insn = func->builder->init_insn;
+                       block->last_insn = init_block->last_insn;
+                       init_block->last_insn = func->builder->init_insn - 1;
+                       detach_block(block);
+                       attach_block_after(block, init_block);
+               }
+               func->builder->init_insn = -1;
+       }
+
+       /* If the first block is just after "init_block", then nothing to do */
+       if(init_block->next == first_block)
+       {
+               return 1;
+       }
+
+       /* Keep moving blocks until we come across "to_label" */
+       block = first_block;
+       move_current = 0;
+       while(block != 0 && block->label != to_label)
+       {
+               next = block->next;
+               move_current = (block == func->builder->current_block);
+               detach_block(block);
+               attach_block_after(block, init_block);
+               init_block = block;
+               block = next;
+       }
+       func->builder->init_block = init_block;
+
+       /* The first block will be entered via its top now */
+       first_block->entered_via_top = 1;
+
+       /* Fix up the current block reference if we just moved it */
+       if(move_current)
+       {
+               func->builder->current_block = func->builder->last_block;
+               return jit_insn_label(func, 0);
+       }
+
+       /* Done */
+       return 1;
+}
+
 /*@
  * @deftypefun void jit_insn_iter_init ({jit_insn_iter_t *} iter, jit_block_t block)
  * Initialize an iterator to point to the first instruction in @code{block}.
index 9f1974abd87f30f1fb6d7c0455df4459418a8032..1dec549c2b638b0e5242628a3e5b59a727e5d876 100644 (file)
@@ -291,6 +291,10 @@ struct _jit_builder
        /* The current block that is being constructed */
        jit_block_t                     current_block;
 
+       /* The position to insert initialization blocks */
+       jit_block_t                     init_block;
+       int                                     init_insn;
+
        /* Exception handlers for the function */
        jit_block_eh_t          exception_handlers;
        jit_block_eh_t          current_handler;