The following patch fixes PR63897.  The details can be found on

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63897

The patch was successfully bootstrapped and tested on x86 and x86-64.

Committed as rev. 217947.

2014-11-21  Vladimir Makarov  <vmaka...@redhat.com>

        PR target/63897
        * lra-lives.c (mark_regno_live, mark_regno_dead): Remove last
        argument.
        (process_bb_lives): Rename dead_insn_p on remove_p
        and global_live_info_p on dead_insn_p.  Calculate local live info
        unconditionally.  Remove last argument in calls mark_regno_live and
        mark_regno_dead.  Reorganize body of EXECUTE_IF_SET_IN_BITMAP.
        (lra_create_live_ranges): Rename to lra_create_live_ranges_1.
        Return bool.  Rename global_live_info_p on dead_insn_p.  Return
        flag of live info change.
        (lra_create_live_ranges): New.
Index: lra-lives.c
===================================================================
--- lra-lives.c (revision 217865)
+++ lra-lives.c (working copy)
@@ -321,11 +321,11 @@ mark_pseudo_dead (int regno, int point)
 static bitmap bb_killed_pseudos, bb_gen_pseudos;
 
 /* Mark register REGNO (pseudo or hard register) in MODE as live at
-   program point POINT.  Update BB_GEN_PSEUDOS if LOCAL_SETS_P.
+   program point POINT.  Update BB_GEN_PSEUDOS.
    Return TRUE if the liveness tracking sets were modified, or FALSE
    if nothing changed.  */
 static bool
-mark_regno_live (int regno, machine_mode mode, int point, bool local_sets_p)
+mark_regno_live (int regno, machine_mode mode, int point)
 {
   int last;
   bool changed = false;
@@ -344,19 +344,17 @@ mark_regno_live (int regno, machine_mode
          mark_pseudo_live (regno, point);
          changed = true;
        }
-      if (local_sets_p)
-       bitmap_set_bit (bb_gen_pseudos, regno);
+      bitmap_set_bit (bb_gen_pseudos, regno);
     }
   return changed;
 }
 
 
 /* Mark register REGNO in MODE as dead at program point POINT.  Update
-   BB_GEN_PSEUDOS and BB_KILLED_PSEUDOS if LOCAL_SETS_P.  Return TRUE
-   if the liveness tracking sets were modified, or FALSE if nothing
-   changed.  */
+   BB_GEN_PSEUDOS and BB_KILLED_PSEUDOS.  Return TRUE if the liveness
+   tracking sets were modified, or FALSE if nothing changed.  */
 static bool
-mark_regno_dead (int regno, machine_mode mode, int point, bool local_sets_p)
+mark_regno_dead (int regno, machine_mode mode, int point)
 {
   int last;
   bool changed = false;
@@ -375,11 +373,8 @@ mark_regno_dead (int regno, machine_mode
          mark_pseudo_dead (regno, point);
          changed = true;
        }
-      if (local_sets_p)
-       {
-         bitmap_clear_bit (bb_gen_pseudos, regno);
-         bitmap_set_bit (bb_killed_pseudos, regno);
-       }
+      bitmap_clear_bit (bb_gen_pseudos, regno);
+      bitmap_set_bit (bb_killed_pseudos, regno);
     }
   return changed;
 }
@@ -639,10 +634,10 @@ check_pseudos_live_through_calls (int re
    BB ends.  The function updates this counter and returns in
    CURR_POINT the program point where BB starts.  The function also
    does local live info updates and can delete the dead insns if
-   GLOBAL_LIVE_INFO_P.  It returns true if pseudo live info was
+   DEAD_INSN_P.  It returns true if pseudo live info was
    changed at the BB start.  */
 static bool
-process_bb_lives (basic_block bb, int &curr_point, bool global_live_info_p)
+process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
 {
   int i, regno, freq;
   unsigned int j;
@@ -662,13 +657,10 @@ process_bb_lives (basic_block bb, int &c
   EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
     mark_pseudo_live (j, curr_point);
 
-  if (global_live_info_p)
-    {
-      bb_gen_pseudos = &get_bb_data (bb)->gen_pseudos;
-      bb_killed_pseudos = &get_bb_data (bb)->killed_pseudos;
-      bitmap_clear (bb_gen_pseudos);
-      bitmap_clear (bb_killed_pseudos);
-    }
+  bb_gen_pseudos = &get_bb_data (bb)->gen_pseudos;
+  bb_killed_pseudos = &get_bb_data (bb)->killed_pseudos;
+  bitmap_clear (bb_gen_pseudos);
+  bitmap_clear (bb_killed_pseudos);
   freq = REG_FREQ_FROM_BB (bb);
 
   if (lra_dump_file != NULL)
@@ -701,7 +693,7 @@ process_bb_lives (basic_block bb, int &c
 
       set = single_set (curr_insn);
 
-      if (global_live_info_p && set != NULL_RTX
+      if (dead_insn_p && set != NULL_RTX
          && REG_P (SET_DEST (set)) && REGNO (SET_DEST (set)) >= 
FIRST_PSEUDO_REGISTER
          && find_reg_note (curr_insn, REG_EH_REGION, NULL_RTX) == NULL_RTX
          && ! may_trap_p (PATTERN (curr_insn))
@@ -710,21 +702,21 @@ process_bb_lives (basic_block bb, int &c
          && (pic_offset_table_rtx == NULL_RTX
              || pic_offset_table_rtx != SET_DEST (set)))
        {
-         bool dead_insn_p = true;
+         bool remove_p = true;
 
          for (reg = curr_id->regs; reg != NULL; reg = reg->next)
            if (reg->type != OP_IN && sparseset_bit_p (pseudos_live, 
reg->regno))
              {
-               dead_insn_p = false;
+               remove_p = false;
                break;
              }
          for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
            if (reg->type != OP_IN)
              {
-               dead_insn_p = false;
+               remove_p = false;
                break;
              }
-         if (dead_insn_p && ! volatile_refs_p (PATTERN (curr_insn)))
+         if (remove_p && ! volatile_refs_p (PATTERN (curr_insn)))
            {
              dst_regno = REGNO (SET_DEST (set));
              if (lra_dump_file != NULL)
@@ -818,7 +810,7 @@ process_bb_lives (basic_block bb, int &c
          {
            need_curr_point_incr
              |= mark_regno_live (reg->regno, reg->biggest_mode,
-                                 curr_point, global_live_info_p);
+                                 curr_point);
            check_pseudos_live_through_calls (reg->regno);
          }
 
@@ -835,7 +827,7 @@ process_bb_lives (basic_block bb, int &c
        if (reg->type == OP_OUT && ! reg->early_clobber && ! reg->subreg_p)
          need_curr_point_incr
            |= mark_regno_dead (reg->regno, reg->biggest_mode,
-                               curr_point, global_live_info_p);
+                               curr_point);
 
       for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
        if (reg->type == OP_OUT && ! reg->early_clobber && ! reg->subreg_p)
@@ -877,7 +869,7 @@ process_bb_lives (basic_block bb, int &c
          {
            need_curr_point_incr
              |= mark_regno_live (reg->regno, reg->biggest_mode,
-                                 curr_point, global_live_info_p);
+                                 curr_point);
            check_pseudos_live_through_calls (reg->regno);
          }
 
@@ -897,7 +889,7 @@ process_bb_lives (basic_block bb, int &c
        if (reg->type == OP_OUT && reg->early_clobber && ! reg->subreg_p)
          need_curr_point_incr
            |= mark_regno_dead (reg->regno, reg->biggest_mode,
-                               curr_point, global_live_info_p);
+                               curr_point);
 
       for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
        if (reg->type == OP_OUT && reg->early_clobber && ! reg->subreg_p)
@@ -971,25 +963,22 @@ process_bb_lives (basic_block bb, int &c
     }
 
   bool live_change_p = false;
-  if (global_live_info_p)
+  /* Check if bb border live info was changed.  */
+  unsigned int live_pseudos_num = 0;
+  EXECUTE_IF_SET_IN_BITMAP (df_get_live_in (bb),
+                           FIRST_PSEUDO_REGISTER, j, bi)
     {
-      /* Check if bb border live info was changed.  */
-      unsigned int live_pseudos_num = 0;
-      EXECUTE_IF_SET_IN_BITMAP (df_get_live_in (bb),
-                               FIRST_PSEUDO_REGISTER, j, bi)
+      live_pseudos_num++;
+      if (! sparseset_bit_p (pseudos_live, j))
        {
-         live_pseudos_num++;
-         if (! sparseset_bit_p (pseudos_live, j))
-           {
-             live_change_p = TRUE;
-             break;
-           }
+         live_change_p = TRUE;
+         break;
        }
-      live_change_p
-       = (live_change_p
-          || sparseset_cardinality (pseudos_live) != live_pseudos_num);
     }
-
+  live_change_p
+    = (live_change_p
+       || sparseset_cardinality (pseudos_live) != live_pseudos_num);
+  
   /* See if we'll need an increment at the end of this basic block.
      An increment is needed if the PSEUDOS_LIVE set is not empty,
      to make sure the finish points are set up correctly.  */
@@ -1180,13 +1169,14 @@ compress_live_ranges (void)
 /* The number of the current live range pass.  */
 int lra_live_range_iter;
 
-/* The main entry function creates live ranges only for memory pseudos
-   (or for all ones if ALL_P), set up CONFLICT_HARD_REGS for the
-   pseudos.  It also does dead insn elimination and global live
-   analysis only for pseudos and only if GLOBAL_LIVE_INFO_P and the
-   pseudo live info was changed on a BB border.  */
-void
-lra_create_live_ranges (bool all_p, bool global_live_info_p)
+/* The function creates live ranges only for memory pseudos (or for
+   all ones if ALL_P), set up CONFLICT_HARD_REGS for the pseudos.  It
+   also does dead insn elimination if DEAD_INSN_P and global live
+   analysis only for pseudos and only if the pseudo live info was
+   changed on a BB border.  Return TRUE if the live info was
+   changed.  */
+static bool
+lra_create_live_ranges_1 (bool all_p, bool dead_insn_p)
 {
   basic_block bb;
   int i, hard_regno, max_regno = max_reg_num ();
@@ -1239,7 +1229,7 @@ lra_create_live_ranges (bool all_p, bool
   if (! have_referenced_pseudos)
     {
       timevar_pop (TV_LRA_CREATE_LIVE_RANGES);
-      return;
+      return false;
     }
 
   pseudos_live = sparseset_alloc (max_regno);
@@ -1262,7 +1252,7 @@ lra_create_live_ranges (bool all_p, bool
       if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun) || bb
          == ENTRY_BLOCK_PTR_FOR_FN (cfun))
        continue;
-      if (process_bb_lives (bb, curr_point, global_live_info_p))
+      if (process_bb_lives (bb, curr_point, dead_insn_p))
        bb_live_change_p = true;
     }
   if (bb_live_change_p)
@@ -1317,6 +1307,27 @@ lra_create_live_ranges (bool all_p, bool
   sparseset_free (pseudos_live);
   compress_live_ranges ();
   timevar_pop (TV_LRA_CREATE_LIVE_RANGES);
+  return bb_live_change_p;
+}
+
+/* The main entry function creates live-ranges and other live info
+   necessary for the assignment sub-pass.  It uses
+   lra_creates_live_ranges_1 -- so read comments for the
+   function.  */
+void
+lra_create_live_ranges (bool all_p, bool dead_insn_p)
+{
+  if (! lra_create_live_ranges_1 (all_p, dead_insn_p))
+    return;
+  if (lra_dump_file != NULL)
+    fprintf (lra_dump_file, "Live info was changed -- recalculate it\n");
+  /* Live info was changed on a bb border.  It means that some info,
+     e.g. about conflict regs, calls crossed may be wrong, live
+     ranges.  We need this info for allocation.  So recalcualate it
+     again.  */
+  lra_clear_live_ranges ();
+  bool res = lra_create_live_ranges_1 (all_p, dead_insn_p);
+  lra_assert (! res);
 }
 
 /* Finish all live ranges.  */

Reply via email to