diff mbox

patch to fix PR63897

Message ID 546FAF6E.4020001@redhat.com
State New
Headers show

Commit Message

Vladimir Makarov Nov. 21, 2014, 9:32 p.m. UTC
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  <vmakarov@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.

Comments

H.J. Lu Nov. 25, 2014, 12:23 a.m. UTC | #1
On Fri, Nov 21, 2014 at 1:32 PM, Vladimir Makarov <vmakarov@redhat.com> wrote:
> 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  <vmakarov@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.

This caused:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64061
H.J. Lu Nov. 26, 2014, 11:28 p.m. UTC | #2
On Mon, Nov 24, 2014 at 4:23 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Fri, Nov 21, 2014 at 1:32 PM, Vladimir Makarov <vmakarov@redhat.com> wrote:
>> 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  <vmakarov@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.
>
> This caused:
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64061

This also caused:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64087
diff mbox

Patch

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.  */