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]

Re: sh-elf-4_1-branch created


Joern RENNECKE <joern.rennecke@st.com> wrote:
> Oh dear.  This is basically an architecture bug - you are supposed to be 
> able to
> hoist pta / ptb / ptabs / ptrel, but because all these instructions can 
> generate
> exceptions, this is not safe, particularily not for ptabs.  The 
> gettrcost hack is
> supposed to effectively prevent the register allocator using target 
> registers
> for arbitrary integers, and I had hoped that the case where you have
> something that really looks like a pointer but is an integer was rare enough
> that we recommend using -fno-branch-target-load-optimize when it actually
> hits, till the architecture is fixed.  If the runtime library already 
> encounters this
> problem, this might also happen more often than tolerable for other code.

I tried -fno-branch-target-load-optimize but it doesn't solve that
case unfortunately.

> WIth the current architecture, target registers can, strictly speaking, 
> not hold
> DImode or SImode, but only PSImode or PDImode, whre these would be
> defined to have only as many bits as the implementation implements for
> addresses, and binary 11 endings are not allowed.  However, PSImode is 
> already
> taken for FPSCR.  We'd really need more partial integer modes to make 
> this sane.
> Well, we could use PDImode throughout...  but then the register saves would
> get wonky.  Also, using funny modes really only protects against putting 
> integers
> into target registers, which is what the gettrcost hack guards against.  The
> scheduler can still decide it wants to move a target register load, so 
> ptabs would
> have to display a data-dependent side effect.  Something like
> (trap_if (eq (and trx 3) 3),  (unspec (call trx))) or (unspec_volatile 
> trx).
> This will need reload_insi / reload_indi (or reload_inpsi / reload_inpdi)
> patterns to get working.  caller_save probably won't work, we'll be lucky to
> cleanly disable it for target registers.
> Luckily, the value 0 from weak symbols is a valid address for the 
> purposes of pt,
> so we should be OK if we say that pt is only to be used to load 
> label_refs and
> genuine code symbol_refs.  But can we really tell if we have a genuine code
> symbol_ref?  There is SYMBOL_REF_FUNCTION_P to tell us if the symbol
> has been declared as a function, but is it acceptable that the program 
> fails if
> you link in a module where this symbol is defined to be something that 
> is invalid
> as a code address, even if  no attemt to actually call through this 
> symbols is made?
> E.g. you might have a chain of functions that return a pointer to the 
> next function.
> The end of the chain is denoted as -1, and so is an empty chain...

Now I've recognized that this is a hard problem.  Thanks for your
explanation.

I think that it'd be very rare anyway.  I've tested even the kernel
emulation which fixes such PTABS so as to write the value dropped
the bit 1 to the target register.  It works fine, though not applicable
everywhere.

> For static libraries, having an extra symbol basically costs you nothing.
> However, for shared libraries, a new symbol would require a new GOT entry.
> I suppose the right paradigm for elf shared libraries is symbol versioning -
> old code can use the new sdivsi3 implementation just fine, but not vice 
> versa.
> Thus, for systems that come with shared libraries, the divsi3 expander 
> should
> generate a reference to __sdivsi3 with an ew version number, rather than 
> __sdivsi3_1 .
> I don't know how to go about that, though.

I see.

> Another issue here is that linux compiles the static libgcc with 
> -fpic.   This will
> inevitably generate less efficient and larger code than ordinary 
> compilation.

Surely -fpic makes libgcc code lengthy.  But I'm afraid that removing
-fpic breaks somthing.  Historically, sh*-linux used the non-pic
libgcc and I've got several complaints about it, though almost of
them were the linker problems.  I'm unsure that is the case for
the current sh64.  Ugh, no.  I've just tried TARGET_LIBGCC2_CFLAGS=
in t-linux64 to remove -fpic and got a failure when building
libgcc_s.so:

/usr/local/bin/sh64-unknown-linux-gnu-ld: libgcc/./_absvsi2_s.o(.text..SHmedia32): unresolvable relocation against symbol `abort@@GLIBC_2.2'
/usr/local/bin/sh64-unknown-linux-gnu-ld: final link failed: Nonrepresentable section on output

Of course we ought to fix it, but it seems removing -fpic is risky
at this stage after all.
How do you think about the appended patch?  It isn't so clean but
is simple.  It makes the target possible to override the default
division strategy for -O0 and -Os.
I've regtested it and found no new failures in c&c++ testsuite 
comparing with the previous one using RUNTESTFLAGS="-mdiv=inv:minlat"
on sh64-unknown-linux-gnu.

Regards,
	kaz
--
2005-04-13  Kaz Kojima  <kkojima@gcc.gnu.org>

	* config/sh/sh.c (sh_div_strategy): Initialize with
	SH_DIV_STRATEGY_DEFAULT.
	* config/sh/sh.c (SH_DIV_STR_FOR_SIZE): Define.
	(SH_DIV_STRATEGY_DEFAULT): Likewise.
	(OPTIMIZATION_OPTIONS): Set sh_div_str to SH_DIV_STR_FOR_SIZE
	when optimized for size.
	* config/sh/linux.h (SH_DIV_STRATEGY_DEFAULT): Redefine.
	(SH_DIV_STR_FOR_SIZE): Likewise.
	* config/sh/netbsd-elf.h (SH_DIV_STRATEGY_DEFAULT): Likewise.
	(SH_DIV_STR_FOR_SIZE): Likewise.

diff -u3prN ORIG/gcc-4.1-sh/gcc/config/sh/sh.c LOCAL/gcc-4.1-sh/gcc/config/sh/sh.c
--- ORIG/gcc-4.1-sh/gcc/config/sh/sh.c	Sat Apr  9 02:41:26 2005
+++ LOCAL/gcc-4.1-sh/gcc/config/sh/sh.c	Wed Apr 13 15:43:16 2005
@@ -11121,7 +11121,7 @@ const char *sh_multcost_str = "";
 const char *sh_gettrcost_str = "100";
 const char *sh_div_str = "";
 const char *cut2_workaround_str = "";
-enum sh_divide_strategy_e sh_div_strategy = SH_DIV_CALL;
+enum sh_divide_strategy_e sh_div_strategy = SH_DIV_STRATEGY_DEFAULT;
 
 /* This defines the storage for the variable part of a -mboard= option.
    It is only required when using the sh-superh-elf target */
diff -u3prN ORIG/gcc-4.1-sh/gcc/config/sh/sh.h LOCAL/gcc-4.1-sh/gcc/config/sh/sh.h
--- ORIG/gcc-4.1-sh/gcc/config/sh/sh.h	Sat Apr  9 02:41:30 2005
+++ LOCAL/gcc-4.1-sh/gcc/config/sh/sh.h	Wed Apr 13 16:06:26 2005
@@ -762,6 +762,10 @@ extern int target_flags;
 %(subtarget_link_emul_suffix) \
 %{mrelax:-relax} %(subtarget_link_spec)"
 
+#ifndef SH_DIV_STR_FOR_SIZE
+#define SH_DIV_STR_FOR_SIZE "call"
+#endif
+
 #define DRIVER_SELF_SPECS "%{m2a:%{ml:%eSH2a does not support little-endian}}"
 #define OPTIMIZATION_OPTIONS(LEVEL,SIZE)				\
 do {									\
@@ -774,7 +778,7 @@ do {									\
   if (SIZE)								\
     {									\
       target_flags |= SPACE_BIT;					\
-      sh_div_str = "call";						\
+      sh_div_str = SH_DIV_STR_FOR_SIZE ;				\
     }									\
   if (TARGET_SHMEDIA && LEVEL > 1)					\
     {									\
@@ -804,6 +808,10 @@ enum sh_divide_strategy_e {
 };
 
 extern enum sh_divide_strategy_e sh_div_strategy;
+
+#ifndef SH_DIV_STRATEGY_DEFAULT
+#define SH_DIV_STRATEGY_DEFAULT SH_DIV_CALL
+#endif
 
 #define OVERRIDE_OPTIONS 						\
 do {									\
diff -u3prN ORIG/gcc-4.1-sh/gcc/config/sh/linux.h LOCAL/gcc-4.1-sh/gcc/config/sh/linux.h
--- ORIG/gcc-4.1-sh/gcc/config/sh/linux.h	Sat Apr  9 02:41:26 2005
+++ LOCAL/gcc-4.1-sh/gcc/config/sh/linux.h	Wed Apr 13 16:08:35 2005
@@ -105,3 +105,10 @@ Boston, MA 02111-1307, USA.  */
 #undef DBX_REGISTER_NUMBER
 #define DBX_REGISTER_NUMBER(REGNO) \
   ((! TARGET_SH5 && (REGNO) == 16) ? 16 : SH_DBX_REGISTER_NUMBER (REGNO))
+
+/* Since libgcc is compiled with -fpic for this target, we can't use
+   __sdivsi3_1 as the division strategy for -O0 and -Os.  */
+#undef SH_DIV_STRATEGY_DEFAULT
+#define SH_DIV_STRATEGY_DEFAULT SH_DIV_CALL2
+#undef SH_DIV_STR_FOR_SIZE
+#define SH_DIV_STR_FOR_SIZE "call2"

diff -u3prN ORIG/gcc-4.1-sh/gcc/config/sh/netbsd-elf.h LOCAL/gcc-4.1-sh/gcc/config/sh/netbsd-elf.h
--- ORIG/gcc-4.1-sh/gcc/config/sh/netbsd-elf.h	Tue Jun 22 03:18:40 2004
+++ LOCAL/gcc-4.1-sh/gcc/config/sh/netbsd-elf.h	Wed Apr 13 20:52:07 2005
@@ -1,5 +1,5 @@
 /* Definitions for SH running NetBSD using ELF
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Wasabi Systems, Inc.
 
 This file is part of GCC.
@@ -114,3 +114,10 @@ do									\
       }									\
   }									\
 while (0)
+
+/* Since libgcc is compiled with -fpic for this target, we can't use
+   __sdivsi3_1 as the division strategy for -O0 and -Os.  */
+#undef SH_DIV_STRATEGY_DEFAULT
+#define SH_DIV_STRATEGY_DEFAULT SH_DIV_CALL2
+#undef SH_DIV_STR_FOR_SIZE
+#define SH_DIV_STR_FOR_SIZE "call2"


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