Re: [PATCH 3/3] spill-reload: Use radix_tree_lookup() in insert_mov_insns()

2009-08-18 Thread Arthur Huillet
Ack here as well, this is obviously correct (provided radix_tree_lookup() 
works).

On Tue, 18 Aug 2009 21:41:19 +0300
Pekka Enberg penb...@cs.helsinki.fi wrote:

 Lets use radix_tree_lookup() and get rid of the nasty loop in
 bb_last_insn(). For some reason, this seems to fix the infinite loop
 triggered by empty basic blocks.
 
 Cc: Arthur HUILLET arthur.huil...@free.fr
 Cc: Tomek Grabiec tgrab...@gmail.com
 Signed-off-by: Pekka Enberg penb...@cs.helsinki.fi
 ---
  jit/basic-block.c  |   16 +---
  jit/spill-reload.c |2 +-
  2 files changed, 2 insertions(+), 16 deletions(-)
 
 diff --git a/jit/basic-block.c b/jit/basic-block.c
 index 6de5c3f..dbf3675 100644
 --- a/jit/basic-block.c
 +++ b/jit/basic-block.c
 @@ -176,21 +176,7 @@ 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;
 + return list_entry(bb-insn_list.prev, struct insn, insn_list_node);
  }
  
  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..515db8a 100644
 --- a/jit/spill-reload.c
 +++ b/jit/spill-reload.c
 @@ -183,7 +183,7 @@ 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   = radix_tree_lookup(cu-lir_insn_map, from_bb-end_insn 
 - 1);
  
   /* Spill all intervals that have to be resolved */
   for (i = 0; i  nr_mapped; i++) {
 -- 
 1.5.6.3
 


-- 
Greetings, 
A. Huillet

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


[PATCH 2/3] spill-reload: Remove redundant argument from insert_copy_slot_insn()

2009-08-18 Thread Pekka Enberg
The 'pop_at_insn' argument is not used in insert_copy_slot_insn()
function so remove it to clean up code.

Cc: Arthur HUILLET arthur.huil...@free.fr
Cc: Tomek Grabiec tgrab...@gmail.com
Signed-off-by: Pekka Enberg penb...@cs.helsinki.fi
---
 jit/spill-reload.c |   13 +
 1 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/jit/spill-reload.c b/jit/spill-reload.c
index bf31288..5ced80e 100644
--- a/jit/spill-reload.c
+++ b/jit/spill-reload.c
@@ -125,8 +125,7 @@ insert_copy_slot_insn(struct live_interval *interval,
  struct compilation_unit *cu,
  struct stack_slot *from,
  struct stack_slot *to,
- struct insn *push_at_insn,
- struct insn *pop_at_insn)
+ struct insn *push_at_insn)
 {
struct insn *push, *pop;
 
@@ -140,7 +139,7 @@ insert_copy_slot_insn(struct live_interval *interval,
free_insn(push);
return warn(out of memory), -ENOMEM;
}
-   pop-bytecode_offset = pop_at_insn-bytecode_offset;
+   pop-bytecode_offset = push_at_insn-bytecode_offset;
 
list_add_tail(push-insn_list_node, push_at_insn-insn_list_node);
list_add(pop-insn_list_node, push-insn_list_node);
@@ -179,10 +178,10 @@ static void insert_mov_insns(struct compilation_unit *cu,
 struct basic_block *from_bb,
 struct basic_block *to_bb)
 {
-   int i;
-   struct insn *spill_at_insn, *reload_at_insn;
struct live_interval *from_it, *to_it;
struct stack_slot *slots[nr_mapped];
+   struct insn *spill_at_insn;
+   int i;
 
spill_at_insn   = bb_last_insn(from_bb);
 
@@ -201,12 +200,10 @@ static void insert_mov_insns(struct compilation_unit *cu,
for (i = 0; i  nr_mapped; i++) {
to_it   = mappings[i].to;
 
-   reload_at_insn = bb_first_insn(to_bb);
-
if (to_it-need_reload  to_it-range.start = 
to_bb-start_insn) {
insert_copy_slot_insn(mappings[i].to, cu, slots[i],
to_it-spill_parent-spill_slot,
-   spill_at_insn, reload_at_insn);
+   spill_at_insn);
continue;
}
 
-- 
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


[PATCH 3/3] spill-reload: Use radix_tree_lookup() in insert_mov_insns()

2009-08-18 Thread Pekka Enberg
Lets use radix_tree_lookup() and get rid of the nasty loop in
bb_last_insn(). For some reason, this seems to fix the infinite loop
triggered by empty basic blocks.

Cc: Arthur HUILLET arthur.huil...@free.fr
Cc: Tomek Grabiec tgrab...@gmail.com
Signed-off-by: Pekka Enberg penb...@cs.helsinki.fi
---
 jit/basic-block.c  |   16 +---
 jit/spill-reload.c |2 +-
 2 files changed, 2 insertions(+), 16 deletions(-)

diff --git a/jit/basic-block.c b/jit/basic-block.c
index 6de5c3f..dbf3675 100644
--- a/jit/basic-block.c
+++ b/jit/basic-block.c
@@ -176,21 +176,7 @@ 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;
+   return list_entry(bb-insn_list.prev, struct insn, insn_list_node);
 }
 
 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..515db8a 100644
--- a/jit/spill-reload.c
+++ b/jit/spill-reload.c
@@ -183,7 +183,7 @@ 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   = radix_tree_lookup(cu-lir_insn_map, from_bb-end_insn 
- 1);
 
/* 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


[PATCH 1/3] spill-reload: Insert spill instructions before branches

2009-08-18 Thread Pekka Enberg
Use insn_is_branch() to determine whether we must insert a spill
instruction before or after the last instruction in a basic block.

Cc: Arthur HUILLET arthur.huil...@free.fr
Cc: Tomek Grabiec tgrab...@gmail.com
Signed-off-by: Pekka Enberg penb...@cs.helsinki.fi
---
 arch/mmix/include/arch/instruction.h |5 +
 arch/x86/include/arch/instruction.h  |   17 +
 jit/spill-reload.c   |8 
 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/arch/mmix/include/arch/instruction.h 
b/arch/mmix/include/arch/instruction.h
index 427131a..d12bf83 100644
--- a/arch/mmix/include/arch/instruction.h
+++ b/arch/mmix/include/arch/instruction.h
@@ -108,6 +108,11 @@ exception_spill_insn(struct stack_slot *slot)
return NULL;
 }
 
+static inline bool insn_is_branch(struct insn *insn)
+{
+   return insn-type == INSN_JMP;
+}
+
 struct insn *alloc_insn(enum insn_type);
 void free_insn(struct insn *);
 
diff --git a/arch/x86/include/arch/instruction.h 
b/arch/x86/include/arch/instruction.h
index f2f858c..8d875b1 100644
--- a/arch/x86/include/arch/instruction.h
+++ b/arch/x86/include/arch/instruction.h
@@ -308,6 +308,23 @@ static inline struct insn *jump_insn(struct basic_block 
*bb)
return branch_insn(INSN_JMP_BRANCH, bb);
 }
 
+
+static inline bool insn_is_branch(struct insn *insn)
+{
+   switch (insn-type) {
+   case INSN_JE_BRANCH:
+   case INSN_JGE_BRANCH:
+   case INSN_JG_BRANCH:
+   case INSN_JLE_BRANCH:
+   case INSN_JL_BRANCH:
+   case INSN_JMP_BRANCH:
+   case INSN_JNE_BRANCH:
+   return true;
+   default:
+   return false;
+   }
+}
+
 struct insn *alloc_insn(enum insn_type);
 void free_insn(struct insn *);
 
diff --git a/jit/spill-reload.c b/jit/spill-reload.c
index 17b5134..bf31288 100644
--- a/jit/spill-reload.c
+++ b/jit/spill-reload.c
@@ -68,7 +68,7 @@ static struct insn *last_insn(struct compilation_unit *cu, 
struct live_interval
 static struct stack_slot *
 spill_interval(struct live_interval *interval,
   struct compilation_unit *cu,
-  struct insn *last, bool tail)
+  struct insn *last)
 {
struct stack_slot *slot;
struct insn *spill;
@@ -83,7 +83,7 @@ spill_interval(struct live_interval *interval,
 
spill-bytecode_offset = last-bytecode_offset;
 
-   if (tail)
+   if (insn_is_branch(last))
list_add_tail(spill-insn_list_node, last-insn_list_node);
else
list_add(spill-insn_list_node, last-insn_list_node);
@@ -94,7 +94,7 @@ spill_interval(struct live_interval *interval,
 static int
 insert_spill_insn(struct live_interval *interval, struct compilation_unit *cu)
 {
-   interval-spill_slot = spill_interval(interval, cu, last_insn(cu, 
interval), false);
+   interval-spill_slot = spill_interval(interval, cu, last_insn(cu, 
interval));
 
if (!interval-spill_slot)
return warn(out of memory), -ENOMEM;
@@ -193,7 +193,7 @@ static void insert_mov_insns(struct compilation_unit *cu,
if (from_it-need_spill  from_it-range.end  
from_bb-end_insn) {
slots[i] = from_it-spill_slot;
} else {
-   slots[i] = spill_interval(from_it, cu, spill_at_insn, 
true);
+   slots[i] = spill_interval(from_it, cu, spill_at_insn);
}
}
 
-- 
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


Re: [PATCH 3/3] spill-reload: Use radix_tree_lookup() in insert_mov_insns()

2009-08-18 Thread Tomek Grabiec
2009/8/18 Pekka Enberg penb...@cs.helsinki.fi:
 Lets use radix_tree_lookup() and get rid of the nasty loop in
 bb_last_insn(). For some reason, this seems to fix the infinite loop
 triggered by empty basic blocks.

 Cc: Arthur HUILLET arthur.huil...@free.fr
 Cc: Tomek Grabiec tgrab...@gmail.com
 Signed-off-by: Pekka Enberg penb...@cs.helsinki.fi
 ---
  jit/basic-block.c  |   16 +---
  jit/spill-reload.c |    2 +-
  2 files changed, 2 insertions(+), 16 deletions(-)

 diff --git a/jit/basic-block.c b/jit/basic-block.c
 index 6de5c3f..dbf3675 100644
 --- a/jit/basic-block.c
 +++ b/jit/basic-block.c
 @@ -176,21 +176,7 @@ 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;
 +       return list_entry(bb-insn_list.prev, struct insn, insn_list_node);
  }

  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..515db8a 100644
 --- a/jit/spill-reload.c
 +++ b/jit/spill-reload.c
 @@ -183,7 +183,7 @@ 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   = radix_tree_lookup(cu-lir_insn_map, 
 from_bb-end_insn - 1);

        /* Spill all intervals that have to be resolved */
        for (i = 0; i  nr_mapped; i++) {
 --
 1.5.6.3



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.

-- 
Tomek Grabiec

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


Re: [PATCH 3/3] spill-reload: Use radix_tree_lookup() in insert_mov_insns()

2009-08-18 Thread Pekka Enberg
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