This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix up ppc64-linux profiledbootstrap - .toc section references in .debug_loc (PR target/51957)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: David Edelsohn <dje dot gcc at gmail dot com>, Alan Modra <amodra at gmail dot com>, Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 23 Jan 2012 19:29:18 +0100
- Subject: [PATCH] Fix up ppc64-linux profiledbootstrap - .toc section references in .debug_loc (PR target/51957)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
profiledbootstrap currently fails on powerpc64-linux (64-bit). The problem
is that the linker errors on .toc section references from within
non-allocated sections. Alan changed the linker some months ago to
not die with assertion failure, but error out on these, and the attached
testcase reduced from cp/parser.c during bootstrap shows that we still
can hit it in some cases. The problem here is that var-tracking.c
(adjust_insn) isn't able to delegitimize it, because the UNSPEC_TOCREL
isn't added there to r2 register, but to a debug_expr (which only afterwards
is found to contain r2 value). So the UNSPEC_TOCREL makes it through to
mem_loc_descriptor, where it is already properly delegitimized into a
(mem (symbol_ref (".LC0")) where .LC0 is a constant pool (.toc) symbol.
We in some places try to prefer avoid_constant_pool_reference values over
the mems, in this case avoid_constant_pool returns (symbol_ref "w"), which
is a non-local symbol which isn't const_ok_for_output though. So
mem_loc_descriptor on the avoid_constant_pool_reference value fails and we
try the original (mem (symbol_ref (".LC0")) - on other targets this is still
useful, if we know the right value is in say some .got entry etc. and we
can reference that location from within the .debug_info, we win.
Unfortunately the ppc64 linker doesn't like this, so we need to reject
those. The following patch adds a target hook and rejects there from
emitting into .debug_info/.debug_loc any SYMBOL_REFs that are in the
.toc section.
Bootstrapped/regtested on x86_64-linux and i686-linux, profiledbootstrapped
on powerpc64-linux (both --with-cpu=default32 and defaulting to 64-bit,
the last one failed without this patch), powerpc64-linux regtest is in
progress (but the testcase in the patch has been tested already to
fail without the patch and succeed with the patch).
Ok for trunk?
2012-01-23 Jakub Jelinek <jakub@redhat.com>
PR target/51957
* target.def (const_not_ok_for_debug_p): New hook.
* doc/tm.texi.in (TARGET_CONST_NOT_OK_FOR_DEBUG_P): New hook
documentation.
* doc/tm.texi: Regenerated.
* dwarf2out.c (const_ok_for_output_1): If
targetm.const_not_ok_for_debug_p returns true, fail.
* config/rs6000/rs6000.c (rs6000_const_not_ok_for_debug_p): New
function.
(TARGET_CONST_NOT_OK_FOR_DEBUG_P): Redefine.
* gcc.dg/pr51957-1.c: New test.
* gcc.dg/pr51957-1.h: New file.
* gcc.dg/pr51957-2.c: New test.
--- gcc/target.def.jj 2012-01-20 12:35:16.000000000 +0100
+++ gcc/target.def 2012-01-23 13:14:52.601638343 +0100
@@ -1382,6 +1382,14 @@ DEFHOOK
rtx, (rtx x),
delegitimize_mem_from_attrs)
+/* Given an RTX, return true if it is not ok to emit it into debug info
+ section. */
+DEFHOOK
+(const_not_ok_for_debug_p,
+ "",
+ bool, (rtx x),
+ hook_bool_rtx_false)
+
/* Given an address RTX, say whether it is valid. */
DEFHOOK
(legitimate_address_p,
--- gcc/doc/tm.texi.in.jj 2012-01-20 12:35:10.000000000 +0100
+++ gcc/doc/tm.texi.in 2012-01-23 13:27:19.544241676 +0100
@@ -5567,6 +5567,11 @@ the semantics of these opaque @code{UNSP
into their original form.
@end deftypefn
+@hook TARGET_CONST_NOT_OK_FOR_DEBUG_P
+This hook should return true if @var{x} should not be emitted into
+debug sections.
+@end deftypefn
+
@hook TARGET_CANNOT_FORCE_CONST_MEM
This hook should return true if @var{x} is of a form that cannot (or
should not) be spilled to the constant pool. @var{mode} is the mode
--- gcc/doc/tm.texi.jj 2012-01-20 12:35:10.000000000 +0100
+++ gcc/doc/tm.texi 2012-01-23 13:27:33.000000000 +0100
@@ -5631,6 +5631,11 @@ the semantics of these opaque @code{UNSP
into their original form.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_CONST_NOT_OK_FOR_DEBUG_P (rtx @var{x})
+This hook should return true if @var{x} should not be emitted into
+debug sections.
+@end deftypefn
+
@deftypefn {Target Hook} bool TARGET_CANNOT_FORCE_CONST_MEM (enum machine_mode @var{mode}, rtx @var{x})
This hook should return true if @var{x} is of a form that cannot (or
should not) be spilled to the constant pool. @var{mode} is the mode
--- gcc/dwarf2out.c.jj 2012-01-22 16:02:10.000000000 +0100
+++ gcc/dwarf2out.c 2012-01-23 13:58:09.887380014 +0100
@@ -10683,6 +10683,13 @@ const_ok_for_output_1 (rtx *rtlp, void *
return 1;
}
+ if (targetm.const_not_ok_for_debug_p (rtl))
+ {
+ expansion_failed (NULL_TREE, rtl,
+ "Expression rejected for debug by the backend.\n");
+ return 1;
+ }
+
if (GET_CODE (rtl) != SYMBOL_REF)
return 0;
--- gcc/config/rs6000/rs6000.c.jj 2012-01-22 16:02:10.000000000 +0100
+++ gcc/config/rs6000/rs6000.c 2012-01-23 13:25:05.092031129 +0100
@@ -1106,6 +1106,7 @@ static rtx rs6000_debug_legitimize_addre
static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
static rtx rs6000_delegitimize_address (rtx);
+static bool rs6000_const_not_ok_for_debug_p (rtx);
static rtx rs6000_tls_get_addr (void);
static rtx rs6000_got_sym (void);
static int rs6000_tls_symbol_ref_1 (rtx *, void *);
@@ -1405,6 +1406,9 @@ static const struct attribute_spec rs600
#undef TARGET_DELEGITIMIZE_ADDRESS
#define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
+#undef TARGET_CONST_NOT_OK_FOR_DEBUG_P
+#define TARGET_CONST_NOT_OK_FOR_DEBUG_P rs6000_const_not_ok_for_debug_p
+
#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
#undef TARGET_ASM_FUNCTION_EPILOGUE
@@ -5815,6 +5819,25 @@ rs6000_delegitimize_address (rtx orig_x)
return orig_x;
}
+/* Return true if X shouldn't be emitted into the debug info.
+ The linker doesn't like .toc section references from
+ .debug_* sections, so reject .toc section symbols. */
+
+static bool
+rs6000_const_not_ok_for_debug_p (rtx x)
+{
+ if (GET_CODE (x) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (x))
+ {
+ rtx c = get_pool_constant (x);
+ enum machine_mode cmode = get_pool_mode (x);
+ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (c, cmode))
+ return true;
+ }
+
+ return false;
+}
+
/* Construct the SYMBOL_REF for the tls_get_addr function. */
static GTY(()) rtx rs6000_tls_symbol;
--- gcc/testsuite/gcc.dg/pr51957-1.c.jj 2012-01-23 14:06:45.024357678 +0100
+++ gcc/testsuite/gcc.dg/pr51957-1.c 2012-01-23 14:12:02.895492825 +0100
@@ -0,0 +1,29 @@
+/* PR target/51957 */
+/* { dg-do link } */
+/* { dg-options "-O2 -g -fprofile-use" } */
+/* { dg-additional-sources "pr51957-2.c" } */
+
+int v[128];
+#include "pr51957-1.h"
+
+void
+foo (U *x)
+{
+ T *a = x->u;
+ while (1)
+ {
+ union R *b;
+ b = fn1 ();
+ if (b != w[0] && !(v[b->p->c] == 1))
+ {
+ fn2 (a->t, "foobar", b->p);
+ b = w[0];
+ }
+ if (b != w[0])
+ fn3 ();
+ if (w[0] && b != w[0])
+ fn4 (b->p);
+ if (b != w[0] && (v[b->p->c] == 1) && fn4 (b->p))
+ break;
+ }
+}
--- gcc/testsuite/gcc.dg/pr51957-1.h.jj 2012-01-23 14:06:56.491290757 +0100
+++ gcc/testsuite/gcc.dg/pr51957-1.h 2012-01-23 14:07:35.243060438 +0100
@@ -0,0 +1,9 @@
+union R { int c; union R *p; };
+extern union R *w[];
+typedef struct { int t; } T;
+typedef struct { void *u; } U;
+union R *fn1 (void);
+void fn2 (int, const char *, union R *);
+void fn3 (void);
+int fn4 (union R *);
+void foo (U *x);
--- gcc/testsuite/gcc.dg/pr51957-2.c.jj 2012-01-23 14:10:59.840862700 +0100
+++ gcc/testsuite/gcc.dg/pr51957-2.c 2012-01-23 14:10:52.870904033 +0100
@@ -0,0 +1,35 @@
+/* PR target/51957 */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+#include "pr51957-1.h"
+
+union R *w[10];
+
+union R *
+fn1 (void)
+{
+ return (union R *) 0;
+}
+
+void
+fn2 (int x, const char *y, union R *z)
+{
+}
+
+void
+fn3 (void)
+{
+}
+
+int
+fn4 (union R *x)
+{
+ return 0;
+}
+
+int
+main ()
+{
+ return 0;
+}
Jakub