On Tue, 2009-08-18 at 21:21 +0200, Tomek Grabiec wrote: > Like I said on IRC, this will not work for empty basic blocks, because > spill_at_insn will belong to the preceding > basic block. This causes that instructions will be added to different > (preceding) basic block and might not be executed on some > execution paths.
I think the following patch _is_ correct but it breaks "make regression" so I think we're silently spilling/reloading empty basic blocks. Pekka >From 999622798d073ae892c316e6f69fde7697233e4d Mon Sep 17 00:00:00 2001 From: Pekka Enberg <penb...@cs.helsinki.fi> Date: Tue, 18 Aug 2009 21:12:22 +0300 Subject: [PATCH] spill-reload: Use radix_tree_lookup() in bb_last_insn() Lets use radix_tree_lookup() and get rid of the nasty loop in bb_last_insn(). Cc: Arthur HUILLET <arthur.huil...@free.fr> Cc: Tomek Grabiec <tgrab...@gmail.com> Signed-off-by: Pekka Enberg <penb...@cs.helsinki.fi> --- include/jit/basic-block.h | 5 +++++ jit/basic-block.c | 23 ++++++++--------------- jit/spill-reload.c | 3 ++- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/include/jit/basic-block.h b/include/jit/basic-block.h index e50f6c6..e1d8c86 100644 --- a/include/jit/basic-block.h +++ b/include/jit/basic-block.h @@ -74,6 +74,11 @@ static inline struct basic_block *bb_entry(struct list_head *head) return list_entry(head, struct basic_block, bb_list_node); } +static inline bool bb_is_empty(struct basic_block *bb) +{ + return list_is_empty(&bb->stmt_list); +} + struct basic_block *alloc_basic_block(struct compilation_unit *, unsigned long, unsigned long); struct basic_block *get_basic_block(struct compilation_unit *, unsigned long, unsigned long); void free_basic_block(struct basic_block *); diff --git a/jit/basic-block.c b/jit/basic-block.c index 6de5c3f..0f40bcc 100644 --- a/jit/basic-block.c +++ b/jit/basic-block.c @@ -176,21 +176,14 @@ struct insn *bb_first_insn(struct basic_block *bb) struct insn *bb_last_insn(struct basic_block *bb) { - struct insn *this = list_entry(bb->insn_list.prev, struct insn, insn_list_node); - - /* - * We want to return the last "real" instruction of the basic block. Taking the - * last of the insn_list will not work in case a live interval has been spilled - * right after the final jump of the basic block. - * This is a side effect of the linear scan algorithm. - * - * As a result, we browse instructions starting from the last, in order to find the one - * that has a LIR position matching the position for the end of the block. - */ - while (this->lir_pos != bb->end_insn - 1) { - this = list_entry(this->insn_list_node.prev, struct insn, insn_list_node); - } - return this; + unsigned long pos = bb->end_insn - 1; + + if (bb_is_empty(bb)) + return NULL; + + assert(pos >= bb->start_insn); + + return radix_tree_lookup(bb->b_parent->lir_insn_map, pos); } static int __bb_add_neighbor(void *new, void **array, unsigned long *nb) diff --git a/jit/spill-reload.c b/jit/spill-reload.c index 5ced80e..a8806f1 100644 --- a/jit/spill-reload.c +++ b/jit/spill-reload.c @@ -183,7 +183,8 @@ static void insert_mov_insns(struct compilation_unit *cu, struct insn *spill_at_insn; int i; - spill_at_insn = bb_last_insn(from_bb); + spill_at_insn = bb_last_insn(from_bb); + assert(spill_at_insn != NULL); /* Spill all intervals that have to be resolved */ for (i = 0; i < nr_mapped; i++) { -- 1.5.6.3 ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel