Patchwork [lra] a patch to fix a live-range splitting problem in EBB

login
register
mail settings
Submitter Vladimir Makarov
Date March 5, 2012, 6:40 p.m.
Message ID <4F5508B8.80908@redhat.com>
Download mbox | patch
Permalink /patch/144746/
State New
Headers show

Comments

Vladimir Makarov - March 5, 2012, 6:40 p.m.
On some targets in rare cases, LRA can put a live-range splitting insn 
right after a jump insn setting up the split pseudo.  The following 
patch fixes the problem by putting such insn at the beginning of next BB.

The patch was successfully bootstrapped on x86/x86-64.

Committed as rev. 184942.

2012-03-05  Vladimir Makarov <vmakarov@redhat.com>

         * lra-constraints.c (simplify_operand_subreg): Treat out subreg
         operand which is a part of the pseudo as in/out one.
         (get_live_on_other_edges): Move lower and add non-input operands
         of jump to the bitmap.

Patch

Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 184749)
+++ lra-constraints.c	(working copy)
@@ -1371,7 +1371,8 @@  simplify_operand_subreg (int nop, enum m
 	= (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS);
 
       if (get_reload_reg (type, reg_mode, reg, rclass, "subreg reg", &new_reg)
-	  && type != OP_OUT)
+	  && (type != OP_OUT
+	      || GET_MODE_SIZE (GET_MODE (reg)) > GET_MODE_SIZE (mode)))
 	{
 	  push_to_sequence (before);
 	  lra_emit_move (new_reg, reg);
@@ -4214,21 +4215,6 @@  add_to_inherit (int regno, rtx insns)
   to_inherit[to_inherit_num++].insns = insns;
 }
 
-/* Set up RES by registers living on edges FROM except edege (FROM,
-   TO).  */
-static void
-get_live_on_other_edges (basic_block from, basic_block to, bitmap res)
-{
-  edge e;
-  edge_iterator ei;
-
-  gcc_assert (to != NULL);
-  bitmap_clear (res);
-  FOR_EACH_EDGE (e, ei, from->succs)
-    if (e->dest != to)
-      bitmap_ior_into (res, DF_LR_IN (e->dest));
-}
-	
 /* Return first (if FIRST_P) or last non-debug insn in basic block BB.
    Return null if there are no non-debug insns in the block.  */
 static rtx
@@ -4245,6 +4231,31 @@  get_non_debug_insn (bool first_p, basic_
   return insn;
 }
 
+/* Set up RES by registers living on edges FROM except edge (FROM, TO)
+   or by registers set up in a jump insn in BB FROM.  */
+static void
+get_live_on_other_edges (basic_block from, basic_block to, bitmap res)
+{
+  int regno;
+  rtx last;
+  struct lra_insn_reg *reg;
+  edge e;
+  edge_iterator ei;
+
+  gcc_assert (to != NULL);
+  bitmap_clear (res);
+  FOR_EACH_EDGE (e, ei, from->succs)
+    if (e->dest != to)
+      bitmap_ior_into (res, DF_LR_IN (e->dest));
+  if ((last = get_non_debug_insn (false, from)) == NULL_RTX || ! JUMP_P (last))
+    return;
+  curr_id = lra_get_insn_recog_data (last);
+  for (reg = curr_id->regs; reg != NULL; reg = reg->next)
+    if (reg->type != OP_IN
+	&& (regno = reg->regno) >= FIRST_PSEUDO_REGISTER)
+      bitmap_set_bit (res, regno);
+}
+	
 /* Used as a temporary results of some bitmap calculations.  */
 static bitmap_head temp_bitmap;