diff options
author | Jakub Jelinek <jakub@redhat.com> | 2001-09-11 18:50:05 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2001-09-11 18:50:05 +0200 |
commit | 201556f0e005802b8ebb206a193a6feb55a555af (patch) | |
tree | 1e64917dd6eadf802b7c67e6f7384cc9fc03f1ae /gcc/varasm.c | |
parent | d21b1cb8741f7dfbeab6a456d67b322312933a8c (diff) | |
download | gcc-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.c | 137 |
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 |