This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch to fix PR69030


  The following patch fixes

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

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

  Committed as rev. 232445.

2016-01-15  Vladimir Makarov  <vmakarov@redhat.com>

        PR rtl-optimization/69030
        * lra-spills.c (remove_pseudos): Check nrefs and make the function
        returning bool.
        (spill_pseudos): Delete debug insn for dead pseudo.
        (lra_spill): Initiate spill_hard_reg and slots memory separately.

2016-01-15  Vladimir Makarov  <vmakarov@redhat.com>

        PR rtl-optimization/69030
        * lra-spills.c (remove_pseudos): Check nrefs and make the function
        returning bool.
        (spill_pseudos): Delete debug insn for dead pseudo.
        (lra_spill): Initiate spill_hard_reg and slots memory separately.

Index: lra-spills.c
===================================================================
--- lra-spills.c	(revision 232143)
+++ lra-spills.c	(working copy)
@@ -396,17 +396,19 @@ assign_stack_slot_num_and_sort_pseudos (
 
 /* Recursively process LOC in INSN and change spilled pseudos to the
    corresponding memory or spilled hard reg.  Ignore spilled pseudos
-   created from the scratches.	*/
-static void
+   created from the scratches.  Return true if the pseudo nrefs equal
+   to 0 (don't change the pseudo in this case).  Otherwise return false.  */
+static bool
 remove_pseudos (rtx *loc, rtx_insn *insn)
 {
   int i;
   rtx hard_reg;
   const char *fmt;
   enum rtx_code code;
-
+  bool res = false;
+  
   if (*loc == NULL_RTX)
-    return;
+    return res;
   code = GET_CODE (*loc);
   if (code == REG && (i = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER
       && lra_get_regno_hard_regno (i) < 0
@@ -416,6 +418,9 @@ remove_pseudos (rtx *loc, rtx_insn *insn
 	 into scratches back.  */
       && ! lra_former_scratch_p (i))
     {
+      if (lra_reg_info[i].nrefs == 0
+	  && pseudo_slots[i].mem == NULL && spill_hard_reg[i] == NULL)
+	return true;
       if ((hard_reg = spill_hard_reg[i]) != NULL_RTX)
 	*loc = copy_rtx (hard_reg);
       else
@@ -425,22 +430,23 @@ remove_pseudos (rtx *loc, rtx_insn *insn
 					false, false, 0, true);
 	  *loc = x != pseudo_slots[i].mem ? x : copy_rtx (x);
 	}
-      return;
+      return res;
     }
 
   fmt = GET_RTX_FORMAT (code);
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     {
       if (fmt[i] == 'e')
-	remove_pseudos (&XEXP (*loc, i), insn);
+	res = remove_pseudos (&XEXP (*loc, i), insn) || res;
       else if (fmt[i] == 'E')
 	{
 	  int j;
 
 	  for (j = XVECLEN (*loc, i) - 1; j >= 0; j--)
-	    remove_pseudos (&XVECEXP (*loc, i, j), insn);
+	    res = remove_pseudos (&XVECEXP (*loc, i, j), insn) || res;
 	}
     }
+  return res;
 }
 
 /* Convert spilled pseudos into their stack slots or spill hard regs,
@@ -450,7 +456,7 @@ static void
 spill_pseudos (void)
 {
   basic_block bb;
-  rtx_insn *insn;
+  rtx_insn *insn, *curr;
   int i;
   bitmap_head spilled_pseudos, changed_insns;
 
@@ -467,52 +473,70 @@ spill_pseudos (void)
     }
   FOR_EACH_BB_FN (bb, cfun)
     {
-      FOR_BB_INSNS (bb, insn)
-	if (bitmap_bit_p (&changed_insns, INSN_UID (insn)))
-	  {
-	    rtx *link_loc, link;
-	    remove_pseudos (&PATTERN (insn), insn);
-	    if (CALL_P (insn))
-	      remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn);
-	    for (link_loc = &REG_NOTES (insn);
-		 (link = *link_loc) != NULL_RTX;
-		 link_loc = &XEXP (link, 1))
-	      {
-		switch (REG_NOTE_KIND (link))
-		  {
-		  case REG_FRAME_RELATED_EXPR:
-		  case REG_CFA_DEF_CFA:
-		  case REG_CFA_ADJUST_CFA:
-		  case REG_CFA_OFFSET:
-		  case REG_CFA_REGISTER:
-		  case REG_CFA_EXPRESSION:
-		  case REG_CFA_RESTORE:
-		  case REG_CFA_SET_VDRAP:
-		    remove_pseudos (&XEXP (link, 0), insn);
-		    break;
-		  default:
-		    break;
-		  }
-	      }
-	    if (lra_dump_file != NULL)
-	      fprintf (lra_dump_file,
-		       "Changing spilled pseudos to memory in insn #%u\n",
-		       INSN_UID (insn));
-	    lra_push_insn (insn);
-	    if (lra_reg_spill_p || targetm.different_addr_displacement_p ())
-	      lra_set_used_insn_alternative (insn, -1);
-	  }
-	else if (CALL_P (insn))
-	  /* Presence of any pseudo in CALL_INSN_FUNCTION_USAGE does
-	     not affect value of insn_bitmap of the corresponding
-	     lra_reg_info.  That is because we don't need to reload
-	     pseudos in CALL_INSN_FUNCTION_USAGEs.  So if we process
-	     only insns in the insn_bitmap of given pseudo here, we
-	     can miss the pseudo in some
-	     CALL_INSN_FUNCTION_USAGEs.  */
-	  remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn);
-      bitmap_and_compl_into (df_get_live_in (bb), &spilled_pseudos);
-      bitmap_and_compl_into (df_get_live_out (bb), &spilled_pseudos);
+      FOR_BB_INSNS_SAFE (bb, insn, curr)
+	{
+	  bool removed_pseudo_p = false;
+	  
+	  if (bitmap_bit_p (&changed_insns, INSN_UID (insn)))
+	    {
+	      rtx *link_loc, link;
+
+	      removed_pseudo_p = remove_pseudos (&PATTERN (insn), insn);
+	      if (CALL_P (insn)
+		  && remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn))
+		removed_pseudo_p = true;
+	      for (link_loc = &REG_NOTES (insn);
+		   (link = *link_loc) != NULL_RTX;
+		   link_loc = &XEXP (link, 1))
+		{
+		  switch (REG_NOTE_KIND (link))
+		    {
+		    case REG_FRAME_RELATED_EXPR:
+		    case REG_CFA_DEF_CFA:
+		    case REG_CFA_ADJUST_CFA:
+		    case REG_CFA_OFFSET:
+		    case REG_CFA_REGISTER:
+		    case REG_CFA_EXPRESSION:
+		    case REG_CFA_RESTORE:
+		    case REG_CFA_SET_VDRAP:
+		      if (remove_pseudos (&XEXP (link, 0), insn))
+			removed_pseudo_p = true;
+		      break;
+		    default:
+		      break;
+		    }
+		}
+	      if (lra_dump_file != NULL)
+		fprintf (lra_dump_file,
+			 "Changing spilled pseudos to memory in insn #%u\n",
+			 INSN_UID (insn));
+	      lra_push_insn (insn);
+	      if (lra_reg_spill_p || targetm.different_addr_displacement_p ())
+		lra_set_used_insn_alternative (insn, -1);
+	    }
+	  else if (CALL_P (insn)
+		   /* Presence of any pseudo in CALL_INSN_FUNCTION_USAGE
+		      does not affect value of insn_bitmap of the
+		      corresponding lra_reg_info.  That is because we
+		      don't need to reload pseudos in
+		      CALL_INSN_FUNCTION_USAGEs.  So if we process only
+		      insns in the insn_bitmap of given pseudo here, we
+		      can miss the pseudo in some
+		      CALL_INSN_FUNCTION_USAGEs.  */
+		   && remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn))
+	    removed_pseudo_p = true;
+	  if (removed_pseudo_p)
+	    {
+	      lra_assert (DEBUG_INSN_P (insn));
+	      lra_set_insn_deleted (insn);
+	      if (lra_dump_file != NULL)
+		fprintf (lra_dump_file,
+			 "Debug insn #%u is deleted as containing removed pseudo\n",
+			 INSN_UID (insn));
+	    }
+	  bitmap_and_compl_into (df_get_live_in (bb), &spilled_pseudos);
+	  bitmap_and_compl_into (df_get_live_out (bb), &spilled_pseudos);
+	}
     }
   bitmap_clear (&spilled_pseudos);
   bitmap_clear (&changed_insns);
@@ -548,12 +572,14 @@ lra_spill (void)
     if (lra_reg_info[i].nrefs != 0 && lra_get_regno_hard_regno (i) < 0
 	/* We do not want to assign memory for former scratches.  */
 	&& ! lra_former_scratch_p (i))
-      {
-	spill_hard_reg[i] = NULL_RTX;
-	pseudo_regnos[n++] = i;
-      }
+      pseudo_regnos[n++] = i;
   lra_assert (n > 0);
   pseudo_slots = XNEWVEC (struct pseudo_slot, regs_num);
+  for (i = FIRST_PSEUDO_REGISTER; i < regs_num; i++)
+    {
+      spill_hard_reg[i] = NULL_RTX;
+      pseudo_slots[i].mem = NULL_RTX;
+    }
   slots = XNEWVEC (struct slot, regs_num);
   /* Sort regnos according their usage frequencies.  */
   qsort (pseudo_regnos, n, sizeof (int), regno_freq_compare);
Index: testsuite/gcc.target/i386/pr69030.c
===================================================================
--- testsuite/gcc.target/i386/pr69030.c	(revision 0)
+++ testsuite/gcc.target/i386/pr69030.c	(working copy)
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -g -w" } */
+
+int a, b, c = 7, d;
+static unsigned e, g;
+char f;
+static unsigned fn1() {
+  unsigned h = e - b ^ c;
+  int i = h / c & a * g, j = g * h;
+  if (h) {
+    if (d)
+      h = e;
+    j = a;
+    a = (a && (g % f && i) % h) | c | ~2;
+    if (b)
+      printf("", 1);
+  }
+  c = i;
+  a = j;
+  return 2;
+}
+
+int main() {
+  for (; b < -18; --b)
+    g = 0;
+  fn1();
+  return 0;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]