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] EH_USES df fix (PR target/37378, take 2)


Hi!

As pointed out by Hans-Peter Nilsson, we want to make EH_USES regs live even
if some code path ends with an endless loop, the insns in between still
might throw, or during debugging the debugger (or something called from
async signal handler) might want to do a backtrace).  The patch I've posted
earlier doesn't cure e.g.

extern int foo (int, int);
extern int bar (void);

int
baz (int x, int y)
{
  if (__builtin_expect (y == 0, 0))
    {
      foo (x + y, x * y);
      bar ();
      while (1)
	;
    }

  if (x == (int) 0x80000000L && y == -1)
    return x;

  return x / y;
}
at -O2 - rp is saved into a local register only if y != 0.
The following alternative patch makes EH_USES registers just live
everywhere, which IMHO matches best what we really want - let those
registers stay live through the whole function.

Bootstrapped/regtested on ia64-linux, ok for trunk?

2008-10-27  Jakub Jelinek  <jakub@redhat.com>

	PR target/37378
	* df-scan.c (df_bb_refs_collect): Don't handle EH_USES here.
	(df_get_entry_block_def_set): Neither here.
	(df_get_regular_block_artificial_uses): Add EH_USES registers.

--- gcc/df-scan.c.jj	2008-10-14 07:58:50.000000000 -0400
+++ gcc/df-scan.c	2008-10-27 14:13:41.000000000 -0400
@@ -3555,29 +3555,6 @@ df_bb_refs_collect (struct df_collection
     }
 #endif
 
-
-#ifdef EH_USES
-  if (bb_has_eh_pred (bb))
-    {
-      unsigned int i;
-      /* This code is putting in an artificial ref for the use at the
-	 TOP of the block that receives the exception.  It is too
-	 cumbersome to actually put the ref on the edge.  We could
-	 either model this at the top of the receiver block or the
-	 bottom of the sender block.
-
-         The bottom of the sender block is problematic because not all
-         out-edges of a block are eh-edges.  However, it is true
-         that all edges into a block are either eh-edges or none of
-         them are eh-edges.  Thus, we can model this at the top of the
-         eh-receiver for all of the edges at once. */
-      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-	if (EH_USES (i))
-	  df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[i], NULL,
-			 bb, NULL, DF_REF_REG_USE, DF_REF_AT_TOP, -1, -1, 0);
-    }
-#endif
-
   /* Add the hard_frame_pointer if this block is the target of a
      non-local goto.  */
   if (bb->flags & BB_NON_LOCAL_GOTO_TARGET)
@@ -3667,6 +3644,8 @@ df_bb_refs_record (int bb_index, bool sc
 static void
 df_get_regular_block_artificial_uses (bitmap regular_block_artificial_uses)
 {
+  unsigned int i;
+
   bitmap_clear (regular_block_artificial_uses);
 
   if (reload_completed)
@@ -3702,6 +3681,20 @@ df_get_regular_block_artificial_uses (bi
     }
   /* The all-important stack pointer must always be live.  */
   bitmap_set_bit (regular_block_artificial_uses, STACK_POINTER_REGNUM);
+
+#ifdef EH_USES
+  /* EH_USES registers are used:
+     1) at all insns that might throw (calls or with -fnon-call-exceptions
+	trapping insns)
+     2) in all EH edges
+     3) to support backtraces and/or debugging, anywhere between their
+	initialization and where they the saved registers are restored
+	from them, including the cases where we don't reach the epilogue
+	(noreturn call or infinite loop).  */
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    if (EH_USES (i))
+      bitmap_set_bit (regular_block_artificial_uses, i);
+#endif
 }
 
 
@@ -3826,16 +3819,6 @@ df_get_entry_block_def_set (bitmap entry
   /* These registers are live everywhere.  */
   if (!reload_completed)
     {
-#ifdef EH_USES
-      /* The ia-64, the only machine that uses this, does not define these 
-	 until after reload.  */
-      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-	if (EH_USES (i))
-	  {
-	    bitmap_set_bit (entry_block_defs, i);
-	  }
-#endif
-      
 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
       /* Pseudos with argument area equivalences may require
 	 reloading via the argument pointer.  */


	Jakub


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