c0579b8
2012-01-23  Jakub Jelinek  <jakub@redhat.com>
c0579b8
c0579b8
	PR target/51957
c0579b8
	* target.def (const_not_ok_for_debug_p): New hook.
c0579b8
	* doc/tm.texi.in (TARGET_CONST_NOT_OK_FOR_DEBUG_P): New hook
c0579b8
	documentation.
c0579b8
	* doc/tm.texi: Regenerated.
c0579b8
	* dwarf2out.c (const_ok_for_output_1): If
c0579b8
	targetm.const_not_ok_for_debug_p returns true, fail.
c0579b8
	* config/rs6000/rs6000.c (rs6000_const_not_ok_for_debug_p): New
c0579b8
	function.
c0579b8
	(TARGET_CONST_NOT_OK_FOR_DEBUG_P): Redefine.
c0579b8
c0579b8
	* gcc.dg/pr51957-1.c: New test.
c0579b8
	* gcc.dg/pr51957-1.h: New file.
c0579b8
	* gcc.dg/pr51957-2.c: New test.
c0579b8
c0579b8
--- gcc/target.def.jj	2012-01-20 12:35:16.000000000 +0100
c0579b8
+++ gcc/target.def	2012-01-23 13:14:52.601638343 +0100
c0579b8
@@ -1382,6 +1382,14 @@ DEFHOOK
c0579b8
  rtx, (rtx x),
c0579b8
  delegitimize_mem_from_attrs)
c0579b8
 
c0579b8
+/* Given an RTX, return true if it is not ok to emit it into debug info
c0579b8
+   section.  */
c0579b8
+DEFHOOK
c0579b8
+(const_not_ok_for_debug_p,
c0579b8
+ "",
c0579b8
+ bool, (rtx x),
c0579b8
+ hook_bool_rtx_false)
c0579b8
+
c0579b8
 /* Given an address RTX, say whether it is valid.  */
c0579b8
 DEFHOOK
c0579b8
 (legitimate_address_p,
c0579b8
--- gcc/doc/tm.texi.in.jj	2012-01-20 12:35:10.000000000 +0100
c0579b8
+++ gcc/doc/tm.texi.in	2012-01-23 13:27:19.544241676 +0100
c0579b8
@@ -5567,6 +5567,11 @@ the semantics of these opaque @code{UNSP
c0579b8
 into their original form.
c0579b8
 @end deftypefn
c0579b8
 
c0579b8
+@hook TARGET_CONST_NOT_OK_FOR_DEBUG_P
c0579b8
+This hook should return true if @var{x} should not be emitted into
c0579b8
+debug sections.
c0579b8
+@end deftypefn
c0579b8
+
c0579b8
 @hook TARGET_CANNOT_FORCE_CONST_MEM
c0579b8
 This hook should return true if @var{x} is of a form that cannot (or
c0579b8
 should not) be spilled to the constant pool.  @var{mode} is the mode
c0579b8
--- gcc/doc/tm.texi.jj	2012-01-20 12:35:10.000000000 +0100
c0579b8
+++ gcc/doc/tm.texi	2012-01-23 13:27:33.000000000 +0100
c0579b8
@@ -5631,6 +5631,11 @@ the semantics of these opaque @code{UNSP
c0579b8
 into their original form.
c0579b8
 @end deftypefn
c0579b8
 
c0579b8
+@deftypefn {Target Hook} bool TARGET_CONST_NOT_OK_FOR_DEBUG_P (rtx @var{x})
c0579b8
+This hook should return true if @var{x} should not be emitted into
c0579b8
+debug sections.
c0579b8
+@end deftypefn
c0579b8
+
c0579b8
 @deftypefn {Target Hook} bool TARGET_CANNOT_FORCE_CONST_MEM (enum machine_mode @var{mode}, rtx @var{x})
c0579b8
 This hook should return true if @var{x} is of a form that cannot (or
c0579b8
 should not) be spilled to the constant pool.  @var{mode} is the mode
c0579b8
--- gcc/dwarf2out.c.jj	2012-01-22 16:02:10.000000000 +0100
c0579b8
+++ gcc/dwarf2out.c	2012-01-23 13:58:09.887380014 +0100
c0579b8
@@ -10683,6 +10683,13 @@ const_ok_for_output_1 (rtx *rtlp, void *
c0579b8
       return 1;
c0579b8
     }
c0579b8
 
c0579b8
+  if (targetm.const_not_ok_for_debug_p (rtl))
c0579b8
+    {
c0579b8
+      expansion_failed (NULL_TREE, rtl,
c0579b8
+			"Expression rejected for debug by the backend.\n");
c0579b8
+      return 1;
c0579b8
+    }
c0579b8
+
c0579b8
   if (GET_CODE (rtl) != SYMBOL_REF)
c0579b8
     return 0;
c0579b8
 
c0579b8
--- gcc/config/rs6000/rs6000.c.jj	2012-01-22 16:02:10.000000000 +0100
c0579b8
+++ gcc/config/rs6000/rs6000.c	2012-01-23 13:25:05.092031129 +0100
c0579b8
@@ -1106,6 +1106,7 @@ static rtx rs6000_debug_legitimize_addre
c0579b8
 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
c0579b8
 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
c0579b8
 static rtx rs6000_delegitimize_address (rtx);
c0579b8
+static bool rs6000_const_not_ok_for_debug_p (rtx);
c0579b8
 static rtx rs6000_tls_get_addr (void);
c0579b8
 static rtx rs6000_got_sym (void);
c0579b8
 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
c0579b8
@@ -1405,6 +1406,9 @@ static const struct attribute_spec rs600
c0579b8
 #undef TARGET_DELEGITIMIZE_ADDRESS
c0579b8
 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
c0579b8
 
c0579b8
+#undef TARGET_CONST_NOT_OK_FOR_DEBUG_P
c0579b8
+#define TARGET_CONST_NOT_OK_FOR_DEBUG_P rs6000_const_not_ok_for_debug_p
c0579b8
+
c0579b8
 #undef TARGET_ASM_FUNCTION_PROLOGUE
c0579b8
 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
c0579b8
 #undef TARGET_ASM_FUNCTION_EPILOGUE
c0579b8
@@ -5815,6 +5819,25 @@ rs6000_delegitimize_address (rtx orig_x)
c0579b8
   return orig_x;
c0579b8
 }
c0579b8
 
c0579b8
+/* Return true if X shouldn't be emitted into the debug info.
c0579b8
+   The linker doesn't like .toc section references from
c0579b8
+   .debug_* sections, so reject .toc section symbols.  */
c0579b8
+
c0579b8
+static bool
c0579b8
+rs6000_const_not_ok_for_debug_p (rtx x)
c0579b8
+{
c0579b8
+  if (GET_CODE (x) == SYMBOL_REF
c0579b8
+      && CONSTANT_POOL_ADDRESS_P (x))
c0579b8
+    {
c0579b8
+      rtx c = get_pool_constant (x);
c0579b8
+      enum machine_mode cmode = get_pool_mode (x);
c0579b8
+      if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (c, cmode))
c0579b8
+	return true;
c0579b8
+    }
c0579b8
+
c0579b8
+  return false;
c0579b8
+}
c0579b8
+
c0579b8
 /* Construct the SYMBOL_REF for the tls_get_addr function.  */
c0579b8
 
c0579b8
 static GTY(()) rtx rs6000_tls_symbol;
c0579b8
--- gcc/testsuite/gcc.dg/pr51957-1.c.jj	2012-01-23 14:06:45.024357678 +0100
c0579b8
+++ gcc/testsuite/gcc.dg/pr51957-1.c	2012-01-23 14:12:02.895492825 +0100
c0579b8
@@ -0,0 +1,29 @@
c0579b8
+/* PR target/51957 */
c0579b8
+/* { dg-do link } */
c0579b8
+/* { dg-options "-O2 -g -fprofile-use" } */
c0579b8
+/* { dg-additional-sources "pr51957-2.c" } */
c0579b8
+
c0579b8
+int v[128];
c0579b8
+#include "pr51957-1.h"
c0579b8
+
c0579b8
+void
c0579b8
+foo (U *x)
c0579b8
+{
c0579b8
+  T *a = x->u;
c0579b8
+  while (1)
c0579b8
+    {
c0579b8
+      union R *b;
c0579b8
+      b = fn1 ();
c0579b8
+      if (b != w[0] && !(v[b->p->c] == 1))
c0579b8
+	{
c0579b8
+	  fn2 (a->t, "foobar", b->p);
c0579b8
+	  b = w[0];
c0579b8
+	}
c0579b8
+      if (b != w[0])
c0579b8
+	fn3 ();
c0579b8
+      if (w[0] && b != w[0])
c0579b8
+	fn4 (b->p);
c0579b8
+      if (b != w[0] && (v[b->p->c] == 1) && fn4 (b->p))
c0579b8
+	break;
c0579b8
+    }
c0579b8
+}
c0579b8
--- gcc/testsuite/gcc.dg/pr51957-1.h.jj	2012-01-23 14:06:56.491290757 +0100
c0579b8
+++ gcc/testsuite/gcc.dg/pr51957-1.h	2012-01-23 14:07:35.243060438 +0100
c0579b8
@@ -0,0 +1,9 @@
c0579b8
+union R { int c; union R *p; };
c0579b8
+extern union R *w[];
c0579b8
+typedef struct { int t; } T;
c0579b8
+typedef struct { void *u; } U;
c0579b8
+union R *fn1 (void);
c0579b8
+void fn2 (int, const char *, union R *);
c0579b8
+void fn3 (void);
c0579b8
+int fn4 (union R *);
c0579b8
+void foo (U *x);
c0579b8
--- gcc/testsuite/gcc.dg/pr51957-2.c.jj	2012-01-23 14:10:59.840862700 +0100
c0579b8
+++ gcc/testsuite/gcc.dg/pr51957-2.c	2012-01-23 14:10:52.870904033 +0100
c0579b8
@@ -0,0 +1,35 @@
c0579b8
+/* PR target/51957 */
c0579b8
+/* { dg-do compile } */
c0579b8
+/* { dg-options "-O0" } */
c0579b8
+
c0579b8
+#include "pr51957-1.h"
c0579b8
+
c0579b8
+union R *w[10];
c0579b8
+
c0579b8
+union R *
c0579b8
+fn1 (void)
c0579b8
+{
c0579b8
+  return (union R *) 0;
c0579b8
+}
c0579b8
+
c0579b8
+void
c0579b8
+fn2 (int x, const char *y, union R *z)
c0579b8
+{
c0579b8
+}
c0579b8
+
c0579b8
+void
c0579b8
+fn3 (void)
c0579b8
+{
c0579b8
+}
c0579b8
+
c0579b8
+int
c0579b8
+fn4 (union R *x)
c0579b8
+{
c0579b8
+  return 0;
c0579b8
+}
c0579b8
+
c0579b8
+int
c0579b8
+main ()
c0579b8
+{
c0579b8
+  return 0;
c0579b8
+}