From: Rhys Weatherley Date: Fri, 21 May 2004 23:32:32 +0000 (+0000) Subject: Rename "jit_insn_move_blocks" to "jit_insn_move_blocks_to_end" and X-Git-Tag: r.0.0.4~92 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=a0eb7f57228a666a367b52d0a50c320910597b5c;p=francis%2Flibjit.git 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. --- diff --git a/ChangeLog b/ChangeLog index 5434c10..f84a9ba 100644 --- 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 * jit/jit-gen-arm.c, jit/jit-gen-arm.h: modify the ARM codegen diff --git a/dpas/dpas-parser.y b/dpas/dpas-parser.y index 6e9fba7..426b7a0 100644 --- a/dpas/dpas-parser.y +++ b/dpas/dpas-parser.y @@ -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); diff --git a/include/jit/jit-insn.h b/include/jit/jit-insn.h index 692c781..43318bf 100644 --- a/include/jit/jit-insn.h +++ b/include/jit/jit-insn.h @@ -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; diff --git a/jit/jit-function.c b/jit/jit-function.c index d4fe2b2..5ca0505 100644 --- a/jit/jit-function.c +++ b/jit/jit-function.c @@ -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; } diff --git a/jit/jit-insn.c b/jit/jit-insn.c index 190f1e3..8781aaa 100644 --- a/jit/jit-insn.c +++ b/jit/jit-insn.c @@ -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}. diff --git a/jit/jit-internal.h b/jit/jit-internal.h index 9f1974a..1dec549 100644 --- a/jit/jit-internal.h +++ b/jit/jit-internal.h @@ -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;