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 for rs6000 .sdata handling, especially with C++ and Java



This fixes various problems with .sdata handling.  It avoids
unnecessarily putting static variables in .sdata when they would
never be referenced there.  It somewhat simplifies the code.
It also handles .sdata and .sdata2 properly in the presence of
-fdata-sections and C++ weak linking; this part requires a patch to ld
(sold separately :-).

Bootstrapped on powerpc-linux and tested with (plain), -fpic and
-msdata.  -msdata now passes with no extra regressions but for the
cases where the testsuite uses -fpic, since -fpic -msdata is not
presently allowed.

I'll commit this once the linker patch is OKed.

-- 
- Geoffrey Keating <geoffk@cygnus.com>

===File ~/patches/cygnus/rs6000-sdata_data.patch============
2000-08-08  Geoff Keating  <geoffk@cygnus.com>

	* config/rs6000/rs6000.c (rs6000_select_section): Rewrite to
	not put stuff in .sdata unnecessarily.
	(rs6000_unique_section): New function.
	* config/rs6000/rs6000-protos.h: Add rs6000_unique_section.
	* config/rs6000/sysv4.h (UNIQUE_SECTION): Define.

Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.9
diff -p -u -u -p -r1.9 rs6000-protos.h
--- rs6000-protos.h	2000/08/08 18:50:15	1.9
+++ rs6000-protos.h	2000/08/09 02:36:24
@@ -126,6 +126,7 @@ extern int rs6000_valid_type_attribute_p
 extern void rs6000_set_default_type_attributes PARAMS ((tree));
 extern void rs6000_encode_section_info PARAMS ((tree));
 extern void rs6000_select_section PARAMS ((tree, int));
+extern void rs6000_unique_section PARAMS ((tree, int));
 #ifdef ARGS_SIZE_RTX
 /* expr.h defines ARGS_SIZE_RTX and `enum direction' */
 extern enum direction function_arg_padding PARAMS ((enum machine_mode, tree));
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.141
diff -p -u -u -p -r1.141 rs6000.c
--- rs6000.c	2000/08/08 18:50:14	1.141
+++ rs6000.c	2000/08/09 02:36:47
@@ -7355,45 +7355,104 @@ rs6000_select_section (decl, reloc)
      int reloc;
 {
   int size = int_size_in_bytes (TREE_TYPE (decl));
+  int needs_sdata;
+  int readonly;
+  static void (* const sec_funcs[4]) PARAMS ((void)) = {
+    &const_section,
+    &sdata2_section,
+    &data_section,
+    &sdata_section
+  };
+  
+  needs_sdata = (size > 0 
+		 && size <= g_switch_value
+		 && rs6000_sdata != SDATA_NONE
+		 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
 
   if (TREE_CODE (decl) == STRING_CST)
-    {
-      if (! flag_writable_strings)
-	const_section ();
-      else
-	data_section ();
-    }
+    readonly = ! flag_writable_strings;
   else if (TREE_CODE (decl) == VAR_DECL)
-    {
-      if ((flag_pic && reloc)
-	  || ! TREE_READONLY (decl)
-	  || TREE_SIDE_EFFECTS (decl)
-	  || ! DECL_INITIAL (decl)
-	  || (DECL_INITIAL (decl) != error_mark_node
-	      && ! TREE_CONSTANT (DECL_INITIAL (decl))))
-	{
-	  if (rs6000_sdata != SDATA_NONE && (size > 0)
-	      && (size <= g_switch_value))
-	    sdata_section ();
-	  else
-	    data_section ();
-	}
-      else
-	{
-	  if (rs6000_sdata != SDATA_NONE && (size > 0)
-	      && (size <= g_switch_value))
-	    {
-	      if (rs6000_sdata == SDATA_EABI)
-		sdata2_section ();
-	      else
-		sdata_section ();  /* System V doesn't have .sdata2/.sbss2 */
-	    }
-	  else
-	    const_section ();
-	}
-    }
+    readonly = (! (flag_pic && reloc)
+		&& TREE_READONLY (decl)
+		&& ! TREE_SIDE_EFFECTS (decl)
+		&& DECL_INITIAL (decl)
+		&& DECL_INITIAL (decl) != error_mark_node
+		&& TREE_CONSTANT (DECL_INITIAL (decl)));
   else
-    const_section ();
+    readonly = 1;
+  if (needs_sdata && rs6000_sdata != SDATA_EABI)
+    readonly = 0;
+  
+  (*sec_funcs[(readonly ? 0 : 2) + (needs_sdata ? 1 : 0)])();
+}
+
+/* A C statement to build up a unique section name, expressed as a
+   STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
+   RELOC indicates whether the initial value of EXP requires
+   link-time relocations.  If you do not define this macro, GCC will use
+   the symbol name prefixed by `.' as the section name.  Note - this
+   macro can now be called for unitialised data items as well as
+   initialised data and functions.  */
+
+void
+rs6000_unique_section (decl, reloc)
+     tree decl;
+     int reloc;
+{
+  int size = int_size_in_bytes (TREE_TYPE (decl));
+  int needs_sdata;
+  int readonly;
+  int len;
+  int sec;
+  const char *name;
+  char *string;
+  const char *prefix;
+
+  static const char *const prefixes[7][2] =
+  {
+    { ".text.",   ".gnu.linkonce.t." },
+    { ".rodata.", ".gnu.linkonce.r." },
+    { ".sdata2.", ".gnu.linkonce.s2." },
+    { ".data.",   ".gnu.linkonce.d." },
+    { ".sdata.",  ".gnu.linkonce.s." },
+    { ".bss.",    ".gnu.linkonce.b." },
+    { ".sbss.",   ".gnu.linkonce.sb." }
+  };
+  
+  needs_sdata = (TREE_CODE (decl) != FUNCTION_DECL
+		 && size > 0 
+		 && size <= g_switch_value
+		 && rs6000_sdata != SDATA_NONE
+		 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
+
+  if (TREE_CODE (decl) == STRING_CST)
+    readonly = ! flag_writable_strings;
+  else if (TREE_CODE (decl) == VAR_DECL)
+    readonly = (! (flag_pic && reloc)
+		&& TREE_READONLY (decl)
+		&& ! TREE_SIDE_EFFECTS (decl)
+		&& DECL_INITIAL (decl)
+		&& DECL_INITIAL (decl) != error_mark_node
+		&& TREE_CONSTANT (DECL_INITIAL (decl)));
+  else
+    readonly = 1;
+  if (needs_sdata && rs6000_sdata != SDATA_EABI)
+    readonly = 0;
+
+  sec = ((TREE_CODE (decl) == FUNCTION_DECL ? 0 : 1)
+	 + (readonly ? 0 : 2) 
+	 + (needs_sdata ? 1 : 0)
+	 + (DECL_INITIAL (decl) == 0
+	    || DECL_INITIAL (decl) == error_mark_node) ? 4 : 0);
+
+  name   = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+  prefix = prefixes[sec][DECL_ONE_ONLY (decl)];
+  len    = strlen (name) + strlen (prefix);
+  string = alloca (len + 1);
+  
+  sprintf (string, "%s%s", prefix, name);
+  
+  DECL_SECTION_NAME (decl) = build_string (len, string);
 }
 
 
Index: gcc/config/rs6000/sysv4.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.32
diff -p -u -u -p -r1.32 sysv4.h
--- sysv4.h	2000/07/21 00:46:23	1.32
+++ sysv4.h	2000/08/09 02:36:51
@@ -549,7 +549,19 @@ fini_section ()								\
 
 /* Override elfos.h definition.  */
 #undef	SELECT_SECTION
-#define	SELECT_SECTION(DECL,RELOC) rs6000_select_section (DECL, RELOC)
+#define	SELECT_SECTION(DECL, RELOC) rs6000_select_section (DECL, RELOC)
+
+/* A C statement to build up a unique section name, expressed as a
+   STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
+   RELOC indicates whether the initial value of EXP requires
+   link-time relocations.  If you do not define this macro, GCC will use
+   the symbol name prefixed by `.' as the section name.  Note - this
+   macro can now be called for unitialised data items as well as
+   initialised data and functions.  */
+
+/* Override elfos.h definition.  */
+#undef	UNIQUE_SECTION
+#define UNIQUE_SECTION(DECL, RELOC) rs6000_unique_section (DECL, RELOC)
 
 /* Return non-zero if this entry is to be written into the constant pool
    in a special way.  We do so if this is a SYMBOL_REF, LABEL_REF or a CONST
============================================================

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