diff mbox

powerpc64 large-toc vs. reload

Message ID 20110620150432.GP21332@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra June 20, 2011, 3:04 p.m. UTC
On Sun, Jun 19, 2011 at 11:04:12PM -0400, David Edelsohn wrote:
> On Sun, Jun 19, 2011 at 10:03 AM, Alan Modra <amodra@gmail.com> wrote:
> >        * config/rs6000/rs6000.c (create_TOC_reference): Wrap high part
> >        of toc-relative address in CONST.
> >        (rs6000_delegitimize_address): Recognize changed address.
> >        (rs6000_legitimize_reload_address): Likewise.
> >        (rs6000_emit_move): Don't force these constants to memory.
> >        * config/rs6000/rs6000.md (tls_gd, tls_gd_high): Wrap high part of
> >        toc-relative address in CONST.
> >        (tls_ld, tls_ld_high, tls_got_dtprel, tls_got_dtprel_high): Likewise.
> >        (tls_got_tprel, tls_got_tprel_high, largetoc_high): Likewise.
> 
> Okay.

I applied this after boostrapping c,c++,fortran,lto and finding no
regressions, both on mainline and gcc-4.6.  Then I did the same for
gcc-4.6-ibm and gcc-4.5-ibm, and discovered an internal compiler error
on the gcc-4.5-ibm branch in one fortran testcase.  Arrgh!  This was
due to reload putting one of the new CONST patterns in the constant
pool.  I'm almost certain this can happen on mainline and 4.6 too but
just doesn't trigger on the testsuite or during bootstrap.

So I need to make a followup patch and match the new CONST pattern in
rs6000_cannot_force_const_mem.  reload.c:CONST_POOL_OK_P will then
prevent reload putting these constants into memory.

Bootstrapped and regression tested all over again.  This is what I'm
about to commit.

	* config/rs6000/rs6000.c (rs6000_cannot_force_const_mem): Match
	CONST high part large-toc address.
	(rs6000_tls_referenced_p): Make static.
	* config/rs6000/rs6000-protos.h (rs6000_tls_referenced_p): Delete.
diff mbox

Patch

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 175200)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -6045,7 +6045,7 @@  rs6000_legitimize_tls_address (rtx addr,
 
 /* Return 1 if X contains a thread-local symbol.  */
 
-bool
+static bool
 rs6000_tls_referenced_p (rtx x)
 {
   if (! TARGET_HAVE_TLS)
@@ -6059,6 +6059,11 @@  rs6000_tls_referenced_p (rtx x)
 static bool
 rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
 {
+  if (GET_CODE (x) == CONST
+      && GET_CODE (XEXP (x, 0)) == PLUS
+      && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH)
+    return true;
+
   return rs6000_tls_referenced_p (x);
 }
 
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
--- gcc/config/rs6000/rs6000-protos.h	(revision 175200)
+++ gcc/config/rs6000/rs6000-protos.h	(working copy)
@@ -171,7 +171,6 @@  extern unsigned int rs6000_dbx_register_
 extern void rs6000_emit_epilogue (int);
 extern void rs6000_emit_eh_reg_restore (rtx, rtx);
 extern const char * output_isel (rtx *);
-extern bool rs6000_tls_referenced_p (rtx);
 
 extern void rs6000_aix_asm_output_dwarf_table_ref (char *);
 

The 4.6 patch is a little different due to 4.5 not already having
rs6000_cannot_force_const_mem.

	* config/rs6000/rs6000.c (rs6000_cannot_force_const_mem): New func.
	(TARGET_CANNOT_FORCE_CONST_MEM): Update definition.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 175201)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -1212,6 +1212,7 @@  static enum machine_mode rs6000_eh_retur
 static bool rs6000_can_eliminate (const int, const int);
 static void rs6000_conditional_register_usage (void);
 static void rs6000_trampoline_init (rtx, tree, rtx);
+static bool rs6000_cannot_force_const_mem (rtx);
 
 /* Hash table stuff for keeping track of TOC entries.  */
 
@@ -1382,7 +1383,7 @@  static const struct default_options rs60
 #define TARGET_HAVE_TLS HAVE_AS_TLS
 
 #undef TARGET_CANNOT_FORCE_CONST_MEM
-#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
+#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
 
 #undef TARGET_DELEGITIMIZE_ADDRESS
 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
@@ -6651,6 +6663,19 @@  rs6000_tls_referenced_p (rtx x)
   return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
 }
 
+/* Implement TARGET_CANNOT_FORCE_CONST_MEM.  */
+
+static bool
+rs6000_cannot_force_const_mem (rtx x)
+{
+  if (GET_CODE (x) == CONST
+      && GET_CODE (XEXP (x, 0)) == PLUS
+      && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH)
+    return true;
+
+  return rs6000_tls_referenced_p (x);
+}
+
 /* Return 1 if *X is a thread-local symbol.  This is the same as
    rs6000_tls_symbol_ref except for the type of the unused argument.  */