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]

[PATCH] Relax tail calls on SPARC if as/ld support it, unless -mno-relax


Hi!

The following patch adds configure checks for -relax option in gas (because
gas did not grok it on SPARC until recently) and if it is detected, uses it
by default for both gas and GNU ld (the latter accepted -relax for quite
some time already, only it did not do anything on SPARC).
The relaxation is IMHO safe to be enabled as default, there is -mno-relax
gcc switch which can turn it off though.
Also, if gas is detected with -relax, it never generates sethi/jmpl for leaf
tail calls, because they are quite expensive (are not predicted well) and as
the tail call will be usually optimized into branch always, it will be even
cheaper so that we can trade it for the one instruction slot being a
mov %g1,%o7 (resp. nop after relaxation).
Ok to commit?

2000-06-07  Jakub Jelinek  <jakub@redhat.com>

	* configure.in: Check whether gas supports -relax.
	* configure, config.in: Rebuilt.
	* config/sparc/sparc.h (ASM_RELAX_SPEC): Define.
	(ASM_SPEC): Use it.
	(TARGET_SWITCHES): Add -mrelax and -mno-relax.
	* config/sparc/linux64.h (LINK_SPEC): Pass -relax to
	linker unless -mno-relax.
	(ASM_SPEC): Use ASM_RELAX_SPEC.
	* config/sparc/linux.h (LINK_SPEC, ASM_SPEC): Likewise.
	* config/sparc/sparc.c (output_sibcall): If HAVE_AS_RELAX_OPTION,
	never use sethi/jmpl for leaf tail calls.  Use or with rs2 %g0
	instead of mov, so that gas can further optimize it.

--- gcc/configure.in.jj	Wed Jun  7 08:41:04 2000
+++ gcc/configure.in	Wed Jun  7 10:20:31 2000
@@ -4550,6 +4550,25 @@ case "$target" in 
 		[Define if your assembler supports .register.])
     fi
 
+    AC_CACHE_CHECK([assembler supports -relax],
+	gcc_cv_as_relax_opt, [
+	gcc_cv_as_relax_opt=unknown
+	if test x$gcc_cv_as != x; then
+	    # Check if gas supports -relax
+	    echo ".text" > conftest.s
+	    if $gcc_cv_as -relax -o conftest.o conftest.s > /dev/null 2>&1; then
+		gcc_cv_as_relax_opt=yes
+	    else
+		gcc_cv_as_relax_opt=no
+	    fi
+	    rm -f conftest.s conftest.o
+	fi
+    ])
+    if test "x$gcc_cv_as_relax_opt" = xyes; then
+	AC_DEFINE(HAVE_AS_RELAX_OPTION, 1,
+		[Define if your assembler supports -relax option.])
+    fi
+
     case "$tm_file" in
     *64*)
 	AC_CACHE_CHECK([for 64 bit support in assembler ($gcc_cv_as)],
--- gcc/config/sparc/sparc.h.jj	Thu Jun  1 12:10:34 2000
+++ gcc/config/sparc/sparc.h	Wed Jun  7 10:20:31 2000
@@ -324,12 +324,18 @@ Unrecognized value in TARGET_CPU_DEFAULT
 %{!m32:%{!m64:%(asm_arch_default)}} \
 "
 
+#ifdef HAVE_AS_RELAX_OPTION
+#define ASM_RELAX_SPEC " %{!mno-relax:-relax}"
+#else
+#define ASM_RELAX_SPEC
+#endif
+
 /* Special flags to the Sun-4 assembler when using pipe for input.  */
 
 #define ASM_SPEC "\
 %| %{R} %{!pg:%{!p:%{fpic:-k} %{fPIC:-k}}} %{keep-local-as-symbols:-L} \
 %(asm_cpu) \
-"
+" ASM_RELAX_SPEC
 
 #define LIB_SPEC "%{!shared:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} %{g:-lg}}"
 
@@ -606,6 +612,8 @@ extern int target_flags;
     {"no-stack-bias", -MASK_STACK_BIAS,			"Do not use stack bias" }, \
     {"faster-structs", MASK_FASTER_STRUCTS,			"Use structs on stronger alignment for double-word copies" }, \
     {"no-faster-structs", -MASK_FASTER_STRUCTS,		"Do not use structs on stronger alignment for double-word copies" }, \
+    {"relax", 0,					"Optimize tail call instructions in assembler and linker" }, \
+    {"no-relax", 0,					"Do not optimize tail call instructions in assembler or linker" }, \
     SUBTARGET_SWITCHES			\
     { "", TARGET_DEFAULT, ""}}
 
--- gcc/config/sparc/linux64.h.jj	Thu Jun  1 12:10:31 2000
+++ gcc/config/sparc/linux64.h	Wed Jun  7 10:20:31 2000
@@ -1,5 +1,5 @@
 /* Definitions for 64-bit SPARC running Linux-based GNU systems with ELF.
-   Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
    Contributed by David S. Miller (davem@caip.rutgers.edu)
 
 This file is part of GNU CC.
@@ -246,6 +246,7 @@ Boston, MA 02111-1307, USA.  */
 #define LINK_SPEC "\
 %(link_arch) \
 %{mlittle-endian:-EL} \
+%{!mno-relax:-relax} \
 "
 
 #undef	CC1_SPEC
@@ -291,6 +292,7 @@ Boston, MA 02111-1307, USA.  */
         %{!dynamic-linker:-dynamic-linker /lib64/ld-linux.so.2}} \
         %{static:-static}}} \
 %{mlittle-endian:-EL} \
+%{!mno-relax:-relax} \
 "
 
 #endif /* !SPARC_BI_ARCH */
@@ -309,7 +311,7 @@ Boston, MA 02111-1307, USA.  */
 -s %{fpic:-K PIC} %{fPIC:-K PIC} \
 %{mlittle-endian:-EL} \
 %(asm_cpu) %(asm_arch) \
-"
+" ASM_RELAX_SPEC
 
 /* Same as sparc.h */
 #undef DBX_REGISTER_NUMBER
--- gcc/config/sparc/linux.h.jj	Thu Jun  1 12:10:30 2000
+++ gcc/config/sparc/linux.h	Wed Jun  7 10:20:31 2000
@@ -179,6 +179,7 @@ Boston, MA 02111-1307, USA.  */
 #endif
 #else
 #define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \
+  %{!mno-relax:-relax} \
   %{!shared: \
     %{!ibcs: \
       %{!static: \
@@ -191,7 +192,8 @@ Boston, MA 02111-1307, USA.  */
    It's safe to pass -s always, even if -g is not used. */
 #undef ASM_SPEC
 #define ASM_SPEC \
-  "%{V} %{v:%{!V:-V}} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s %{fpic:-K PIC} %{fPIC:-K PIC}"
+  "%{V} %{v:%{!V:-V}} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s %{fpic:-K PIC} %{fPIC:-K PIC}" \
+  ASM_RELAX_SPEC
 
 /* Same as sparc.h */
 #undef DBX_REGISTER_NUMBER
--- gcc/config/sparc/sparc.c.jj	Wed Jun  7 08:41:11 2000
+++ gcc/config/sparc/sparc.c	Wed Jun  7 10:45:43 2000
@@ -3737,7 +3737,15 @@ output_sibcall (insn, call_operand)
 
   if (leaf_regs)
     {
+#ifdef HAVE_AS_RELAX_OPTION
+      /* If as and ld are relaxing tail call insns into branch always,
+	 use or %o7,%g0,X; call Y; or X,%g0,%o7 always, so that it can
+	 be optimized.  With sethi/jmpl as nor ld has no easy way how to
+	 find out if somebody does not branch between the sethi and jmpl.  */
+      int spare_slot = 0;
+#else
       int spare_slot = ((TARGET_ARCH32 || TARGET_CM_MEDLOW) && ! flag_pic);
+#endif
       int size = 0;
 
       if ((actual_fsize || ! spare_slot) && delay_slot)
@@ -3786,9 +3794,11 @@ output_sibcall (insn, call_operand)
 	{
 	  if (size)
 	    fprintf (asm_out_file, "\tsub\t%%sp, -%d, %%sp\n", size);
-	  output_asm_insn ("mov\t%%o7, %%g1", operands);
+	  /* Use or with rs2 %%g0 instead of mov, so that as/ld can optimize
+	     it into branch if possible.  */
+	  output_asm_insn ("or\t%%o7, %%g0, %%g1", operands);
 	  output_asm_insn ("call\t%a0, 0", operands);
-	  output_asm_insn (" mov\t%%g1, %%o7", operands);
+	  output_asm_insn (" or\t%%g1, %%g0, %%o7", operands);
 	}
       return "";
     }
--- gcc/config.in.jj	Thu Jun  1 12:10:26 2000
+++ gcc/config.in	Wed Jun  7 10:20:31 2000
@@ -426,6 +426,9 @@
 /* Define if your assembler supports .register. */
 #undef HAVE_AS_REGISTER_PSEUDO_OP
 
+/* Define if your assembler supports -relax option. */
+#undef HAVE_AS_RELAX_OPTION
+
 /* Define if the assembler supports 64bit sparc. */
 #undef AS_SPARC64_FLAG
 
--- gcc/configure.jj	Wed Jun  7 08:41:04 2000
+++ gcc/configure	Wed Jun  7 10:21:33 2000
@@ -8916,10 +8916,38 @@ EOF
 
     fi
 
+    echo $ac_n "checking assembler supports -relax""... $ac_c" 1>&6
+echo "configure:8921: checking assembler supports -relax" >&5
+if eval "test \"`echo '$''{'gcc_cv_as_relax_opt'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	gcc_cv_as_relax_opt=unknown
+	if test x$gcc_cv_as != x; then
+	    # Check if gas supports -relax
+	    echo ".text" > conftest.s
+	    if $gcc_cv_as -relax -o conftest.o conftest.s > /dev/null 2>&1; then
+		gcc_cv_as_relax_opt=yes
+	    else
+		gcc_cv_as_relax_opt=no
+	    fi
+	    rm -f conftest.s conftest.o
+	fi
+    
+fi
+
+echo "$ac_t""$gcc_cv_as_relax_opt" 1>&6
+    if test "x$gcc_cv_as_relax_opt" = xyes; then
+	cat >> confdefs.h <<\EOF
+#define HAVE_AS_RELAX_OPTION 1
+EOF
+
+    fi
+
     case "$tm_file" in
     *64*)
 	echo $ac_n "checking for 64 bit support in assembler ($gcc_cv_as)""... $ac_c" 1>&6
-echo "configure:8923: checking for 64 bit support in assembler ($gcc_cv_as)" >&5
+echo "configure:8951: checking for 64 bit support in assembler ($gcc_cv_as)" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_flags64'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8964,7 +8992,7 @@ EOF
 
     if test "x$gcc_cv_as_flags64" != xno; then
 	echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6
-echo "configure:8968: checking for assembler offsetable %lo() support" >&5
+echo "configure:8996: checking for assembler offsetable %lo() support" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_offsetable_lo10'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -9003,7 +9031,7 @@ EOF
 
   i[34567]86-*-*)
     echo $ac_n "checking assembler instructions""... $ac_c" 1>&6
-echo "configure:9007: checking assembler instructions" >&5
+echo "configure:9035: checking assembler instructions" >&5
     gcc_cv_as_instructions=
     if test x$gcc_cv_as != x; then
 	set "filds fists" "filds mem; fists mem"
@@ -9133,7 +9161,7 @@ fi
 
 # Build a new-libstdc++ system (ie libstdc++-v3)
 echo $ac_n "checking for libstdc++ to install""... $ac_c" 1>&6
-echo "configure:9137: checking for libstdc++ to install" >&5
+echo "configure:9165: checking for libstdc++ to install" >&5
 # Check whether --enable-libstdcxx-v3 or --disable-libstdcxx-v3 was given.
 if test "${enable_libstdcxx_v3+set}" = set; then
   enableval="$enable_libstdcxx_v3"
@@ -9157,7 +9185,7 @@ EOF
 
 
 echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:9161: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:9189: checking whether to enable maintainer-specific portions of Makefiles" >&5
     # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
 if test "${enable_maintainer_mode+set}" = set; then
   enableval="$enable_maintainer_mode"

	Jakub

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