[PATCH] SHF_MERGE support for gcc (take 4)

Jakub Jelinek jakub@redhat.com
Mon Sep 10 08:34:00 GMT 2001


Hi!

See e.g. http://gcc.gnu.org/ml/gcc-patches/2001-05/msg00253.html
for more info.
Bootstrapped on i386-redhat-linux, one regression (buggy testcase
execute/20000801-4.c).
Similar versions of the patch (for 2.96-RH and 3.0.1) are used in our linux
distribution for more than 2 months without problems on IA-32, IA-64 and
Alpha. It bootstraps (2.96-RH patch) on sparc-linux too.
Ok to commit?

2001-09-10  Jakub Jelinek  <jakub@redhat.com>

	* configure.in: Check whether assembler supports section merging.
	* config.in: Rebuilt.
	* configure: Rebuilt.
	* varasm.c (variable_section, output_constant_pool): Pass alignment
	to SELECT_SECTION and SELECT_RTX_SECTION.
	* toplev.c (flag_merge_constants): New.
	(f_options): Add -fmerge-constants and -fmerge-all-constants
	options.
	(toplev_main): Default to -fno-merge-constants if not optimizing.
	* flags.h (flag_merge_constants): Add extern.
	* invoke.texi (-fmerge-constants, -fmerge-all-constants): Document.
	* tm.texi (SELECT_SECTION, SELECT_RTX_SECTION): Document added third
	argument.
	* config/elfos.h (EXTRA_SECTIONS): Add new sections.
	(EXTRA_SECTION_FUNCTIONS): Add CONST_STR_SECTION_FUNCTION and
	CONST_VAR_SECTION_FUNCTION.
	(USE_GAS_SUBSECTION_ORDERING, CONST_STR_SECTION_FUNCTION,
	CONST_VAR_SECTION_FUNCTION): Define.
	(SELECT_RTX_SECTION, SELECT_SECTION): Add third macro argument.
	Put constant into special SHF_MERGE sections if the linker should
	attempt to merge duplicates.
	* config/ia64/sysv4.h (EXTRA_SECTIONS): Add new sections.
	(EXTRA_SECTION_FUNCTIONS): Add CONST_STR_SECTION_FUNCTION and
	CONST_VAR_SECTION_FUNCTION.
	(SELECT_RTX_SECTION, SELECT_SECTION): Add third macro argument.
	Put constant into special SHF_MERGE sections if the linker should
	attempt to merge duplicates.
	* config/alpha/elf.h: Likewise.
	* config/nextstep.h: Add third argument to SELECT_RTX_SECTION and
	SELECT_SECTION.
	* config/svr3.h: Likewise.
	* config/darwin.h: Likewise.
	* config/arm/aof.h: Likewise.
	* config/arm/linux-elf.h: Likewise.
	* config/avr/avr.h: Likewise.
	* config/c4x/c4x.h: Likewise.
	* config/d30v/d30v.h: Likewise.
	* config/i386/dgux.h: Likewise.
	* config/i386/osfrose.h: Likewise.
	* config/i386/sco5.h: Likewise.
	* config/i386/svr3gas.h: Likewise.
	* config/ia64/aix.h: Likewise.
	* config/m32r/m32r.h: Likewise.
	* config/m68k/m68k.h: Likewise.
	* config/m88k/dgux.h: Likewise.
	* config/m88k/m88k.h: Likewise.
	* config/mcore/mcore-pe.h: Likewise.
	* config/mips/mips.h: Likewise.
	* config/pa/pa.h: Likewise.
	* config/pa/pa-linux.h: Likewise.
	* config/romp/romp.h: Likewise.
	* config/rs6000/sysv4.h: Likewise.
	* config/rs6000/xcoff.h: Likewise.
	* config/s390/linux.h: Likewise.
	* config/sparc/sparc.h: Likewise.
	* config/sparc/sysv4.h: Likewise.
	* config/stormy16/stormy16.h: Likewise.
	* config/v850/v850.h: Likewise.
	* config/vax/vms.h: Likewise.

	* com.c (ffe_init_options): Default to -fmerge-all-constants
	if optimizing.

--- gcc/varasm.c.jj	Mon Sep  3 19:53:52 2001
+++ gcc/varasm.c	Mon Sep 10 11:11:39 2001
@@ -560,7 +560,7 @@ variable_section (decl, reloc)
 	 for them.  */
 
 #ifdef SELECT_SECTION
-      SELECT_SECTION (decl, reloc);
+      SELECT_SECTION (decl, reloc, DECL_ALIGN (decl));
 #else
       if (DECL_READONLY_SECTION (decl, reloc))
 	readonly_data_section ();
@@ -3305,13 +3305,19 @@ output_constant_def_contents (exp, reloc
 {
   int align;
 
+  /* Align the location counter as required by EXP's data type.  */
+  align = TYPE_ALIGN (TREE_TYPE (exp));
+#ifdef CONSTANT_ALIGNMENT
+  align = CONSTANT_ALIGNMENT (exp, align);
+#endif
+
   if (IN_NAMED_SECTION (exp))
     named_section (exp, NULL, reloc);
   else
     {
       /* First switch to text section, except for writable strings.  */
 #ifdef SELECT_SECTION
-      SELECT_SECTION (exp, reloc);
+      SELECT_SECTION (exp, reloc, align);
 #else
       if (((TREE_CODE (exp) == STRING_CST) && flag_writable_strings)
 	  || (flag_pic && reloc))
@@ -3321,12 +3327,6 @@ output_constant_def_contents (exp, reloc
 #endif
     }
 
-  /* Align the location counter as required by EXP's data type.  */
-  align = TYPE_ALIGN (TREE_TYPE (exp));
-#ifdef CONSTANT_ALIGNMENT
-  align = CONSTANT_ALIGNMENT (exp, align);
-#endif
-
   if (align > BITS_PER_UNIT)
     ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
 
@@ -3877,7 +3877,7 @@ output_constant_pool (fnname, fndecl)
 
       /* First switch to correct section.  */
 #ifdef SELECT_RTX_SECTION
-      SELECT_RTX_SECTION (pool->mode, x);
+      SELECT_RTX_SECTION (pool->mode, x, pool->align);
 #else
       readonly_data_section ();
 #endif
--- gcc/doc/tm.texi.jj	Mon Sep  3 19:53:59 2001
+++ gcc/doc/tm.texi	Mon Sep 10 11:11:39 2001
@@ -5650,25 +5650,26 @@ If these items should be placed in the t
 not be defined.
 
 @findex SELECT_SECTION
-@item SELECT_SECTION (@var{exp}, @var{reloc})
+@item SELECT_SECTION (@var{exp}, @var{reloc}, @var{align})
 A C statement or statements to switch to the appropriate section for
 output of @var{exp}.  You can assume that @var{exp} is either a
 @code{VAR_DECL} node or a constant of some sort.  @var{reloc}
 indicates whether the initial value of @var{exp} requires link-time
 relocations.  Select the section by calling @code{text_section} or one
-of the alternatives for other sections.
+of the alternatives for other sections.  @var{align} is the constant
+alignment in bits.
 
 Do not define this macro if you put all read-only variables and
 constants in the read-only data section (usually the text section).
 
 @findex SELECT_RTX_SECTION
-@item SELECT_RTX_SECTION (@var{mode}, @var{rtx})
+@item SELECT_RTX_SECTION (@var{mode}, @var{rtx}, @var{align})
 A C statement or statements to switch to the appropriate section for
 output of @var{rtx} in mode @var{mode}.  You can assume that @var{rtx}
 is some kind of constant in RTL@.  The argument @var{mode} is redundant
 except in the case of a @code{const_int} rtx.  Select the section by
 calling @code{text_section} or one of the alternatives for other
-sections.
+sections.  @var{align} is the constant alignment in bits.
 
 Do not define this macro if you put all constants in the read-only
 data section.
--- gcc/doc/invoke.texi.jj	Mon Sep 10 10:34:56 2001
+++ gcc/doc/invoke.texi	Mon Sep 10 11:11:40 2001
@@ -262,8 +262,8 @@ in the following sections.
 -fforce-addr  -fforce-mem  -ffunction-sections @gol
 -fgcse  -fgcse-lm  -fgcse-sm @gol
 -finline-functions  -finline-limit=@var{n}  -fkeep-inline-functions @gol
--fkeep-static-consts  -fmove-all-movables @gol
--fno-default-inline  -fno-defer-pop @gol
+-fkeep-static-consts  -fmerge-constants  -fmerge-all-constants @gol
+-fmove-all-movables  -fno-default-inline  -fno-defer-pop @gol
 -fno-function-cse  -fno-guess-branch-probability @gol
 -fno-inline  -fno-math-errno  -fno-peephole  -fno-peephole2 @gol
 -funsafe-math-optimizations -fno-trapping-math @gol
@@ -3320,6 +3320,23 @@ on, even if the variables aren't referen
 GCC enables this option by default.  If you want to force the compiler to
 check if the variable was referenced, regardless of whether or not
 optimization is turned on, use the @option{-fno-keep-static-consts} option.
+
+@item -fmerge-constants
+Attempt to merge identical constants (string constants and floating point
+constants) accross compilation units.
+
+This option is default for optimized compilation if assembler and linker
+support it.  Use @samp{-fno-merge-constants} to inhibit this behaviour.
+
+@item -fmerge-all-constants
+Attempt to merge identical constants and identical variables.
+
+This option implies @samp{-fmerge-constants}.  In addition to
+@samp{-fmerge-constants} this considers e.g. even constant initialized
+arrays or initialized constant variables with integral or floating point
+types.  Languages like C or C++ require each non-automatic variable to
+have distinct location, so using this option will result in non-conforming
+behaviour.
 
 @item -fno-function-cse
 @opindex fno-function-cse
--- gcc/config.in.jj	Sun Jul 22 21:33:44 2001
+++ gcc/config.in	Mon Sep 10 11:11:40 2001
@@ -475,6 +475,9 @@
 /* Define if your assembler mis-optimizes .eh_frame data. */
 #undef USE_AS_TRADITIONAL_FORMAT
 
+/* Define if your assembler supports marking sections with SHF_MERGE flag. */
+#undef HAVE_GAS_SHF_MERGE
+
 /* Define if your assembler supports .register. */
 #undef HAVE_AS_REGISTER_PSEUDO_OP
 
--- gcc/configure.in.jj	Mon Sep  3 19:53:23 2001
+++ gcc/configure.in	Mon Sep 10 11:11:40 2001
@@ -1484,6 +1484,26 @@ EOF
 fi
 AC_MSG_RESULT($gcc_cv_as_eh_frame)
 
+AC_MSG_CHECKING(assembler section merging support)
+gcc_cv_as_shf_merge=no
+if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
+  if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 12 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
+    gcc_cv_as_subsections="working SHF_MERGE support"
+  fi
+elif test x$gcc_cv_as != x; then
+	# Check if we support SHF_MERGE sections
+	echo '.section .rodata.str, "ams", @progbits, 1' > conftest.s
+	if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
+		gcc_cv_as_shf_merge=yes
+	fi
+	rm -f conftest.s conftest.o
+fi
+if test x"$gcc_cv_as_shf_merge" = xyes; then
+	AC_DEFINE(HAVE_GAS_SHF_MERGE, 1,
+[Define if your assembler supports marking sections with SHF_MERGE flag.])
+fi
+AC_MSG_RESULT($gcc_cv_as_shf_merge)
+
 case "$target" in 
   sparc*-*-*)
     AC_CACHE_CHECK([assembler .register pseudo-op support],
--- gcc/configure.jj	Sat Aug 18 22:10:27 2001
+++ gcc/configure	Mon Sep 10 11:11:40 2001
@@ -7164,6 +7164,29 @@ EOF
 fi
 echo "$ac_t""$gcc_cv_as_eh_frame" 1>&6
 
+echo $ac_n "checking assembler section merging support""... $ac_c" 1>&6
+echo "configure:6569: checking assembler section merging support" >&5
+gcc_cv_as_shf_merge=no
+if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
+  if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 12 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
+    gcc_cv_as_subsections="working SHF_MERGE support"
+  fi
+elif test x$gcc_cv_as != x; then
+	# Check if we support SHF_MERGE sections
+	echo '.section .rodata.str, "ams", @progbits, 1' > conftest.s
+	if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
+		gcc_cv_as_shf_merge=yes
+	fi
+	rm -f conftest.s conftest.o
+fi
+if test x"$gcc_cv_as_shf_merge" = xyes; then
+	cat >> confdefs.h <<\EOF
+#define HAVE_GAS_SHF_MERGE 1
+EOF
+
+fi
+echo "$ac_t""$gcc_cv_as_shf_merge" 1>&6
+
 case "$target" in 
   sparc*-*-*)
     echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
--- gcc/toplev.c.jj	Mon Sep 10 10:34:47 2001
+++ gcc/toplev.c	Mon Sep 10 11:11:40 2001
@@ -898,6 +898,11 @@ int flag_bounded_pointers = 0;
    For CHILL: defaults to off.  */
 int flag_bounds_check = 0;
 
+/* This will attempt to merge constant section constants, if 1 only
+   string constants and constants from constant pool, if 2 also constant
+   variables.  */
+int flag_merge_constants = 1;
+
 /* If one, renumber instruction UIDs to reduce the number of
    unused UIDs if there are a lot of instructions.  If greater than
    one, unconditionally renumber instruction UIDs.  */
@@ -1139,6 +1144,10 @@ lang_independent_options f_options[] =
    N_("Align all labels") },
   {"align-functions", &align_functions, 0,
    N_("Align the start of functions") },
+  {"merge-constants", &flag_merge_constants, 1,
+   N_("Attempt to merge identical constants accross compilation units") },
+  {"merge-all-constants", &flag_merge_constants, 2,
+   N_("Attempt to merge identical constants and constant variables") },
   {"check-memory-usage", &flag_check_memory_usage, 1,
    N_("Generate code to check every memory access") },
   {"prefix-function-name", &flag_prefix_function_name, 1,
@@ -4678,6 +4687,11 @@ toplev_main (argc, argv)
 		}
 	    }
 	}
+    }
+
+  if (!optimize)
+    {
+      flag_merge_constants = 0;
     }
 
   if (optimize >= 1)
--- gcc/flags.h.jj	Mon Sep  3 19:53:31 2001
+++ gcc/flags.h	Mon Sep 10 11:11:40 2001
@@ -544,6 +544,11 @@ extern int flag_bounded_pointers;
    For CHILL: defaults to off.  */
 extern int flag_bounds_check;
 
+/* This will attempt to merge constant section constants, if 1 only
+   string constants and constants from constant pool, if 2 also constant
+   variables.  */
+extern int flag_merge_constants;
+
 /* If one, renumber instruction UIDs to reduce the number of
    unused UIDs if there are a lot of instructions.  If greater than
    one, unconditionally renumber instruction UIDs.  */
--- gcc/config/elfos.h.jj	Sat Aug 18 22:10:35 2001
+++ gcc/config/elfos.h	Mon Sep 10 11:58:22 2001
@@ -268,7 +268,15 @@ Boston, MA 02111-1307, USA.  */
    includes this file.  */
 
 #undef  EXTRA_SECTIONS
+#ifdef HAVE_GAS_SHF_MERGE
+#define EXTRA_SECTIONS in_const,				\
+  in_const_cst1, in_const_cst2, in_const_cst4,			\
+  in_const_cst8, in_const_cst16, in_const_str1 = 256,		\
+  in_const_str2 = 256 + 32, in_const_str4 = 256 + 2*32,		\
+  in_const_str8 = 256 + 3*32
+#else
 #define EXTRA_SECTIONS in_const
+#endif
 
 /* A default list of extra section function definitions.  For targets
    that use additional sections (e.g. .tdesc) you should override this
@@ -276,10 +284,146 @@ Boston, MA 02111-1307, USA.  */
 
 #undef  EXTRA_SECTION_FUNCTIONS
 #define EXTRA_SECTION_FUNCTIONS		\
-  CONST_SECTION_FUNCTION
+  CONST_SECTION_FUNCTION		\
+  CONST_STR_SECTION_FUNCTION		\
+  CONST_VAR_SECTION_FUNCTION
 
 #define READONLY_DATA_SECTION() const_section ()
 
+#ifdef HAVE_GAS_SUBSECTION_ORDERING
+#define USE_GAS_SUBSECTION_ORDERING 1
+#else
+#define USE_GAS_SUBSECTION_ORDERING 0
+#endif
+
+#ifdef HAVE_GAS_SHF_MERGE
+#define CONST_STR_SECTION_FUNCTION					\
+extern void const_str_section PARAMS ((tree, unsigned HOST_WIDE_INT));	\
+									\
+void									\
+const_str_section (decl, align)						\
+     tree decl;								\
+     unsigned HOST_WIDE_INT align;					\
+{									\
+  enum in_section in;							\
+  enum machine_mode mode;						\
+  const char *str;							\
+  int i, j, len, unit;							\
+									\
+  if (flag_merge_constants						\
+      && USE_CONST_SECTION						\
+      && TREE_CODE (decl) == STRING_CST					\
+      && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE			\
+      && align <= 256)							\
+    {									\
+      mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (decl)));			\
+      switch (GET_MODE_BITSIZE (mode))					\
+	{								\
+	case 8: in = in_const_str1; break;				\
+	case 16: in = in_const_str2; break;				\
+	case 32: in = in_const_str4; break;				\
+	case 64: in = in_const_str8; break;				\
+	default: in = no_section; break;				\
+	}								\
+      if (align < GET_MODE_BITSIZE (mode))				\
+	align = GET_MODE_BITSIZE (mode);				\
+      if (in != no_section)						\
+	{								\
+	  str = TREE_STRING_POINTER (decl);				\
+	  len = TREE_STRING_LENGTH (decl);				\
+	  unit = GET_MODE_SIZE (mode);					\
+	  /* Check for embedded NUL characters.  */			\
+	  for (i = 0; i < len; i += unit)				\
+	    {								\
+	      for (j = 0; j < unit; j++)				\
+		if (str [i + j] != '\0')				\
+		  break;						\
+	      if (j == unit)						\
+		break;							\
+	    }								\
+	  if (i == len - unit)						\
+	    {								\
+	      unit = GET_MODE_BITSIZE (mode) / 8;			\
+	      if (!i && GET_MODE_BITSIZE (mode) < align)		\
+		{							\
+		  /* A "" string with requested alignment greater than	\
+		     character size might cause a problem:		\
+		     if some other string required even bigger		\
+		     alignment than "", then linker might think the	\
+		     "" is just part of padding after some other string	\
+		     and not put it into the hash table initially.	\
+		     But this means "" could have smaller alignment	\
+		     than requested.  */				\
+		  if (USE_GAS_SUBSECTION_ORDERING)			\
+		    {							\
+		      fprintf (asm_out_file,				\
+"\t.section\t.rodata.str%d.%d,\"ams\",@progbits,%d\n\t.subsection\t-1\n",\
+			       unit, (int) (align / 8), unit);		\
+		      in_section = in;					\
+		    }							\
+		  else							\
+		    const_section ();					\
+		  return;						\
+		}							\
+	      in = (enum in_section) ((int) in + align / 8);		\
+	      if (in_section != in)					\
+		{							\
+		  fprintf (asm_out_file,				\
+"\t.section\t.rodata.str%d.%d,\"ams\",@progbits,%d\n",			\
+			   unit, (int) (align / 8), unit);		\
+		  in_section = in;					\
+		}							\
+	      return;							\
+	    }								\
+	}								\
+    }									\
+  const_section ();							\
+}
+
+#define CONST_VAR_SECTION_FUNCTION					\
+extern void const_var_section						\
+  PARAMS ((enum machine_mode, unsigned HOST_WIDE_INT));			\
+									\
+void									\
+const_var_section (mode, align)						\
+     enum machine_mode mode;						\
+     unsigned HOST_WIDE_INT align;					\
+{									\
+  if (flag_merge_constants && mode != VOIDmode && mode != BLKmode	\
+      && GET_MODE_BITSIZE (mode) <= align)				\
+    {									\
+      enum in_section in;						\
+									\
+      switch (align)							\
+	{								\
+	case 8: in = in_const_cst1; break;				\
+	case 16: in = in_const_cst2; break;				\
+	case 32: in = in_const_cst4; break;				\
+	case 64: in = in_const_cst8; break;				\
+	case 128: in = in_const_cst16; break;				\
+	default: in = no_section; break;				\
+	}								\
+      if (in_section != no_section)					\
+	{								\
+	  if (in_section != in)						\
+	    {								\
+	      fprintf (asm_out_file,					\
+"\t.section\t.rodata.cst%d,\"am\",@progbits,%d\n",			\
+		       (int) (align / 8), (int) (align / 8));		\
+	      in_section = in;						\
+	    }								\
+	  return;							\
+	}								\
+    }									\
+  const_section ();							\
+}
+#else
+#define CONST_STR_SECTION_FUNCTION
+#define CONST_VAR_SECTION_FUNCTION
+#define const_str_section(DECL,ALIGN) const_section ()
+#define const_var_section(MODE,ALIGN) const_section ()
+#endif
+
 #define CONST_SECTION_FUNCTION					\
 void								\
 const_section ()						\
@@ -340,11 +484,14 @@ const_section ()						\
 /* A C statement or statements to switch to the appropriate
    section for output of RTX in mode MODE.  RTX is some kind
    of constant in RTL.  The argument MODE is redundant except
-   in the case of a `const_int' rtx.  Currently, these always
-   go into the const section.  */
+   in the case of a `const_int' rtx.
+   If assembler supports SHF_MERGE sections, put it into
+   a .rodata.cstN section where N is size of the constant,
+   otherwise into const section.  */
 
 #undef  SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE, RTX) const_section ()
+#define SELECT_RTX_SECTION(MODE, RTX, ALIGN)	\
+  const_var_section ((MODE), (ALIGN))
 
 /* A C statement or statements to switch to the appropriate
    section for output of DECL.  DECL is either a `VAR_DECL' node
@@ -352,12 +499,12 @@ const_section ()						\
    the initial value of DECL requires link-time relocations.  */
 
 #undef SELECT_SECTION
-#define SELECT_SECTION(DECL, RELOC)				\
+#define SELECT_SECTION(DECL, RELOC, ALIGN)			\
 {								\
   if (TREE_CODE (DECL) == STRING_CST)				\
     {								\
       if (! flag_writable_strings)				\
-	const_section ();					\
+	const_str_section ((DECL), (ALIGN));			\
       else							\
 	data_section ();					\
     }								\
@@ -369,8 +516,15 @@ const_section ()						\
 	  || (DECL_INITIAL (DECL) != error_mark_node		\
 	      && !TREE_CONSTANT (DECL_INITIAL (DECL))))		\
 	data_section ();					\
-      else							\
+      else if (flag_merge_constants < 2)			\
+	/* C and C++ don't allow different variables to share	\
+	   the same location.  -fmerge-all-constants allows	\
+	   even that (at the expense of not conforming).  */	\
 	const_section ();					\
+      else if (TREE_CODE (DECL_INITIAL (DECL)) == STRING_CST)	\
+	const_str_section (DECL_INITIAL (DECL), (ALIGN));	\
+      else							\
+	const_var_section (DECL_MODE (DECL), (ALIGN));		\
     }								\
   else if (TREE_CODE (DECL) == CONSTRUCTOR)			\
     {								\
--- gcc/config/s390/linux.h.jj	Sat Aug 18 22:10:45 2001
+++ gcc/config/s390/linux.h	Mon Sep 10 12:04:52 2001
@@ -295,7 +295,7 @@ do {                                    
  */
 
 #undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE, X)
+#define SELECT_RTX_SECTION(MODE, X, ALIGN)
 
 
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
--- gcc/config/alpha/elf.h.jj	Mon Sep 10 10:34:48 2001
+++ gcc/config/alpha/elf.h	Mon Sep 10 11:35:59 2001
@@ -228,7 +228,15 @@ do {									\
    includes this file.  */
 
 #undef  EXTRA_SECTIONS
+#ifdef HAVE_GAS_SHF_MERGE
+#define EXTRA_SECTIONS in_const, in_sbss, in_sdata,			\
+   in_const_cst1, in_const_cst2, in_const_cst4,				\
+  in_const_cst8, in_const_cst16,					\
+  in_const_str1 = 256, in_const_str2 = 256 + 32,			\
+  in_const_str4 = 256 + 2*32, in_const_str8 = 256 + 3*32
+#else
 #define EXTRA_SECTIONS in_const, in_sbss, in_sdata
+#endif
 
 /* A default list of extra section function definitions.  For targets
    that use additional sections (e.g. .tdesc) you should override this
@@ -237,17 +245,151 @@ do {									\
 #undef  EXTRA_SECTION_FUNCTIONS
 #define EXTRA_SECTION_FUNCTIONS						\
   CONST_SECTION_FUNCTION						\
+  CONST_STR_SECTION_FUNCTION						\
+  CONST_VAR_SECTION_FUNCTION						\
   SECTION_FUNCTION_TEMPLATE(sbss_section, in_sbss, SBSS_SECTION_ASM_OP)	\
   SECTION_FUNCTION_TEMPLATE(sdata_section, in_sdata, SDATA_SECTION_ASM_OP)
 
-extern void ctors_section		PARAMS ((void));
-extern void dtors_section		PARAMS ((void));
 extern void sbss_section		PARAMS ((void));
 extern void sdata_section		PARAMS ((void));
 
 #undef  READONLY_DATA_SECTION
 #define READONLY_DATA_SECTION() const_section ()
 
+#ifdef HAVE_GAS_SUBSECTION_ORDERING
+#define USE_GAS_SUBSECTION_ORDERING 1
+#else
+#define USE_GAS_SUBSECTION_ORDERING 0
+#endif
+
+#ifdef HAVE_GAS_SHF_MERGE
+#define CONST_STR_SECTION_FUNCTION					\
+extern void const_str_section PARAMS ((tree, unsigned HOST_WIDE_INT));	\
+									\
+void									\
+const_str_section (decl, align)						\
+     tree decl;								\
+     unsigned HOST_WIDE_INT align;					\
+{									\
+  enum in_section in;							\
+  enum machine_mode mode;						\
+  const char *str;							\
+  int i, j, len, unit;							\
+									\
+  if (flag_merge_constants						\
+      && USE_CONST_SECTION						\
+      && TREE_CODE (decl) == STRING_CST					\
+      && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE			\
+      && align <= 256)							\
+    {									\
+      mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (decl)));			\
+      switch (GET_MODE_BITSIZE (mode))					\
+	{								\
+	case 8: in = in_const_str1; break;				\
+	case 16: in = in_const_str2; break;				\
+	case 32: in = in_const_str4; break;				\
+	case 64: in = in_const_str8; break;				\
+	default: in = no_section; break;				\
+	}								\
+      if (align < GET_MODE_BITSIZE (mode))				\
+	align = GET_MODE_BITSIZE (mode);				\
+      if (in != no_section)						\
+	{								\
+	  str = TREE_STRING_POINTER (decl);				\
+	  len = TREE_STRING_LENGTH (decl);				\
+	  unit = GET_MODE_SIZE (mode);					\
+	  /* Check for embedded NUL characters.  */			\
+	  for (i = 0; i < len; i += unit)				\
+	    {								\
+	      for (j = 0; j < unit; j++)				\
+		if (str [i + j] != '\0')				\
+		  break;						\
+	      if (j == unit)						\
+		break;							\
+	    }								\
+	  if (i == len - unit)						\
+	    {								\
+	      unit = GET_MODE_BITSIZE (mode) / 8;			\
+	      if (!i && GET_MODE_BITSIZE (mode) < align)		\
+		{							\
+		  /* A "" string with requested alignment greater than	\
+		     character size might cause a problem:		\
+		     if some other string required even bigger		\
+		     alignment than "", then linker might think the	\
+		     "" is just part of padding after some other string	\
+		     and not put it into the hash table initially.	\
+		     But this means "" could have smaller alignment	\
+		     than requested.  */				\
+		  if (USE_GAS_SUBSECTION_ORDERING)			\
+		    {							\
+		      fprintf (asm_out_file,				\
+"\t.section\t.rodata.str%d.%d,\"ams\",@progbits,%d\n\t.subsection\t-1\n",\
+			       unit, (int) (align / 8), unit);		\
+		      in_section = in;					\
+		    }							\
+		  else							\
+		    const_section ();					\
+		  return;						\
+		}							\
+	      in = (enum in_section) ((int) in + align / 8);		\
+	      if (in_section != in)					\
+		{							\
+		  fprintf (asm_out_file,				\
+"\t.section\t.rodata.str%d.%d,\"ams\",@progbits,%d\n",			\
+			   unit, (int) (align / 8), unit);		\
+		  in_section = in;					\
+		}							\
+	      return;							\
+	    }								\
+	}								\
+    }									\
+  const_section ();							\
+}
+
+#define CONST_VAR_SECTION_FUNCTION					\
+extern void const_var_section						\
+  PARAMS ((enum machine_mode, unsigned HOST_WIDE_INT));			\
+									\
+void									\
+const_var_section (mode, align)						\
+     enum machine_mode mode;						\
+     unsigned HOST_WIDE_INT align;					\
+{									\
+  if (flag_merge_constants && mode != VOIDmode && mode != BLKmode	\
+      && GET_MODE_BITSIZE (mode) <= align)				\
+    {									\
+      enum in_section in;						\
+									\
+      switch (align)							\
+	{								\
+	case 8: in = in_const_cst1; break;				\
+	case 16: in = in_const_cst2; break;				\
+	case 32: in = in_const_cst4; break;				\
+	case 64: in = in_const_cst8; break;				\
+	case 128: in = in_const_cst16; break;				\
+	default: in = no_section; break;				\
+	}								\
+      if (in_section != no_section)					\
+	{								\
+	  if (in_section != in)						\
+	    {								\
+	      fprintf (asm_out_file,					\
+"\t.section\t.rodata.cst%d,\"am\",@progbits,%d\n",			\
+		       (int) (align / 8), (int) (align / 8));		\
+	      in_section = in;						\
+	    }								\
+	  return;							\
+	}								\
+    }									\
+  const_section ();							\
+}
+#else
+#define CONST_STR_SECTION_FUNCTION
+#define CONST_VAR_SECTION_FUNCTION
+#define const_str_section(DECL,ALIGN) const_section ()
+#define const_var_section(MODE,ALIGN) const_section ()
+#endif
+
 #undef  CONST_SECTION_FUNCTION
 #define CONST_SECTION_FUNCTION					\
 void								\
@@ -300,6 +442,8 @@ void FN ()					\
 	 {							\
 	   if (flag_writable_strings)				\
 	     SECNUM = 2;					\
+	   else							\
+	     SECNUM = 0x101;					\
 	 }							\
        else if (TREE_CODE (DECL) == VAR_DECL)			\
 	 {							\
@@ -311,6 +455,17 @@ void FN ()					\
 		    || TREE_SIDE_EFFECTS (DECL)			\
 		    || ! TREE_CONSTANT (DECL_INITIAL (DECL)))	\
 	     SECNUM = 2;					\
+	  else if (flag_merge_constants >= 2)			\
+	    {							\
+	      /* C and C++ don't allow different variables to	\
+		 share the same location.  -fmerge-all-constants\
+		 allows even that (at the expense of not	\
+		 conforming).  */				\
+	      if (TREE_CODE (DECL_INITIAL (DECL)) == STRING_CST)\
+		SECNUM = 0x201;					\
+	      else						\
+		SECNUM = 0x301;					\
+	    }							\
 	 }							\
        else if (TREE_CODE (DECL) == CONSTRUCTOR)		\
 	 {							\
@@ -332,7 +487,7 @@ void FN ()					\
    while (0)
 
 #undef  SELECT_SECTION
-#define SELECT_SECTION(DECL, RELOC)		\
+#define SELECT_SECTION(DECL, RELOC, ALIGN)	\
   do						\
     {						\
       typedef void (*sec_fn) PARAMS ((void));	\
@@ -350,7 +505,23 @@ void FN ()					\
 						\
       DO_SELECT_SECTION (sec, DECL, RELOC);	\
 						\
-      (*sec_functions[sec]) ();			\
+      switch (sec)				\
+	{					\
+	case 0x101:				\
+	  const_str_section (DECL, ALIGN);	\
+	  break;				\
+	case 0x201:				\
+	  const_str_section (DECL_INITIAL (DECL),\
+			     ALIGN);		\
+	  break;				\
+	case 0x301:				\
+	  const_var_section (DECL_MODE (DECL),	\
+			     ALIGN);		\
+	  break;				\
+	default:				\
+	  (*sec_functions[sec]) ();		\
+	  break;				\
+	}					\
     }						\
   while (0)
 
@@ -380,7 +551,7 @@ void FN ()					\
       STRIP_NAME_ENCODING (name, name);					\
       nlen = strlen (name);						\
 									\
-      prefix = prefixes[sec][DECL_ONE_ONLY(DECL)];			\
+      prefix = prefixes[sec & 0xff][DECL_ONE_ONLY(DECL)];		\
       plen = strlen (prefix);						\
 									\
       string = alloca (nlen + plen + 1);				\
@@ -399,8 +570,8 @@ void FN ()					\
    go into the const section.  */
 
 #undef  SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE, RTX) \
-   const_section()
+#define SELECT_RTX_SECTION(MODE, RTX, ALIGN) \
+   const_var_section((MODE), (ALIGN))
 
 /* Define the strings used for the special svr4 .type and .size directives.
    These strings generally do not vary from one system running svr4 to
--- gcc/config/arm/aof.h.jj	Sat Aug 18 22:10:36 2001
+++ gcc/config/arm/aof.h	Mon Sep 10 11:11:40 2001
@@ -55,7 +55,7 @@ Boston, MA 02111-1307, USA.  */
 char *aof_text_section ();
 #define TEXT_SECTION_ASM_OP aof_text_section ()
 
-#define SELECT_RTX_SECTION(MODE,RTX) text_section ();
+#define SELECT_RTX_SECTION(MODE,RTX,ALIGN) text_section ();
 
 char *aof_data_section ();
 #define DATA_SECTION_ASM_OP aof_data_section ()
--- gcc/config/arm/linux-elf.h.jj	Sat Aug 18 22:10:37 2001
+++ gcc/config/arm/linux-elf.h	Mon Sep 10 11:11:40 2001
@@ -139,7 +139,7 @@ const_section ()							\
    section for output of DECL.  DECL is either a `VAR_DECL' node
    or a constant of some sort.  RELOC indicates whether forming
    the initial value of DECL requires link-time relocations.  */
-#define SELECT_SECTION(DECL,RELOC)					\
+#define SELECT_SECTION(DECL,RELOC,ALIGN)				\
 {									\
   if (TREE_CODE (DECL) == STRING_CST)					\
     {									\
@@ -204,7 +204,7 @@ const_section ()							\
    of constant in RTL.  The argument MODE is redundant except
    in the case of a `const_int' rtx.  Currently, these always
    go into the const section.  */
-#define SELECT_RTX_SECTION(MODE,RTX) const_section ()
+#define SELECT_RTX_SECTION(MODE,RTX,ALIGN) const_section ()
 
 /* On svr4, we *do* have support for the .init and .fini sections, and we
    can put stuff in there to be executed before and after `main'.  We let
--- gcc/config/avr/avr.h.jj	Mon Sep  3 19:53:52 2001
+++ gcc/config/avr/avr.h	Mon Sep 10 11:11:40 2001
@@ -1890,7 +1890,7 @@ progmem_section (void)							      \
    If these items should be placed in the text section, this macro
    should not be defined.  */
 
-/* `SELECT_SECTION (EXP, RELOC)'
+/* `SELECT_SECTION (EXP, RELOC, ALIGN)'
    A C statement or statements to switch to the appropriate section
    for output of EXP.  You can assume that EXP is either a `VAR_DECL'
    node or a constant of some sort.  RELOC indicates whether the
@@ -1901,7 +1901,7 @@ progmem_section (void)							      \
    Do not define this macro if you put all read-only variables and
    constants in the read-only data section (usually the text section).  */
 
-/* `SELECT_RTX_SECTION (MODE, RTX)'
+/* `SELECT_RTX_SECTION (MODE, RTX, ALIGN)'
    A C statement or statements to switch to the appropriate section
    for output of RTX in mode MODE.  You can assume that RTX is some
    kind of constant in RTL.  The argument MODE is redundant except in
--- gcc/config/c4x/c4x.h.jj	Mon Sep  3 19:53:53 2001
+++ gcc/config/c4x/c4x.h	Mon Sep 10 11:11:40 2001
@@ -2030,7 +2030,7 @@ const_section ()							\
    or a constant of some sort.  RELOC indicates whether forming
    the initial value of DECL requires link-time relocations.  */
 
-#define SELECT_SECTION(DECL, RELOC)					\
+#define SELECT_SECTION(DECL, RELOC, ALIGN)				\
 {									\
   if (TREE_CODE (DECL) == STRING_CST)					\
     {									\
@@ -2075,7 +2075,7 @@ const_section ()							\
    in the case of a `const_int' rtx.  Currently, these always
    go into the const section.  */
 
-#define SELECT_RTX_SECTION(MODE, RTX) const_section()
+#define SELECT_RTX_SECTION(MODE, RTX, ALIGN) const_section()
 
 
 /* Overall Framework of an Assembler File.  */
--- gcc/config/d30v/d30v.h.jj	Mon Sep  3 19:53:53 2001
+++ gcc/config/d30v/d30v.h	Mon Sep 10 11:11:40 2001
@@ -3698,7 +3698,7 @@ extern const char *d30v_branch_cost_stri
    the read-only data section (usually the text section).
 
    Defined in svr4.h.  */
-/* #define SELECT_SECTION(EXP, RELOC) */
+/* #define SELECT_SECTION(EXP, RELOC, ALIGN) */
 
 /* A C statement or statements to switch to the appropriate section for output
    of RTX in mode MODE.  You can assume that RTX is some kind of constant in
@@ -3710,7 +3710,7 @@ extern const char *d30v_branch_cost_stri
    section.
 
    Defined in svr4.h.  */
-/* #define SELECT_RTX_SECTION(MODE, RTX) */
+/* #define SELECT_RTX_SECTION(MODE, RTX, ALIGN) */
 
 /* Define this macro if jump tables (for `tablejump' insns) should be output in
    the text section, along with the assembler instructions.  Otherwise, the
--- gcc/config/i386/dgux.h.jj	Thu May  3 20:07:30 2001
+++ gcc/config/i386/dgux.h	Mon Sep 10 11:11:40 2001
@@ -232,7 +232,7 @@ Boston, MA 02111-1307, USA.  */
 
 /* Must use data section for relocatable constants when pic.  */
 #undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE,RTX)            \
+#define SELECT_RTX_SECTION(MODE,RTX,ALIGN)      \
 {                                               \
   if (flag_pic && symbolic_operand (RTX, VOIDmode)) \
     data_section ();                            \
--- gcc/config/i386/osfrose.h.jj	Sun Jul 22 21:34:29 2001
+++ gcc/config/i386/osfrose.h	Mon Sep 10 11:11:40 2001
@@ -506,7 +506,7 @@ while (0)
    and select that section.  */
 
 #undef	SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE, RTX)					\
+#define SELECT_RTX_SECTION(MODE, RTX, ALIGN)				\
 do									\
   {									\
     if (MODE == Pmode && HALF_PIC_P () && HALF_PIC_ADDRESS_P (RTX))	\
@@ -517,7 +517,7 @@ do									\
 while (0)
 
 #undef	SELECT_SECTION
-#define SELECT_SECTION(DECL, RELOC)					\
+#define SELECT_SECTION(DECL, RELOC, ALIGN)				\
 {									\
   if (RELOC && HALF_PIC_P ())						\
     data_section ();							\
--- gcc/config/i386/sco5.h.jj	Sat Aug 18 22:10:41 2001
+++ gcc/config/i386/sco5.h	Mon Sep 10 11:11:40 2001
@@ -371,7 +371,7 @@ do {									\
 
 /* Must use data section for relocatable constants when pic.  */
 #undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE,RTX)					\
+#define SELECT_RTX_SECTION(MODE,RTX,ALIGN)				\
 {									\
   if (TARGET_ELF) {							\
     if (flag_pic && symbolic_operand (RTX, VOIDmode))			\
@@ -565,7 +565,7 @@ init_section ()								\
    : 0))
 
 #undef SELECT_SECTION
-#define SELECT_SECTION(DECL,RELOC)					\
+#define SELECT_SECTION(DECL,RELOC,ALIGN)				\
 {									\
   if (TARGET_ELF && flag_pic && RELOC)					\
      data_section ();							\
--- gcc/config/i386/svr3gas.h.jj	Sat Aug 18 22:10:41 2001
+++ gcc/config/i386/svr3gas.h	Mon Sep 10 11:39:30 2001
@@ -177,7 +177,7 @@ const_section ()							\
    or a constant of some sort.  RELOC indicates whether forming
    the initial value of DECL requires link-time relocations.  */
 
-#define SELECT_SECTION(DECL,RELOC)					\
+#define SELECT_SECTION(DECL,RELOC,ALIGN)				\
 {									\
   if (TREE_CODE (DECL) == STRING_CST)					\
     {									\
@@ -207,4 +207,4 @@ const_section ()							\
    in the case of a `const_int' rtx.  Currently, these always
    go into the const section.  */
 
-#define SELECT_RTX_SECTION(MODE,RTX) const_section()
+#define SELECT_RTX_SECTION(MODE,RTX,ALIGN) const_section()
--- gcc/config/ia64/sysv4.h.jj	Mon Sep  3 19:53:55 2001
+++ gcc/config/ia64/sysv4.h	Mon Sep 10 11:41:59 2001
@@ -138,12 +138,12 @@ do {									\
 /* We override svr4.h so that we can support the sdata section.  */
 
 #undef SELECT_SECTION
-#define SELECT_SECTION(DECL,RELOC)					\
+#define SELECT_SECTION(DECL,RELOC,ALIGN)				\
 {									\
   if (TREE_CODE (DECL) == STRING_CST)					\
     {									\
       if (! flag_writable_strings)					\
-	const_section ();						\
+	const_str_section ((DECL), (ALIGN));				\
       else								\
 	data_section ();						\
     }									\
@@ -152,13 +152,20 @@ do {									\
       if (XSTR (XEXP (DECL_RTL (DECL), 0), 0)[0]			\
 	  == SDATA_NAME_FLAG_CHAR)					\
         sdata_section ();						\
-      /* ??? We need the extra ! RELOC check, because the default is to \
+      /* ??? We need the extra RELOC check, because the default is to	\
 	 only check RELOC if flag_pic is set, and we don't set flag_pic \
 	 (yet?).  */							\
-      else if (DECL_READONLY_SECTION (DECL, RELOC) && ! (RELOC))	\
+      else if (!DECL_READONLY_SECTION (DECL, RELOC) || (RELOC))		\
+	data_section ();						\
+      else if (flag_merge_constants < 2)				\
+	/* C and C++ don't allow different variables to share		\
+	   the same location.  -fmerge-all-constants allows		\
+	   even that (at the expense of not conforming).  */		\
 	const_section ();						\
+      else if (TREE_CODE (DECL_INITIAL (DECL)) == STRING_CST)		\
+	const_str_section (DECL_INITIAL (DECL), (ALIGN));		\
       else								\
-	data_section ();						\
+	const_var_section (DECL_MODE (DECL), (ALIGN));			\
     }									\
   /* This could be a CONSTRUCTOR containing ADDR_EXPR of a VAR_DECL,	\
      in which case we can't put it in a shared library rodata.  */	\
@@ -172,7 +179,7 @@ do {									\
 
 extern unsigned int ia64_section_threshold;
 #undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE, RTX)					\
+#define SELECT_RTX_SECTION(MODE, RTX, ALIGN)				\
 {									\
   if (GET_MODE_SIZE (MODE) > 0						\
       && GET_MODE_SIZE (MODE) <= ia64_section_threshold)		\
@@ -180,17 +187,27 @@ extern unsigned int ia64_section_thresho
   else if (flag_pic && symbolic_operand ((RTX), (MODE)))		\
     data_section ();							\
   else									\
-    const_section ();							\
+    const_var_section ((MODE), (ALIGN));				\
 }
 
 #undef EXTRA_SECTIONS
+#ifdef HAVE_GAS_SHF_MERGE
+#define EXTRA_SECTIONS in_const, in_sdata, in_sbss,			\
+  in_const_cst1, in_const_cst2, in_const_cst4,				\
+  in_const_cst8, in_const_cst16,					\
+  in_const_str1 = 256, in_const_str2 = 256 + 32,			\
+  in_const_str4 = 256 + 2*32, in_const_str8 = 256 + 3*32
+#else
 #define EXTRA_SECTIONS in_const, in_sdata, in_sbss
+#endif
 
 #undef EXTRA_SECTION_FUNCTIONS
 #define EXTRA_SECTION_FUNCTIONS						\
   CONST_SECTION_FUNCTION						\
   SDATA_SECTION_FUNCTION						\
-  SBSS_SECTION_FUNCTION
+  SBSS_SECTION_FUNCTION							\
+  CONST_STR_SECTION_FUNCTION						\
+  CONST_VAR_SECTION_FUNCTION
 
 #define SDATA_SECTION_ASM_OP "\t.sdata"
 
--- gcc/config/ia64/aix.h.jj	Sat Jul 21 11:42:20 2001
+++ gcc/config/ia64/aix.h	Mon Sep 10 12:05:47 2001
@@ -150,7 +150,7 @@ do {							\
    the initial value of DECL requires link-time relocations.  */
 
 #undef SELECT_SECTION
-#define SELECT_SECTION(DECL,RELOC)					\
+#define SELECT_SECTION(DECL,RELOC,ALIGN)				\
 {									\
   if (TREE_CODE (DECL) == STRING_CST)					\
     {									\
@@ -184,7 +184,7 @@ do {							\
 
 extern unsigned int ia64_section_threshold;
 #undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE, RTX)					\
+#define SELECT_RTX_SECTION(MODE, RTX, ALIGN)				\
 {									\
   if (GET_MODE_SIZE (MODE) > 0						\
       && GET_MODE_SIZE (MODE) <= ia64_section_threshold)		\
--- gcc/config/m32r/m32r.h.jj	Mon Sep  3 19:53:55 2001
+++ gcc/config/m32r/m32r.h	Mon Sep 10 11:11:40 2001
@@ -1534,7 +1534,8 @@ sbss_section ()								\
    or a constant of some sort.  RELOC indicates whether the initial value
    of EXP requires link-time relocations.  */
 #undef  SELECT_SECTION
-#define SELECT_SECTION(EXP, RELOC) m32r_select_section ((EXP), (RELOC))
+#define SELECT_SECTION(EXP, RELOC, ALIGN) \
+  m32r_select_section ((EXP), (RELOC))
 
 /* A C statement or statements to switch to the appropriate section for
    output of RTX in mode MODE.  You can assume that RTX
--- gcc/config/m68k/m68k.h.jj	Sat Aug 18 22:10:42 2001
+++ gcc/config/m68k/m68k.h	Mon Sep 10 11:11:40 2001
@@ -359,7 +359,7 @@ extern int target_flags;
 /* This is how to align an instruction for optimal branching. */
 #define LABEL_ALIGN_AFTER_BARRIER(LABEL) (m68k_align_jumps)
 
-#define SELECT_RTX_SECTION(MODE, X)					\
+#define SELECT_RTX_SECTION(MODE, X, ALIGN)				\
 {									\
   if (!flag_pic)							\
     readonly_data_section();						\
--- gcc/config/m88k/dgux.h.jj	Thu May  3 20:07:32 2001
+++ gcc/config/m88k/dgux.h	Mon Sep 10 11:11:40 2001
@@ -294,7 +294,7 @@ func_ptr __DTOR_END__[1] = { (func_ptr) 
 
 /* Must use data section for relocatable constants when pic.  */
 #undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE,RTX)            \
+#define SELECT_RTX_SECTION(MODE,RTX,ALIGN)      \
 {                                               \
   if (flag_pic && symbolic_operand (RTX))       \
     data_section ();                            \
--- gcc/config/m88k/m88k.h.jj	Mon Sep  3 19:53:55 2001
+++ gcc/config/m88k/m88k.h	Mon Sep 10 11:11:40 2001
@@ -2480,7 +2480,7 @@ sdata_section ()							\
 
    For strings, the section is selected before the segment info is encoded.  */
 #undef	SELECT_SECTION
-#define SELECT_SECTION(DECL,RELOC)					\
+#define SELECT_SECTION(DECL,RELOC,ALIGN)				\
 {									\
   if (TREE_CODE (DECL) == STRING_CST)					\
     {									\
--- gcc/config/mcore/mcore-pe.h.jj	Sat Aug 18 22:10:43 2001
+++ gcc/config/mcore/mcore-pe.h	Mon Sep 10 11:11:40 2001
@@ -81,7 +81,7 @@ rdata_section ()						\
    or a constant of some sort.  RELOC indicates whether forming
    the initial value of DECL requires link-time relocations.  */
 #undef  SELECT_SECTION
-#define SELECT_SECTION(DECL, RELOC)					\
+#define SELECT_SECTION(DECL, RELOC, ALIGN)				\
 {									\
   if (TREE_CODE (DECL) == STRING_CST)					\
     {									\
@@ -111,7 +111,7 @@ rdata_section ()						\
    in the case of a `const_int' rtx.  Currently, these always
    go into the const section.  */
 #undef  SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE, RTX) rdata_section ()
+#define SELECT_RTX_SECTION(MODE, RTX, ALIGN) rdata_section ()
 
 #define MCORE_EXPORT_NAME(STREAM, NAME)			\
   do							\
--- gcc/config/mips/mips.h.jj	Mon Sep  3 19:53:55 2001
+++ gcc/config/mips/mips.h	Mon Sep 10 11:11:40 2001
@@ -4462,10 +4462,12 @@ rdata_section ()							\
    and select that section.  */
 
 #undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE,RTX)	mips_select_rtx_section (MODE, RTX)
+#define SELECT_RTX_SECTION(MODE, RTX, ALIGN) \
+  mips_select_rtx_section (MODE, RTX)
 
 #undef SELECT_SECTION
-#define SELECT_SECTION(DECL, RELOC)	mips_select_section (DECL, RELOC)
+#define SELECT_SECTION(DECL, RELOC, ALIGN) \
+  mips_select_section (DECL, RELOC)
 
 
 /* Store in OUTPUT a string (made with alloca) containing
--- gcc/config/pa/pa.h.jj	Mon Sep 10 10:34:52 2001
+++ gcc/config/pa/pa.h	Mon Sep 10 11:11:40 2001
@@ -1403,7 +1403,7 @@ do { 									\
    library.  Since we can't know at compile time if a symbol will be
    satisfied by a shared library or main program we put any symbolic
    constant into the normal data section.  */
-#define SELECT_RTX_SECTION(MODE,RTX)	\
+#define SELECT_RTX_SECTION(MODE,RTX,ALIGN)	\
   if (symbolic_operand (RTX, MODE))	\
     data_section ();			\
   else					\
@@ -1413,7 +1413,7 @@ do { 									\
    in the read-only data section to a symbol defined in a shared
    library.  Therefore, expressions that might require a reloc can
    not be placed in the read-only data section.  */
-#define SELECT_SECTION(EXP,RELOC) \
+#define SELECT_SECTION(EXP,RELOC,ALIGN) \
   if (TREE_CODE (EXP) == VAR_DECL \
       && TREE_READONLY (EXP) \
       && !TREE_THIS_VOLATILE (EXP) \
--- gcc/config/pa/pa-linux.h.jj	Fri Jun  8 11:37:16 2001
+++ gcc/config/pa/pa-linux.h	Mon Sep 10 12:06:32 2001
@@ -55,7 +55,7 @@ Boston, MA 02111-1307, USA.  */
 
 /* Put plabels into the data section so we can relocate them.  */
 #undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE,RTX)	\
+#define SELECT_RTX_SECTION(MODE,RTX,ALIGN)	\
   if (flag_pic && function_label_operand (RTX, MODE))	\
     data_section ();					\
   else							\
--- gcc/config/romp/romp.h.jj	Sun Jul 22 21:34:36 2001
+++ gcc/config/romp/romp.h	Mon Sep 10 11:11:40 2001
@@ -717,7 +717,7 @@ struct rt_cargs {int gregs, fregs; };
 
    On ROMP, all constants are in the data area.  */
 
-#define SELECT_RTX_SECTION(MODE, X)	data_section ()
+#define SELECT_RTX_SECTION(MODE, X, ALIGN)	data_section ()
 
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */
--- gcc/config/rs6000/xcoff.h.jj	Mon Aug 13 23:14:01 2001
+++ gcc/config/rs6000/xcoff.h	Mon Sep 10 12:03:19 2001
@@ -144,7 +144,7 @@ toc_section ()						\
    On the RS/6000, we have a special section for all variables except those
    that are static.  */
 
-#define SELECT_SECTION(EXP,RELOC)			\
+#define SELECT_SECTION(EXP,RELOC,ALIGN)			\
 {							\
   if ((TREE_CODE (EXP) == STRING_CST			\
        && ! flag_writable_strings)			\
@@ -199,7 +199,7 @@ toc_section ()						\
    However, if this is being placed in the TOC it must be output as a
    toc entry.  */
 
-#define SELECT_RTX_SECTION(MODE, X)			\
+#define SELECT_RTX_SECTION(MODE, X, ALIGN)		\
 { if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X, MODE))	\
     toc_section ();					\
   else							\
--- gcc/config/rs6000/sysv4.h.jj	Sat Aug 18 22:20:38 2001
+++ gcc/config/rs6000/sysv4.h	Mon Sep 10 11:11:40 2001
@@ -566,7 +566,7 @@ fini_section ()								\
 
 /* Override elfos.h definition.  */
 #undef	SELECT_RTX_SECTION
-#define	SELECT_RTX_SECTION(MODE, X) rs6000_select_rtx_section (MODE, X)
+#define	SELECT_RTX_SECTION(MODE, X, ALIGN) rs6000_select_rtx_section (MODE, X)
 
 /* A C statement or statements to switch to the appropriate
    section for output of DECL.  DECL is either a `VAR_DECL' node
@@ -575,7 +575,7 @@ fini_section ()								\
 
 /* Override elfos.h definition.  */
 #undef	SELECT_SECTION
-#define	SELECT_SECTION(DECL, RELOC) rs6000_select_section (DECL, RELOC)
+#define	SELECT_SECTION(DECL, RELOC, ALIGN) 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).
--- gcc/config/sparc/sparc.h.jj	Mon Sep  3 19:53:56 2001
+++ gcc/config/sparc/sparc.h	Mon Sep 10 11:11:40 2001
@@ -912,7 +912,7 @@ if (TARGET_ARCH64				\
 #endif
 
 /* This is defined differently for v9 in a cover file.  */
-#define SELECT_SECTION(T,RELOC)						\
+#define SELECT_SECTION(T,RELOC,ALIGN)					\
 {									\
   if (TREE_CODE (T) == VAR_DECL)					\
     {									\
@@ -945,7 +945,7 @@ if (TARGET_ARCH64				\
 /* Use text section for a constant
    unless we need more alignment than that offers.  */
 /* This is defined differently for v9 in a cover file.  */
-#define SELECT_RTX_SECTION(MODE, X)		\
+#define SELECT_RTX_SECTION(MODE, X, ALIGN)	\
 {						\
   if (GET_MODE_BITSIZE (MODE) <= MAX_TEXT_ALIGN \
       && ! (flag_pic && (symbolic_operand ((X), (MODE)) || SUNOS4_SHARED_LIBRARIES)))  \
--- gcc/config/sparc/sysv4.h.jj	Sat Aug 18 22:10:46 2001
+++ gcc/config/sparc/sysv4.h	Mon Sep 10 11:11:40 2001
@@ -79,7 +79,7 @@ Boston, MA 02111-1307, USA.  */
 
 /* Must use data section for relocatable constants when pic.  */
 #undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE,RTX)		\
+#define SELECT_RTX_SECTION(MODE,RTX,ALIGN)	\
 {						\
   if (flag_pic && symbolic_operand ((RTX), (MODE))) \
     data_section ();				\
--- gcc/config/v850/v850.h.jj	Mon Sep  3 19:53:56 2001
+++ gcc/config/v850/v850.h	Mon Sep 10 11:11:40 2001
@@ -1164,7 +1164,7 @@ zbss_section ()								\
    Do not define this macro if you put all read-only variables and
    constants in the read-only data section (usually the text section).  */
 #undef  SELECT_SECTION
-#define SELECT_SECTION(EXP, RELOC)					\
+#define SELECT_SECTION(EXP, RELOC, ALIGN)				\
 do {									\
   if (TREE_CODE (EXP) == VAR_DECL)					\
     {									\
@@ -1227,7 +1227,7 @@ do {									\
 
    Do not define this macro if you put all constants in the read-only
    data section.  */
-/* #define SELECT_RTX_SECTION(MODE, RTX) */
+/* #define SELECT_RTX_SECTION(MODE, RTX, ALIGN) */
 
 /* Output at beginning/end of assembler file.  */
 #undef ASM_FILE_START
--- gcc/config/vax/vms.h.jj	Sat Aug 18 22:10:47 2001
+++ gcc/config/vax/vms.h	Mon Sep 10 11:11:40 2001
@@ -218,7 +218,7 @@ const_section ()					\
    Since this macro is used in a number of places, we must also be able
    to decide where to place string constants.  */
 
-#define SELECT_SECTION(T,RELOC)						\
+#define SELECT_SECTION(T,RELOC,ALIGN)					\
 {									\
   if (TREE_CODE (T) == VAR_DECL)					\
     {									\
--- gcc/config/stormy16/stormy16.h.jj	Sat Sep  1 20:31:46 2001
+++ gcc/config/stormy16/stormy16.h	Mon Sep 10 12:03:55 2001
@@ -3470,7 +3470,7 @@ do {							\
    the read-only data section (usually the text section).
 
    Defined in svr4.h.  */
-/* #define SELECT_SECTION(EXP, RELOC) */
+/* #define SELECT_SECTION(EXP, RELOC, ALIGN) */
 
 /* A C statement or statements to switch to the appropriate section for output
    of RTX in mode MODE.  You can assume that RTX is some kind of constant in
@@ -3482,7 +3482,7 @@ do {							\
    section.
 
    Defined in svr4.h.  */
-/* #define SELECT_RTX_SECTION(MODE, RTX) */
+/* #define SELECT_RTX_SECTION(MODE, RTX, ALIGN) */
 
 /* Define this macro if jump tables (for `tablejump' insns) should be output in
    the text section, along with the assembler instructions.  Otherwise, the
--- gcc/config/darwin.h.jj	Mon Sep 10 10:34:48 2001
+++ gcc/config/darwin.h	Mon Sep 10 12:02:03 2001
@@ -509,7 +509,7 @@ void alias_section (name, alias)			\
 #define READONLY_DATA_SECTION const_section
 
 #undef	SELECT_SECTION
-#define SELECT_SECTION(exp,reloc)				\
+#define SELECT_SECTION(exp,reloc,align)				\
   do								\
     {								\
       if (TREE_CODE (exp) == STRING_CST)			\
@@ -633,7 +633,7 @@ void alias_section (name, alias)			\
   while (0)
 
 #undef	SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(mode, rtx)					\
+#define SELECT_RTX_SECTION(mode, rtx, align)				\
   do									\
     {									\
       if (GET_MODE_SIZE (mode) == 8)					\
--- gcc/config/nextstep.h.jj	Sat Aug 18 22:10:35 2001
+++ gcc/config/nextstep.h	Mon Sep 10 11:11:40 2001
@@ -445,7 +445,7 @@ objc_section_init ()				\
 #define READONLY_DATA_SECTION const_section
 
 #undef	SELECT_SECTION
-#define SELECT_SECTION(exp,reloc)				\
+#define SELECT_SECTION(exp,reloc,align)				\
   do								\
     {								\
       if (TREE_CODE (exp) == STRING_CST)			\
@@ -563,7 +563,7 @@ objc_section_init ()				\
   while (0)
 
 #undef	SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(mode, rtx)					\
+#define SELECT_RTX_SECTION(mode, rtx, align)				\
   do									\
     {									\
       if (GET_MODE_SIZE(mode) == 8)					\
--- gcc/config/svr3.h.jj	Sat Aug 18 22:10:35 2001
+++ gcc/config/svr3.h	Mon Sep 10 11:11:40 2001
@@ -301,7 +301,7 @@ const_section ()							\
    or a constant of some sort.  RELOC indicates whether forming
    the initial value of DECL requires link-time relocations.  */
 
-#define SELECT_SECTION(DECL,RELOC)					\
+#define SELECT_SECTION(DECL,RELOC,ALIGN)				\
 {									\
   if (TREE_CODE (DECL) == STRING_CST)					\
     {									\
@@ -331,4 +331,4 @@ const_section ()							\
    in the case of a `const_int' rtx.  Currently, these always
    go into the const section.  */
 
-#define SELECT_RTX_SECTION(MODE,RTX) const_section()
+#define SELECT_RTX_SECTION(MODE,RTX,ALIGN) const_section()
--- gcc/f/com.c.jj	Sun Jul 22 21:34:54 2001
+++ gcc/f/com.c	Mon Sep 10 11:11:41 2001
@@ -14657,6 +14657,7 @@ ffe_init_options ()
   flag_move_all_movables = 1;
   flag_reduce_all_givs = 1;
   flag_argument_noalias = 2;
+  flag_merge_constants = 2;
   flag_errno_math = 0;
   flag_complex_divide_method = 1;
 }

	Jakub



More information about the Gcc-patches mailing list