Patchwork patch to fix a bug in LRA hard reg splitting

login
register
mail settings
Submitter Vladimir Makarov
Date June 27, 2013, 4:22 p.m.
Message ID <51CC66D6.5060606@redhat.com>
Download mbox | patch
Permalink /patch/255107/
State New
Headers show

Comments

Vladimir Makarov - June 27, 2013, 4:22 p.m.
The following patch fixes a LRA bug for some experimental target. 
Sorry, there is no a test case and the bug can not be reproduced by
other people until the target is made public. 

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

Committed as rev. 200475.

2013-06-27  Vladimir Makarov  <vmakarov@redhat.com>

        * lra-constraints.c (inherit_in_ebb): Process static hard regs
        too.  Process OP_INOUT regs for splitting too.

Patch

Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 200425)
+++ lra-constraints.c	(working copy)
@@ -4762,76 +4762,81 @@  inherit_in_ebb (rtx head, rtx tail)
 	}
       else if (INSN_P (curr_insn))
 	{
+	  int iter;
 	  int max_uid = get_max_uid ();
 
 	  curr_id = lra_get_insn_recog_data (curr_insn);
+	  curr_static_id = curr_id->insn_static_data;
 	  to_inherit_num = 0;
 	  /* Process insn definitions.	*/
-	  for (reg = curr_id->regs; reg != NULL; reg = reg->next)
-	    if (reg->type != OP_IN
-		&& (dst_regno = reg->regno) < lra_constraint_new_regno_start)
-	      {
-		if (dst_regno >= FIRST_PSEUDO_REGISTER && reg->type == OP_OUT
-		    && reg_renumber[dst_regno] < 0 && ! reg->subreg_p
-		    && usage_insns[dst_regno].check == curr_usage_insns_check
-		    && (next_usage_insns
-			= usage_insns[dst_regno].insns) != NULL_RTX)
-		  {
-		    struct lra_insn_reg *r;
+	  for (iter = 0; iter < 2; iter++)
+	    for (reg = iter == 0 ? curr_id->regs : curr_static_id->hard_regs;
+		 reg != NULL;
+		 reg = reg->next)
+	      if (reg->type != OP_IN
+		  && (dst_regno = reg->regno) < lra_constraint_new_regno_start)
+		{
+		  if (dst_regno >= FIRST_PSEUDO_REGISTER && reg->type == OP_OUT
+		      && reg_renumber[dst_regno] < 0 && ! reg->subreg_p
+		      && usage_insns[dst_regno].check == curr_usage_insns_check
+		      && (next_usage_insns
+			  = usage_insns[dst_regno].insns) != NULL_RTX)
+		    {
+		      struct lra_insn_reg *r;
 
-		    for (r = curr_id->regs; r != NULL; r = r->next)
-		      if (r->type != OP_OUT && r->regno == dst_regno)
-			break;
-		    /* Don't do inheritance if the pseudo is also
-		       used in the insn.  */
-		    if (r == NULL)
-		      /* We can not do inheritance right now
-			 because the current insn reg info (chain
-			 regs) can change after that.  */
-		      add_to_inherit (dst_regno, next_usage_insns);
-		  }
-		/* We can not process one reg twice here because of
-		   usage_insns invalidation.  */
-		if ((dst_regno < FIRST_PSEUDO_REGISTER
-		     || reg_renumber[dst_regno] >= 0)
-		    && ! reg->subreg_p && reg->type == OP_OUT)
-		  {
-		    HARD_REG_SET s;
+		      for (r = curr_id->regs; r != NULL; r = r->next)
+			if (r->type != OP_OUT && r->regno == dst_regno)
+			  break;
+		      /* Don't do inheritance if the pseudo is also
+			 used in the insn.  */
+		      if (r == NULL)
+			/* We can not do inheritance right now
+			   because the current insn reg info (chain
+			   regs) can change after that.  */
+			add_to_inherit (dst_regno, next_usage_insns);
+		    }
+		  /* We can not process one reg twice here because of
+		     usage_insns invalidation.  */
+		  if ((dst_regno < FIRST_PSEUDO_REGISTER
+		       || reg_renumber[dst_regno] >= 0)
+		    && ! reg->subreg_p && reg->type != OP_IN)
+		    {
+		      HARD_REG_SET s;
 
-		    if (split_if_necessary (dst_regno, reg->biggest_mode,
-					    potential_reload_hard_regs,
-					    false, curr_insn, max_uid))
-		      change_p = true;
-		    CLEAR_HARD_REG_SET (s);
-		    if (dst_regno < FIRST_PSEUDO_REGISTER)
-		      add_to_hard_reg_set (&s, reg->biggest_mode, dst_regno);
-		    else
-		      add_to_hard_reg_set (&s, PSEUDO_REGNO_MODE (dst_regno),
-					   reg_renumber[dst_regno]);
-		    AND_COMPL_HARD_REG_SET (live_hard_regs, s);
-		  }
-		/* We should invalidate potential inheritance or
-		   splitting for the current insn usages to the next
-		   usage insns (see code below) as the output pseudo
-		   prevents this.  */
-		if ((dst_regno >= FIRST_PSEUDO_REGISTER
-		     && reg_renumber[dst_regno] < 0)
-		    || (reg->type == OP_OUT && ! reg->subreg_p
-			&& (dst_regno < FIRST_PSEUDO_REGISTER
-			    || reg_renumber[dst_regno] >= 0)))
-		  {
-		    /* Invalidate and mark definitions.  */
-		    if (dst_regno >= FIRST_PSEUDO_REGISTER)
-		      usage_insns[dst_regno].check = -(int) INSN_UID (curr_insn);
-		    else
-		      {
-			nregs = hard_regno_nregs[dst_regno][reg->biggest_mode];
-			for (i = 0; i < nregs; i++)
-			  usage_insns[dst_regno + i].check
-			    = -(int) INSN_UID (curr_insn);
-		      }
-		  }
-	      }
+		      if (split_if_necessary (dst_regno, reg->biggest_mode,
+					      potential_reload_hard_regs,
+					      false, curr_insn, max_uid))
+			change_p = true;
+		      CLEAR_HARD_REG_SET (s);
+		      if (dst_regno < FIRST_PSEUDO_REGISTER)
+			add_to_hard_reg_set (&s, reg->biggest_mode, dst_regno);
+		      else
+			add_to_hard_reg_set (&s, PSEUDO_REGNO_MODE (dst_regno),
+					     reg_renumber[dst_regno]);
+		      AND_COMPL_HARD_REG_SET (live_hard_regs, s);
+		    }
+		  /* We should invalidate potential inheritance or
+		     splitting for the current insn usages to the next
+		     usage insns (see code below) as the output pseudo
+		     prevents this.  */
+		  if ((dst_regno >= FIRST_PSEUDO_REGISTER
+		       && reg_renumber[dst_regno] < 0)
+		      || (reg->type == OP_OUT && ! reg->subreg_p
+			  && (dst_regno < FIRST_PSEUDO_REGISTER
+			      || reg_renumber[dst_regno] >= 0)))
+		    {
+		      /* Invalidate and mark definitions.  */
+		      if (dst_regno >= FIRST_PSEUDO_REGISTER)
+			usage_insns[dst_regno].check = -(int) INSN_UID (curr_insn);
+		      else
+			{
+			  nregs = hard_regno_nregs[dst_regno][reg->biggest_mode];
+			  for (i = 0; i < nregs; i++)
+			    usage_insns[dst_regno + i].check
+			      = -(int) INSN_UID (curr_insn);
+			}
+		    }
+		}
 	  if (! JUMP_P (curr_insn))
 	    for (i = 0; i < to_inherit_num; i++)
 	      if (inherit_reload_reg (true, to_inherit[i].regno,
@@ -4876,59 +4881,62 @@  inherit_in_ebb (rtx head, rtx tail)
 	    }
 	  to_inherit_num = 0;
 	  /* Process insn usages.  */
-	  for (reg = curr_id->regs; reg != NULL; reg = reg->next)
-	    if ((reg->type != OP_OUT
-		 || (reg->type == OP_OUT && reg->subreg_p))
-		&& (src_regno = reg->regno) < lra_constraint_new_regno_start)
-	      {
-		if (src_regno >= FIRST_PSEUDO_REGISTER
-		    && reg_renumber[src_regno] < 0 && reg->type == OP_IN)
-		  {
-		    if (usage_insns[src_regno].check == curr_usage_insns_check
-			&& (next_usage_insns
-			    = usage_insns[src_regno].insns) != NULL_RTX
-			&& NONDEBUG_INSN_P (curr_insn))
-		      add_to_inherit (src_regno, next_usage_insns);
-		    else if (usage_insns[src_regno].check
-			     != -(int) INSN_UID (curr_insn))
-                      /* Add usages but only if the reg is not set up
-                         in the same insn.  */
-		      add_next_usage_insn (src_regno, curr_insn, reloads_num);
-		  }
-		else if (src_regno < FIRST_PSEUDO_REGISTER
-			 || reg_renumber[src_regno] >= 0)
-		  {
-		    bool before_p;
-		    rtx use_insn = curr_insn;
+	  for (iter = 0; iter < 2; iter++)
+	    for (reg = iter == 0 ? curr_id->regs : curr_static_id->hard_regs;
+		 reg != NULL;
+		 reg = reg->next)
+	      if ((reg->type != OP_OUT
+		   || (reg->type == OP_OUT && reg->subreg_p))
+		  && (src_regno = reg->regno) < lra_constraint_new_regno_start)
+		{
+		  if (src_regno >= FIRST_PSEUDO_REGISTER
+		      && reg_renumber[src_regno] < 0 && reg->type == OP_IN)
+		    {
+		      if (usage_insns[src_regno].check == curr_usage_insns_check
+			  && (next_usage_insns
+			      = usage_insns[src_regno].insns) != NULL_RTX
+			  && NONDEBUG_INSN_P (curr_insn))
+			add_to_inherit (src_regno, next_usage_insns);
+		      else if (usage_insns[src_regno].check
+			       != -(int) INSN_UID (curr_insn))
+			/* Add usages but only if the reg is not set up
+			   in the same insn.  */
+			add_next_usage_insn (src_regno, curr_insn, reloads_num);
+		    }
+		  else if (src_regno < FIRST_PSEUDO_REGISTER
+			   || reg_renumber[src_regno] >= 0)
+		    {
+		      bool before_p;
+		      rtx use_insn = curr_insn;
 
-		    before_p = (JUMP_P (curr_insn)
-				|| (CALL_P (curr_insn) && reg->type == OP_IN));
-		    if (NONDEBUG_INSN_P (curr_insn)
-			&& split_if_necessary (src_regno, reg->biggest_mode,
-					       potential_reload_hard_regs,
-					       before_p, curr_insn, max_uid))
-		      {
-			if (reg->subreg_p)
-			  lra_risky_transformations_p = true;
-			change_p = true;
-			/* Invalidate.	*/
-			usage_insns[src_regno].check = 0;
-			if (before_p)
-			  use_insn = PREV_INSN (curr_insn);
-		      }
-		    if (NONDEBUG_INSN_P (curr_insn))
-		      {
-			if (src_regno < FIRST_PSEUDO_REGISTER)
-			  add_to_hard_reg_set (&live_hard_regs,
-					       reg->biggest_mode, src_regno);
-			else
-			  add_to_hard_reg_set (&live_hard_regs,
-					       PSEUDO_REGNO_MODE (src_regno),
-					       reg_renumber[src_regno]);
-		      }
-		    add_next_usage_insn (src_regno, use_insn, reloads_num);
-		  }
-	      }
+		      before_p = (JUMP_P (curr_insn)
+				  || (CALL_P (curr_insn) && reg->type == OP_IN));
+		      if (NONDEBUG_INSN_P (curr_insn)
+			  && split_if_necessary (src_regno, reg->biggest_mode,
+						 potential_reload_hard_regs,
+						 before_p, curr_insn, max_uid))
+			{
+			  if (reg->subreg_p)
+			    lra_risky_transformations_p = true;
+			  change_p = true;
+			  /* Invalidate.	*/
+			  usage_insns[src_regno].check = 0;
+			  if (before_p)
+			    use_insn = PREV_INSN (curr_insn);
+			}
+		      if (NONDEBUG_INSN_P (curr_insn))
+			{
+			  if (src_regno < FIRST_PSEUDO_REGISTER)
+			    add_to_hard_reg_set (&live_hard_regs,
+						 reg->biggest_mode, src_regno);
+			  else
+			    add_to_hard_reg_set (&live_hard_regs,
+						 PSEUDO_REGNO_MODE (src_regno),
+						 reg_renumber[src_regno]);
+			}
+		      add_next_usage_insn (src_regno, use_insn, reloads_num);
+		    }
+		}
 	  for (i = 0; i < to_inherit_num; i++)
 	    {
 	      src_regno = to_inherit[i].regno;