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]

Committed: revival of LEGITIMIZE_RELOAD_ADDRESS for CRIS.


Oh my, was this ever needed... not.  I thought I'd fix those
suboptimalities I saw from the generic address reload support
when fixing PR middle-end/24750.  But for all assembled code in
gcc, this only triggers for the specific test-cases in
gcc.target/cris/*.  Anyway, it fixes... a code quality regression
from gcc-4.0.2... which however SEGV:s on rld-legit2.c anyway
because of a braino in the old LEGITIMIZE_RELOAD_ADDRESS
implementation.  I like full code coverage.

gcc/:
	* config/cris/cris.h (LEGITIMIZE_RELOAD_ADDRESS): Define.
	* config/cris/cris.c: Include reload.h.
	(cris_initial_elimination_offset): New function.
	* config/cris/cris-protos.h: (cris_initial_elimination_offset):
	Prototype.

gcc/testsuite/:
	* gcc.target/cris/cris.exp: New file.
	* gcc.target/cris/rld-legit1.c: New test.
	* gcc.target/cris/rld-legit2.c: New test.

Index: cris.c
===================================================================
--- cris.c	(revision 106481)
+++ cris.c	(working copy)
@@ -38,6 +38,7 @@ Boston, MA 02110-1301, USA.  */
 #include "function.h"
 #include "toplev.h"
 #include "recog.h"
+#include "reload.h"
 #include "tm_p.h"
 #include "debug.h"
 #include "output.h"
@@ -1205,6 +1206,81 @@ cris_initial_elimination_offset (int fro
   gcc_unreachable ();
 }
 
+/* Worker function for LEGITIMIZE_RELOAD_ADDRESS.  */
+
+bool
+cris_reload_address_legitimized (rtx x,
+				 enum machine_mode mode ATTRIBUTE_UNUSED,
+				 int opnum ATTRIBUTE_UNUSED,
+				 int itype,
+				 int ind_levels ATTRIBUTE_UNUSED)
+{
+  enum reload_type type = itype;
+  rtx op0, op1;
+  rtx *op0p;
+  rtx *op1p;
+
+  if (GET_CODE (x) != PLUS)
+    return false;
+
+  op0 = XEXP (x, 0);
+  op0p = &XEXP (x, 0);
+  op1 = XEXP (x, 1);
+  op1p = &XEXP (x, 1);
+
+  if (!REG_P (op1))
+    return false;
+
+  if (GET_CODE (op0) == SIGN_EXTEND
+      && GET_CODE (XEXP (op0, 0)) == MEM)
+    {
+      rtx op00 = XEXP (op0, 0);
+      rtx op000 = XEXP (op00, 0);
+      rtx *op000p = &XEXP (op00, 0);
+
+      if ((GET_MODE (op00) == HImode || GET_MODE (op00) == QImode)
+	  && (REG_P (op000)
+	      || (GET_CODE (op000) == POST_INC && REG_P (XEXP (op000, 0)))))
+	{
+	  bool something_reloaded = false;
+
+	  if (GET_CODE (op000) == POST_INC
+	      && REG_P (XEXP (op000, 0))
+	      && REGNO (XEXP (op000, 0)) > CRIS_LAST_GENERAL_REGISTER)
+	    /* No, this gets too complicated and is too rare to care
+	       about trying to improve on the general code Here.
+	       As the return-value is an all-or-nothing indicator, we
+	       punt on the other register too.  */
+	    return false;
+
+	  if ((REG_P (op000)
+	       && REGNO (op000) > CRIS_LAST_GENERAL_REGISTER))
+	    {
+	      /* The address of the inner mem is a pseudo or wrong
+		 reg: reload that.  */
+	      push_reload (op000, NULL_RTX, op000p, NULL, GENERAL_REGS,
+			   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
+	      something_reloaded = true;
+	    }
+
+	  if (REGNO (op1) > CRIS_LAST_GENERAL_REGISTER)
+	    {
+	      /* Base register is a pseudo or wrong reg: reload it.  */
+	      push_reload (op1, NULL_RTX, op1p, NULL, GENERAL_REGS,
+			   GET_MODE (x), VOIDmode, 0, 0,
+			   opnum, type);
+	      something_reloaded = true;
+	    }
+
+	  gcc_assert (something_reloaded);
+
+	  return true;
+	}
+    }
+
+  return false;
+}
+
 /*  This function looks into the pattern to see how this insn affects
     condition codes.
 
@@ -2160,7 +2236,7 @@ cris_asm_output_mi_thunk (FILE *stream,
     }
 }
 
-/* Boilerplate emitted at start of file.  
+/* Boilerplate emitted at start of file.
 
    NO_APP *only at file start* means faster assembly.  It also means
    comments are not allowed.  In some cases comments will be output
Index: cris.h
===================================================================
--- cris.h	(revision 106481)
+++ cris.h	(working copy)
@@ -1055,6 +1055,15 @@ struct cum_args {int regs;};
    FIXME: Check and adjust for gcc-2.9x.  */
 #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) {}
 
+/* Fix reloads known to cause suboptimal spilling.  */
+#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, INDL, WIN)	\
+  do									\
+    {									\
+      if (cris_reload_address_legitimized (X, MODE, OPNUM, TYPE, INDL))	\
+	goto WIN;							\
+    }									\
+  while (0)
+
 /* In CRIS, only the postincrement address mode depends thus,
    since the increment depends on the size of the operand.  */
 #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)	\
Index: cris-protos.h
===================================================================
--- cris-protos.h	(revision 106481)
+++ cris-protos.h	(working copy)
@@ -31,6 +31,7 @@ extern bool cris_simple_epilogue (void);
 #ifdef RTX_CODE
 extern const char *cris_op_str (rtx);
 extern void cris_notice_update_cc (rtx, rtx);
+extern bool cris_reload_address_legitimized (rtx, enum machine_mode, int, int, int);
 extern void cris_print_operand (FILE *, rtx, int);
 extern void cris_print_operand_address (FILE *, rtx);
 extern int cris_side_effect_mode_ok (enum rtx_code, rtx *, int, int,
Index: rld-legit1.c
===================================================================
--- rld-legit1.c	(revision 0)
+++ rld-legit1.c	(revision 0)
@@ -0,0 +1,21 @@
+/* Check that we don't get unnecessary insns due to reload using more
+   insns than needed due to reloading of more locations than
+   needed.  */
+/* { dg-options -O2 } */
+/* { dg-final { scan-assembler-not "movs.w" } } */
+/* { dg-final { scan-assembler-not "move.w" } } */
+
+/* As torture/pr24750-2.c, except we need to clobber R8 for thorough
+   testing and know we can do, since we replace the frame-pointer.  */
+
+int
+f (short *a, char *y)
+{
+  __asm__ ("" : : :
+#ifndef __PIC__
+	   "r0",
+#endif
+	   "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
+	   "r9", "r10", "r11", "r12", "r13");
+  return y[*a];
+}
Index: rld-legit2.c
===================================================================
--- rld-legit2.c	(revision 0)
+++ rld-legit2.c	(revision 0)
@@ -0,0 +1,16 @@
+/* A variant of rld-legit1.c only for full code coverage of the
+   initial version of cris_reload_address_legitimized.  */
+/* { dg-options -O2 } */
+
+short *
+g (short *a, char *y)
+{
+  __asm__ ("" : : :
+#ifndef __PIC__
+	   "r0",
+#endif
+	   "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
+	   "r9", "r10", "r11", "r12", "r13");
+  y[*a++] = 0;
+  return a;
+}
Index: cris.exp
===================================================================
--- cris.exp	(revision 0)
+++ cris.exp	(revision 0)
@@ -0,0 +1,41 @@
+#   Copyright (C) 2005 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  
+
+# GCC testsuite that uses the `gcc-dg.exp' driver, just a single option, no
+# looping over tests.
+
+# Exit immediately if this isn't a CRIS target.
+if ![istarget cris-*-*] then {
+  return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish


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