The patch reverses a fix for PR117248 because it adds new failures in libgo test on arm (PR117999).

I'll fix PR117248 with another patch soon which will not result in PR117999.


commit 1a28ff1c01c290d50fb4ebd6e6a49482195cab9c
Author: Vladimir N. Makarov <vmaka...@redhat.com>
Date:   Wed Dec 18 13:28:43 2024 -0500

    Revert "[PR117248][LRA]: Rewriting reg notes update and fix calculation of conflict hard regs of pseudo."
    
    This reverts commit 75e7d1600f47859df40b2ac0feff5a71e0dbb040.

diff --git a/gcc/lra-lives.cc b/gcc/lra-lives.cc
index 6286c5ad5a8..510f7d927ab 100644
--- a/gcc/lra-lives.cc
+++ b/gcc/lra-lives.cc
@@ -84,10 +84,10 @@ static sparseset pseudos_live_through_setjumps;
 /* Set of hard regs (except eliminable ones) currently live.  */
 static HARD_REG_SET hard_regs_live;
 
-/* Set of pseudos and hard registers in the current insn, only out/inout ones,
-   and the current insn pseudos and hard registers living right after the
-   insn.  */
-static sparseset insn_regnos, out_insn_regnos, insn_regnos_live_after;
+/* Set of pseudos and hard registers start living/dying in the current
+   insn.  These sets are used to update REG_DEAD and REG_UNUSED notes
+   in the insn.  */
+static sparseset start_living, start_dying;
 
 /* Set of pseudos and hard regs dead and unused in the current
    insn.  */
@@ -228,6 +228,17 @@ enum point_type {
   USE_POINT
 };
 
+/* Return TRUE if set A contains a pseudo register, otherwise, return FALSE.  */
+static bool
+sparseset_contains_pseudos_p (sparseset a)
+{
+  int regno;
+  EXECUTE_IF_SET_IN_SPARSESET (a, regno)
+    if (!HARD_REGISTER_NUM_P (regno))
+      return true;
+  return false;
+}
+
 /* Mark pseudo REGNO as living or dying at program point POINT, depending on
    whether TYPE is a definition or a use.  If this is the first reference to
    REGNO that we've encountered, then create a new live range for it.  */
@@ -266,29 +277,29 @@ update_pseudo_point (int regno, int point, enum point_type type)
 /* The corresponding bitmaps of BB currently being processed.  */
 static bitmap bb_killed_pseudos, bb_gen_pseudos;
 
-/* Record hard register REGNO as now being live.  Return true if REGNO liveness
-   changes.  */
-static bool
+/* Record hard register REGNO as now being live.  It updates
+   living hard regs and START_LIVING.  */
+static void
 make_hard_regno_live (int regno)
 {
   lra_assert (HARD_REGISTER_NUM_P (regno));
   if (TEST_HARD_REG_BIT (hard_regs_live, regno)
       || TEST_HARD_REG_BIT (eliminable_regset, regno))
-    return false;
+    return;
   SET_HARD_REG_BIT (hard_regs_live, regno);
+  sparseset_set_bit (start_living, regno);
   if (fixed_regs[regno] || TEST_HARD_REG_BIT (hard_regs_spilled_into, regno))
     bitmap_set_bit (bb_gen_pseudos, regno);
-  return true;
 }
 
-/* Process the definition of hard register REGNO.  This updates hard_regs_live
-   and conflict hard regs for living pseudos.  Return true if REGNO liveness
-   changes.  */
-static bool
+/* Process the definition of hard register REGNO.  This updates
+   hard_regs_live, START_DYING and conflict hard regs for living
+   pseudos.  */
+static void
 make_hard_regno_dead (int regno)
 {
   if (TEST_HARD_REG_BIT (eliminable_regset, regno))
-    return false;
+    return;
 
   lra_assert (HARD_REGISTER_NUM_P (regno));
   unsigned int i;
@@ -296,89 +307,79 @@ make_hard_regno_dead (int regno)
     SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno);
 
   if (! TEST_HARD_REG_BIT (hard_regs_live, regno))
-    return false;
+    return;
   CLEAR_HARD_REG_BIT (hard_regs_live, regno);
+  sparseset_set_bit (start_dying, regno);
   if (fixed_regs[regno] || TEST_HARD_REG_BIT (hard_regs_spilled_into, regno))
     {
       bitmap_clear_bit (bb_gen_pseudos, regno);
       bitmap_set_bit (bb_killed_pseudos, regno);
     }
-  return true;
 }
 
-/* Mark pseudo REGNO as now being live.  Return true if REGNO liveness
-   changes.  */
-static bool
+/* Mark pseudo REGNO as now being live and update START_LIVING.  */
+static void
 mark_pseudo_live (int regno)
 {
   lra_assert (!HARD_REGISTER_NUM_P (regno));
   if (sparseset_bit_p (pseudos_live, regno))
-    return false;
+    return;
+
   sparseset_set_bit (pseudos_live, regno);
-  return true;
+  sparseset_set_bit (start_living, regno);
 }
 
-/* Mark pseudo REGNO as now being dead.  Return true if REGNO liveness
-   changes.  */
-static bool
+/* Mark pseudo REGNO as now being dead and update START_DYING.  */
+static void
 mark_pseudo_dead (int regno)
 {
   lra_assert (!HARD_REGISTER_NUM_P (regno));
   lra_reg_info[regno].conflict_hard_regs |= hard_regs_live;
   if (!sparseset_bit_p (pseudos_live, regno))
-    return false;
+    return;
 
   sparseset_clear_bit (pseudos_live, regno);
-  return true;
+  sparseset_set_bit (start_dying, regno);
 }
 
-/* Mark register REGNO (pseudo or hard register) in MODE as being live and
-   update BB_GEN_PSEUDOS.  Return true if REGNO liveness changes.  */
-static bool
+/* Mark register REGNO (pseudo or hard register) in MODE as being live
+   and update BB_GEN_PSEUDOS.  */
+static void
 mark_regno_live (int regno, machine_mode mode)
 {
   int last;
-  bool change_p = false;
 
   if (HARD_REGISTER_NUM_P (regno))
     {
       for (last = end_hard_regno (mode, regno); regno < last; regno++)
-	if (make_hard_regno_live (regno))
-	  change_p = true;
+	make_hard_regno_live (regno);
     }
   else
     {
-      if (mark_pseudo_live (regno))
-	change_p = true;
+      mark_pseudo_live (regno);
       bitmap_set_bit (bb_gen_pseudos, regno);
     }
-  return change_p;
 }
 
 
-/* Mark register REGNO (pseudo or hard register) in MODE as being dead and
-   update BB_GEN_PSEUDOS and BB_KILLED_PSEUDOS.  Return true if REGNO liveness
-   changes.  */
-static bool
+/* Mark register REGNO (pseudo or hard register) in MODE as being dead
+   and update BB_GEN_PSEUDOS and BB_KILLED_PSEUDOS.  */
+static void
 mark_regno_dead (int regno, machine_mode mode)
 {
   int last;
-  bool change_p = false;
 
   if (HARD_REGISTER_NUM_P (regno))
     {
       for (last = end_hard_regno (mode, regno); regno < last; regno++)
-	if (make_hard_regno_dead (regno))
-	  change_p = true;
+	make_hard_regno_dead (regno);
     }
   else
     {
-      if (mark_pseudo_dead (regno))
-	change_p = true;
+      mark_pseudo_dead (regno);
       bitmap_clear_bit (bb_gen_pseudos, regno);
       bitmap_set_bit (bb_killed_pseudos, regno);
     }
-  return change_p;
 }
 
 
@@ -622,7 +623,7 @@ clear_sparseset_regnos (sparseset set, int regno, enum machine_mode mode)
 {
   if (regno >= FIRST_PSEUDO_REGISTER)
     {
-      sparseset_clear_bit (set, regno);
+      sparseset_clear_bit (dead_set, regno);
       return;
     }
   for (int last = end_hard_regno (mode, regno); regno < last; regno++)
@@ -635,7 +636,7 @@ static bool
 regnos_in_sparseset_p (sparseset set, int regno, enum machine_mode mode)
 {
   if (regno >= FIRST_PSEUDO_REGISTER)
-    return sparseset_bit_p (set, regno);
+    return sparseset_bit_p (dead_set, regno);
   for (int last = end_hard_regno (mode, regno); regno < last; regno++)
     if (!sparseset_bit_p (set, regno))
       return false;
@@ -852,46 +853,8 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
 	      (regno, hard_regno, freq);
 	}
 
-      sparseset_clear (insn_regnos_live_after);
-      sparseset_clear (insn_regnos);
-      sparseset_clear (out_insn_regnos);
-
-      for (reg = curr_id->regs; reg != NULL; reg = reg->next)
-	{
-	  if (!HARD_REGISTER_NUM_P (reg->regno))
-	    {
-	      sparseset_set_bit (insn_regnos, reg->regno);
-	      if (reg->type != OP_IN)
-		sparseset_set_bit (out_insn_regnos, reg->regno);
-	      if (sparseset_bit_p (pseudos_live, reg->regno))
-		sparseset_set_bit (insn_regnos_live_after, reg->regno);
-	    }
-	  else
-	    {
-	      for (int regno = reg->regno,
-		     last = end_hard_regno (reg->biggest_mode, regno);
-		   regno < last;
-		   regno++)
-		{
-		  sparseset_set_bit (insn_regnos, regno);
-		  if (reg->type != OP_IN)
-		    sparseset_set_bit (out_insn_regnos, regno);
-		  if (TEST_HARD_REG_BIT (hard_regs_live, regno))
-		    sparseset_set_bit (insn_regnos_live_after, regno);
-		}
-	    }
-	}
-
-      for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
-	{
-	  sparseset_set_bit (insn_regnos, reg->regno);
-	  if (reg->type != OP_IN)
-	    sparseset_set_bit (out_insn_regnos, reg->regno);
-	  if (TEST_HARD_REG_BIT (hard_regs_live, reg->regno))
-	    sparseset_set_bit (insn_regnos_live_after, reg->regno);
-	}
+      sparseset_clear (start_living);
 
-      bool next_point_p = false;
       /* Mark each defined value as live.  We need to do this for
 	 unused values because they still conflict with quantities
 	 that are live at the time of the definition.  */
@@ -899,21 +862,24 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
 	if (reg->type != OP_IN)
 	  {
 	    update_pseudo_point (reg->regno, curr_point, USE_POINT);
-	    if (mark_regno_live (reg->regno, reg->biggest_mode))
-	      next_point_p = true;
+	    mark_regno_live (reg->regno, reg->biggest_mode);
 	    /* ??? Should be a no-op for unused registers.  */
 	    check_pseudos_live_through_calls (reg->regno, last_call_abi);
 	  }
 
       for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
-	if (reg->type != OP_IN && make_hard_regno_live (reg->regno))
-	  next_point_p = true;
+	if (reg->type != OP_IN)
+	  make_hard_regno_live (reg->regno);
 
       if (curr_id->arg_hard_regs != NULL)
 	for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++)
-	  if (!HARD_REGISTER_NUM_P (regno) /* It is a clobber.  */
-	      && make_hard_regno_live (regno - FIRST_PSEUDO_REGISTER))
-	    next_point_p = true;
+	  if (!HARD_REGISTER_NUM_P (regno))
+	    /* It is a clobber.  */
+	    make_hard_regno_live (regno - FIRST_PSEUDO_REGISTER);
+
+      sparseset_copy (unused_set, start_living);
+
+      sparseset_clear (start_dying);
 
       /* See which defined values die here.  */
       for (reg = curr_id->regs; reg != NULL; reg = reg->next)
@@ -922,21 +888,19 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
 	  {
 	    if (reg->type == OP_OUT)
 	      update_pseudo_point (reg->regno, curr_point, DEF_POINT);
-	    if (mark_regno_dead (reg->regno, reg->biggest_mode))
-	      next_point_p = true;
+	    mark_regno_dead (reg->regno, reg->biggest_mode);
 	  }
 
       for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
 	if (reg->type != OP_IN
-	    && ! reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p
-	    && make_hard_regno_dead (reg->regno))
-	  next_point_p = true;
+	    && ! reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p)
+	  make_hard_regno_dead (reg->regno);
 
       if (curr_id->arg_hard_regs != NULL)
 	for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++)
-	  if (!HARD_REGISTER_NUM_P (regno) /* It is a clobber.  */
-	      && make_hard_regno_dead (regno - FIRST_PSEUDO_REGISTER))
-	    next_point_p = true;
+	  if (!HARD_REGISTER_NUM_P (regno))
+	    /* It is a clobber.  */
+	    make_hard_regno_dead (regno - FIRST_PSEUDO_REGISTER);
 
       if (call_p)
 	{
@@ -959,11 +923,13 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
 	}
 
       /* Increment the current program point if we must.  */
-      if (next_point_p)
+      if (sparseset_contains_pseudos_p (unused_set)
+	  || sparseset_contains_pseudos_p (start_dying))
 	next_program_point (curr_point, freq);
 
       /* If we removed the source reg from a simple register copy from the
-	 live set above, then add it back now.  */
+	 live set above, then add it back now so we don't accidentally add
+	 it to the start_living set below.  */
       if (ignore_reg != NULL_RTX)
 	{
 	  int ignore_regno = REGNO (ignore_reg);
@@ -973,27 +939,31 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
 	    sparseset_set_bit (pseudos_live, ignore_regno);
 	}
 
-      next_point_p = false;
+      sparseset_clear (start_living);
+
       /* Mark each used value as live.	*/
       for (reg = curr_id->regs; reg != NULL; reg = reg->next)
 	if (reg->type != OP_OUT)
 	  {
 	    if (reg->type == OP_IN)
 	      update_pseudo_point (reg->regno, curr_point, USE_POINT);
-	    if (mark_regno_live (reg->regno, reg->biggest_mode))
-	      next_point_p = true;
+	    mark_regno_live (reg->regno, reg->biggest_mode);
 	    check_pseudos_live_through_calls (reg->regno, last_call_abi);
 	  }
 
       for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
-	if (reg->type != OP_OUT && make_hard_regno_live (reg->regno))
-	  next_point_p = true;
+	if (reg->type != OP_OUT)
+	  make_hard_regno_live (reg->regno);
 
       if (curr_id->arg_hard_regs != NULL)
 	/* Make argument hard registers live.  */
 	for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++)
-	  if (HARD_REGISTER_NUM_P (regno) && make_hard_regno_live (regno))
-	    next_point_p = true;
+	  if (HARD_REGISTER_NUM_P (regno))
+	    make_hard_regno_live (regno);
+
+      sparseset_and_compl (dead_set, start_living, start_dying);
+
+      sparseset_clear (start_dying);
 
       /* Mark early clobber outputs dead.  */
       for (reg = curr_id->regs; reg != NULL; reg = reg->next)
@@ -1002,14 +972,12 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
 	  {
 	    if (reg->type == OP_OUT)
 	      update_pseudo_point (reg->regno, curr_point, DEF_POINT);
-	    if (mark_regno_dead (reg->regno, reg->biggest_mode))
-	      next_point_p = true;
+	    mark_regno_dead (reg->regno, reg->biggest_mode);
 
 	    /* We're done processing inputs, so make sure early clobber
 	       operands that are both inputs and outputs are still live.  */
-	    if (reg->type == OP_INOUT
-		&& mark_regno_live (reg->regno, reg->biggest_mode))
-	      next_point_p = true;
+	    if (reg->type == OP_INOUT)
+	      mark_regno_live (reg->regno, reg->biggest_mode);
 	  }
 
       for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
@@ -1021,59 +989,29 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
 	    /* We can have early clobbered non-operand hard reg and
 	       the same hard reg as an insn input.  Don't make hard
 	       reg dead before the insns.  */
-	    for (reg2 = curr_static_id->hard_regs;
-		 reg2 != NULL;
-		 reg2 = reg2->next)
+	    for (reg2 = curr_static_id->hard_regs; reg2 != NULL; reg2 = reg2->next)
 	      if (reg2->type != OP_OUT && reg2->regno == reg->regno)
 		break;
+	    if (reg2 != NULL)
+	      continue;
+
+	    HARD_REG_SET clobbered_regset;
+	    CLEAR_HARD_REG_SET (clobbered_regset);
+	    SET_HARD_REG_BIT (clobbered_regset, reg->regno);
+
+	    for (reg2 = curr_id->regs; reg2 != NULL; reg2 = reg2->next)
+	      if (reg2->type != OP_OUT && reg2->regno < FIRST_PSEUDO_REGISTER
+		  && ira_hard_reg_set_intersection_p (reg2->regno,
+						      reg2->biggest_mode,
+						      clobbered_regset))
+		break;
 	    if (reg2 == NULL)
-	      {
-		HARD_REG_SET clobbered_regset;
-		CLEAR_HARD_REG_SET (clobbered_regset);
-		SET_HARD_REG_BIT (clobbered_regset, reg->regno);
-
-		for (reg2 = curr_id->regs; reg2 != NULL; reg2 = reg2->next)
-		  if (reg2->type != OP_OUT && HARD_REGISTER_NUM_P (reg2->regno)
-		      && ira_hard_reg_set_intersection_p (reg2->regno,
-							  reg2->biggest_mode,
-							  clobbered_regset))
-		    break;
-		if (reg2 == NULL)
-		  {
-		    if (make_hard_regno_dead (reg->regno))
-		      next_point_p = true;
-		  }
-		else
-		  {
-		    EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, j)
-		      SET_HARD_REG_BIT (lra_reg_info[j].conflict_hard_regs,
-					reg->regno);
-		  }
-	      }
+	      make_hard_regno_dead (reg->regno);
 	  }
 
-      sparseset_clear (dead_set);
-      sparseset_clear (unused_set);
-      EXECUTE_IF_SET_IN_SPARSESET (insn_regnos, j)
-	{
-	  if (sparseset_bit_p (insn_regnos_live_after, j))
-	    continue;
-	  if (!HARD_REGISTER_NUM_P (j))
-	    {
-	      if (sparseset_bit_p (pseudos_live, j))
-		sparseset_set_bit (dead_set, j);
-	    }
-	  else
-	    {
-	      if (TEST_HARD_REG_BIT (hard_regs_live, j))
-		sparseset_set_bit (dead_set, j);
-	    }
-	  if (sparseset_bit_p (out_insn_regnos, j))
-	    sparseset_set_bit (unused_set, j);
-	}
-
       /* Increment the current program point if we must.  */
-      if (next_point_p)
+      if (sparseset_contains_pseudos_p (dead_set)
+	  || sparseset_contains_pseudos_p (start_dying))
 	next_program_point (curr_point, freq);
 
       /* Update notes.	*/
@@ -1106,16 +1044,10 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
 	    }
 	  link_loc = &XEXP (link, 1);
 	}
-      EXECUTE_IF_SET_IN_SPARSESET (unused_set, j)
-	{
-	  gcc_assert (find_regno_note (curr_insn, REG_UNUSED, j) == NULL_RTX);
-	  add_reg_note (curr_insn, REG_UNUSED, regno_reg_rtx[j]);
-	}
       EXECUTE_IF_SET_IN_SPARSESET (dead_set, j)
-	{
-	  gcc_assert (find_regno_note (curr_insn, REG_DEAD, j) == NULL_RTX);
-	  add_reg_note (curr_insn, REG_DEAD, regno_reg_rtx[j]);
-	}
+	add_reg_note (curr_insn, REG_DEAD, regno_reg_rtx[j]);
+      EXECUTE_IF_SET_IN_SPARSESET (unused_set, j)
+	add_reg_note (curr_insn, REG_UNUSED, regno_reg_rtx[j]);
     }
 
   if (bb_has_eh_pred (bb))
@@ -1477,9 +1409,8 @@ lra_create_live_ranges_1 (bool all_p, bool dead_insn_p)
   pseudos_live = sparseset_alloc (max_regno);
   pseudos_live_through_calls = sparseset_alloc (max_regno);
   pseudos_live_through_setjumps = sparseset_alloc (max_regno);
-  insn_regnos = sparseset_alloc (max_regno);
-  out_insn_regnos = sparseset_alloc (max_regno);
-  insn_regnos_live_after = sparseset_alloc (max_regno);
+  start_living = sparseset_alloc (max_regno);
+  start_dying = sparseset_alloc (max_regno);
   dead_set = sparseset_alloc (max_regno);
   unused_set = sparseset_alloc (max_regno);
   curr_point = 0;
@@ -1550,9 +1481,8 @@ lra_create_live_ranges_1 (bool all_p, bool dead_insn_p)
   /* Clean up.	*/
   sparseset_free (unused_set);
   sparseset_free (dead_set);
-  sparseset_free (insn_regnos);
-  sparseset_free (out_insn_regnos);
-  sparseset_free (insn_regnos_live_after);
+  sparseset_free (start_dying);
+  sparseset_free (start_living);
   sparseset_free (pseudos_live_through_calls);
   sparseset_free (pseudos_live_through_setjumps);
   sparseset_free (pseudos_live);

Reply via email to