When a live interval ends at a basic block boundary and is spilled, the
spill instruction will appear after the final jump of the basic block.
In that case, bb_last_insn really ought to return the struct insn
corresponding to the jump, not the spill instructions that have been
added afterwards.
This is a bugfix.

Signed-off-by: Arthur HUILLET <arthur.huil...@free.fr>
---
 jit/basic-block.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/jit/basic-block.c b/jit/basic-block.c
index 0a13062..4cd642e 100644
--- a/jit/basic-block.c
+++ b/jit/basic-block.c
@@ -154,7 +154,21 @@ struct insn *bb_first_insn(struct basic_block *bb)
 
 struct insn *bb_last_insn(struct basic_block *bb)
 {
-       return list_entry(bb->insn_list.prev, struct insn, insn_list_node);
+       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;
 }
 
 static int __bb_add_neighbor(void *new, void **array, unsigned long *nb)
-- 
1.6.3.3



------------------------------------------------------------------------------
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to