aboutsummaryrefslogtreecommitdiff
path: root/gcc/varasm.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2001-09-11 18:50:05 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2001-09-11 18:50:05 +0200
commit201556f0e005802b8ebb206a193a6feb55a555af (patch)
tree1e64917dd6eadf802b7c67e6f7384cc9fc03f1ae /gcc/varasm.c
parentd21b1cb8741f7dfbeab6a456d67b322312933a8c (diff)
downloadgcc-201556f0e005802b8ebb206a193a6feb55a555af.zip
gcc-201556f0e005802b8ebb206a193a6feb55a555af.tar.gz
gcc-201556f0e005802b8ebb206a193a6feb55a555af.tar.bz2
configure.in: Check whether assembler supports section merging.
* 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. (mergeable_string_section): New. (mergeable_constant_section): New. (default_elf_asm_named_section): Output SECTION_MERGE and SECTION_STRINGS flags plus SECTION_ENTSIZE entity size. * output.h (mergeable_string_section): New. (mergeable_constant_section): New. (SECTION_MERGE, SECTION_STRINGS, SECTION_ENTSIZE): Define. * 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 (ASM_SECTION_START_OP, ASM_OUTPUT_SECTION_START): Define if assembler has working .subsection -1 support. (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 (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. (ASM_SECTION_START_OP, ASM_OUTPUT_SECTION_START): Define if assembler has working .subsection -1 support. * 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. * config/arm/arm.c (arm_elf_asm_named_section): Output SECTION_MERGE and SECTION_STRINGS flags plus SECTION_ENTSIZE entity size. * config/sparc/sparc.c (sparc_elf_asm_named_section): Use default_elf_asm_named_section for SHF_MERGE sections. * com.c (ffe_init_options): Default to -fmerge-all-constants if optimizing. From-SVN: r45548
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r--gcc/varasm.c137
1 files changed, 125 insertions, 12 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c
index a95994c..defa0c6 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -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 ();
@@ -587,6 +587,111 @@ exception_section ()
readonly_data_section ();
#endif
}
+
+/* Tell assembler to switch to the section for string merging. */
+
+void
+mergeable_string_section (decl, align, flags)
+ tree decl ATTRIBUTE_UNUSED;
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+ unsigned int flags ATTRIBUTE_UNUSED;
+{
+#ifdef HAVE_GAS_SHF_MERGE
+ if (flag_merge_constants
+ && TREE_CODE (decl) == STRING_CST
+ && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
+ && align <= 256
+ && TREE_STRING_LENGTH (decl) >= int_size_in_bytes (TREE_TYPE (decl)))
+ {
+ enum machine_mode mode;
+ unsigned int modesize;
+ const char *str;
+ int i, j, len, unit;
+ char name[30];
+
+ mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (decl)));
+ modesize = GET_MODE_BITSIZE (mode);
+ if (modesize >= 8 && modesize <= 256
+ && (modesize & (modesize - 1)) == 0)
+ {
+ if (align < modesize)
+ align = modesize;
+
+ 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)
+ {
+ sprintf (name, ".rodata.str%d.%d", modesize / 8,
+ (int) (align / 8));
+ flags |= (modesize / 8) | SECTION_MERGE | SECTION_STRINGS;
+ if (!i && modesize < 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. */
+#ifdef ASM_OUTPUT_SECTION_START
+ named_section_flags (name, flags);
+ ASM_OUTPUT_SECTION_START (asm_out_file);
+#else
+ readonly_data_section ();
+#endif
+ return;
+ }
+
+ named_section_flags (name, flags);
+ return;
+ }
+ }
+ }
+#endif
+ readonly_data_section ();
+}
+
+/* Tell assembler to switch to the section for constant merging. */
+
+void
+mergeable_constant_section (mode, align, flags)
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+ unsigned int flags ATTRIBUTE_UNUSED;
+{
+#ifdef HAVE_GAS_SHF_MERGE
+ unsigned int modesize = GET_MODE_BITSIZE (mode);
+
+ if (flag_merge_constants
+ && mode != VOIDmode
+ && mode != BLKmode
+ && modesize <= align
+ && align >= 8
+ && align <= 256
+ && (align & (align - 1)) == 0)
+ {
+ char name[24];
+
+ sprintf (name, ".rodata.cst%d", (int) (align / 8));
+ flags |= (align / 8) | SECTION_MERGE;
+ named_section_flags (name, flags);
+ return;
+ }
+#endif
+ readonly_data_section ();
+}
/* Given NAME, a putative register name, discard any customary prefixes. */
@@ -3305,13 +3410,19 @@ output_constant_def_contents (exp, reloc, labelno)
{
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 +3432,6 @@ output_constant_def_contents (exp, reloc, labelno)
#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 +3982,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
@@ -5060,7 +5165,7 @@ default_elf_asm_named_section (name, flags)
const char *name;
unsigned int flags;
{
- char flagchars[8], *f = flagchars;
+ char flagchars[10], *f = flagchars;
const char *type;
if (!(flags & SECTION_DEBUG))
@@ -5071,6 +5176,10 @@ default_elf_asm_named_section (name, flags)
*f++ = 'x';
if (flags & SECTION_SMALL)
*f++ = 's';
+ if (flags & SECTION_MERGE)
+ *f++ = 'M';
+ if (flags & SECTION_STRINGS)
+ *f++ = 'S';
*f = '\0';
if (flags & SECTION_BSS)
@@ -5078,8 +5187,12 @@ default_elf_asm_named_section (name, flags)
else
type = "progbits";
- fprintf (asm_out_file, "\t.section\t%s,\"%s\",@%s\n",
- name, flagchars, type);
+ if (flags & SECTION_ENTSIZE)
+ fprintf (asm_out_file, "\t.section\t%s,\"%s\",@%s,%d\n",
+ name, flagchars, type, flags & SECTION_ENTSIZE);
+ else
+ fprintf (asm_out_file, "\t.section\t%s,\"%s\",@%s\n",
+ name, flagchars, type);
}
void