From: Mark Mitchell Date: Wed, 15 Sep 2004 17:03:22 +0000 (+0000) Subject: configure.ac: Check for COMDAT support. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c18a5b6cadf88275078d4b72249c8174cf079041;p=gcc.git configure.ac: Check for COMDAT support. * configure.ac: Check for COMDAT support. Robustify check for SHF_MERGE support. * configure: Regenerated. * config.in: Likewise. * langhooks-def.h (lhd_comdat_group): New function. (LANG_HOOKS_COMDAT_GROUP): New macro. (LANG_HOOKS_DECLS): Use it. * langhooks.c (lhd_comdat_group): Define. * langhooks.h (lang_hooks_for_decls): Add comdat_group. * output.h (named_section_flags): Make it a macro. (named_section_real): New function. (default_no_named_section): Add decl parameter. (default_elf_asm_named_section): Likewise. (default_coff_asm_named_section): Likewise. (default_pe_asm_named_section): Likewise. * target.h (gcc_target): Adjust type of named_section. * varasm.c (named_section_flags): Rename to named_section_real. Add decl parameter. (default_no_named_section): Add decl parameter. (default_elf_asm_named_section): Use COMDAT, if available. Deal with the case that ASM_COMMENT_START is "@". (default_coff_asm_named_section): Add decl parameter. (default_pe_asm_named_section): Likewise. * config/alpha/alpha.c (vms_asm_named_section): Add decl parameter. (unicosmk_asm_named_section): Likewise. * config/arm/arm.c (arm_elf_asm_named_section): Remove. * config/arm/elf.h (TARGET_ASM_NAMED_SECTION): Likewise. * config/c4x/c4x.c (c4x_asm_named_section): Add decl parameter. * config/cris/cris-protos.h (cris_target_asm_named_section): Likewise. * config/cris/cris.c (cris_target_asm_named_section): Likewise. * config/h8300/h8300.c (h8300_asm_named_section): Likewise. * config/i386/i386-protos.h (i386_pe_asm_named_section): Likewise. * config/i386/winnt.c (i386_pe_asm_named_section): Likewise. * config/m68k/m68k.c (m68k_coff_asm_named_section): Likewise. * config/mcore/mcore.c (mcore_asm_named_section): Likewise. * config/rs6000/rs6000.c (rs6000_xcoff_asm_named_section): Likewise. * config/sparc/sparc.c (sparce_elf_asm_named_section): Likewise. * cp-objcp-common.h (LANG_HOOKS_COMDAT_GROUP): Define. * cp-tree.h (cxx_comdat_group): Declare. * decl.c (cxx_comdat_group): New function. From-SVN: r87557 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c7210971c2e..e3505b1c2ab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,54 @@ +2004-09-15 Mark Mitchell + + * configure.ac: Check for COMDAT support. Robustify check for + SHF_MERGE support. + * configure: Regenerated. + * config.in: Likewise. + * langhooks-def.h (lhd_comdat_group): New function. + (LANG_HOOKS_COMDAT_GROUP): New macro. + (LANG_HOOKS_DECLS): Use it. + * langhooks.c (lhd_comdat_group): Define. + * langhooks.h (lang_hooks_for_decls): Add comdat_group. + * output.h (named_section_flags): Make it a macro. + (named_section_real): New function. + (default_no_named_section): Add decl parameter. + (default_elf_asm_named_section): Likewise. + (default_coff_asm_named_section): Likewise. + (default_pe_asm_named_section): Likewise. + * target.h (gcc_target): Adjust type of named_section. + * varasm.c (named_section_flags): Rename to named_section_real. + Add decl parameter. + (default_no_named_section): Add decl parameter. + (default_elf_asm_named_section): Use COMDAT, if available. Deal + with the case that ASM_COMMENT_START is "@". + (default_coff_asm_named_section): Add decl parameter. + (default_pe_asm_named_section): Likewise. + * config/alpha/alpha.c (vms_asm_named_section): Add decl + parameter. + (unicosmk_asm_named_section): Likewise. + * config/arm/arm.c (arm_elf_asm_named_section): Remove. + * config/arm/elf.h (TARGET_ASM_NAMED_SECTION): Likewise. + * config/c4x/c4x.c (c4x_asm_named_section): Add decl parameter. + * config/cris/cris-protos.h (cris_target_asm_named_section): + Likewise. + * config/cris/cris.c (cris_target_asm_named_section): + Likewise. + * config/darwin/darwin-protos.h (darwin_asm_named_section): + Likewise. + * config/darwin/darwin.c (darwin_asm_named_section): Likewise. + * config/h8300/h8300.c (h8300_asm_named_section): Likewise. + * config/i386/i386-protos.h (i386_pe_asm_named_section): + Likewise. + * config/i386/winnt.c (i386_pe_asm_named_section): Likewise. + * config/m68k/m68k.c (m68k_coff_asm_named_section): Likewise. + * config/mcore/mcore.c (mcore_asm_named_section): Likewise. + * config/rs6000/rs6000.c (rs6000_xcoff_asm_named_section): + Likewise. + * config/sparc/sparc.c (sparce_elf_asm_named_section): Likewise. + * cp/cp-lang.h (LANG_HOOKS_COMDAT_GROUP): Define. + * cp/cp-tree.h (cxx_comdat_group): Declare. + * cp/decl.c (cxx_comdat_group): New function. + 2004-09-15 Jan Hubicka * tree-ssa.c (verify_flow_sensitive_alias_info): Do not walk dead nodes. diff --git a/gcc/config.in b/gcc/config.in index 64384e5c008..1755c8a3721 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -284,6 +284,9 @@ /* Define if your assembler supports .balign and .p2align. */ #undef HAVE_GAS_BALIGN_AND_P2ALIGN +/* Define 0/1 if your assembler supports COMDAT group. */ +#undef HAVE_GAS_COMDAT_GROUP + /* Define if your assembler uses the new HImode fild and fist notation. */ #undef HAVE_GAS_FILDS_FISTS diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 54d78f6c143..21aa3822797 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -8455,7 +8455,8 @@ vms_section_type_flags (tree decl, const char *name, int reloc) the section; 0 if the default should be used. */ static void -vms_asm_named_section (const char *name, unsigned int flags) +vms_asm_named_section (const char *name, unsigned int flags, + tree decl ATTRIBUTE_UNUSED) { fputc ('\n', asm_out_file); fprintf (asm_out_file, ".section\t%s", name); @@ -8679,7 +8680,8 @@ unicosmk_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED) the section; 0 if the default should be used. */ static void -unicosmk_asm_named_section (const char *name, unsigned int flags) +unicosmk_asm_named_section (const char *name, unsigned int flags, + tree decl ATTRIBUTE_UNUSED) { const char *kind; diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index e7ed0750519..ee334dff1b2 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -145,9 +145,6 @@ static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int); static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int); static void emit_constant_insn (rtx cond, rtx pattern); -#ifdef OBJECT_FORMAT_ELF -static void arm_elf_asm_named_section (const char *, unsigned int); -#endif #ifndef ARM_PE static void arm_encode_section_info (tree, rtx, int); #endif @@ -13771,62 +13768,6 @@ aof_file_end (void) } #endif /* AOF_ASSEMBLER */ -#ifdef OBJECT_FORMAT_ELF -/* Switch to an arbitrary section NAME with attributes as specified - by FLAGS. ALIGN specifies any known alignment requirements for - the section; 0 if the default should be used. - - Differs from the default elf version only in the prefix character - used before the section type. */ - -static void -arm_elf_asm_named_section (const char *name, unsigned int flags) -{ - char flagchars[10], *f = flagchars; - - if (! named_section_first_declaration (name)) - { - fprintf (asm_out_file, "\t.section\t%s\n", name); - return; - } - - if (!(flags & SECTION_DEBUG)) - *f++ = 'a'; - if (flags & SECTION_WRITE) - *f++ = 'w'; - if (flags & SECTION_CODE) - *f++ = 'x'; - if (flags & SECTION_SMALL) - *f++ = 's'; - if (flags & SECTION_MERGE) - *f++ = 'M'; - if (flags & SECTION_STRINGS) - *f++ = 'S'; - if (flags & SECTION_TLS) - *f++ = 'T'; - *f = '\0'; - - fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars); - - if (!(flags & SECTION_NOTYPE)) - { - const char *type; - - if (flags & SECTION_BSS) - type = "nobits"; - else - type = "progbits"; - - fprintf (asm_out_file, ",%%%s", type); - - if (flags & SECTION_ENTSIZE) - fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE); - } - - putc ('\n', asm_out_file); -} -#endif - #ifndef ARM_PE /* Symbols in the text segment can be accessed without indirecting via the constant pool; it may take an extra binary operation, but this is still diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h index dae8acdfdf2..12759566ac4 100644 --- a/gcc/config/arm/elf.h +++ b/gcc/config/arm/elf.h @@ -119,9 +119,6 @@ #define TARGET_ASM_FILE_START_APP_OFF true #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true -#undef TARGET_ASM_NAMED_SECTION -#define TARGET_ASM_NAMED_SECTION arm_elf_asm_named_section - /* For PIC code we need to explicitly specify (PLT) and (GOT) relocs. */ #define NEED_PLT_RELOC flag_pic diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c index 5437568f07d..2d6e66006eb 100644 --- a/gcc/config/c4x/c4x.c +++ b/gcc/config/c4x/c4x.c @@ -195,7 +195,7 @@ static int c4x_label_ref_used_p (rtx, rtx); static tree c4x_handle_fntype_attribute (tree *, tree, tree, int, bool *); const struct attribute_spec c4x_attribute_table[]; static void c4x_insert_attributes (tree, tree *); -static void c4x_asm_named_section (const char *, unsigned int); +static void c4x_asm_named_section (const char *, unsigned int, tree); static int c4x_adjust_cost (rtx, rtx, rtx, int); static void c4x_globalize_label (FILE *, const char *); static bool c4x_rtx_costs (rtx, int, int, int *); @@ -4924,7 +4924,8 @@ c4x_init_libfuncs (void) } static void -c4x_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED) +c4x_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED, + tree decl ATTRIBUTE_UNUSED) { fprintf (asm_out_file, "\t.sect\t\"%s\"\n", name); } diff --git a/gcc/config/cris/cris-protos.h b/gcc/config/cris/cris-protos.h index 15e91df8a59..f085e5d741b 100644 --- a/gcc/config/cris/cris-protos.h +++ b/gcc/config/cris/cris-protos.h @@ -44,8 +44,8 @@ extern int cris_got_symbol (rtx); extern int cris_symbol (rtx); extern void cris_output_addr_const (FILE *, rtx); extern int cris_cfun_uses_pic_table (void); -extern void cris_target_asm_named_section (const char *, unsigned int); #endif /* RTX_CODE */ +extern void cris_target_asm_named_section (const char *, unsigned int, tree); extern int cris_return_address_on_stack (void); diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index 468859f9f42..2021c711dca 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -2450,12 +2450,13 @@ cris_reg_overlap_mentioned_p (rtx x, rtx in) We just dispatch to the functions for ELF and a.out. */ void -cris_target_asm_named_section (const char *name, unsigned int flags) +cris_target_asm_named_section (const char *name, unsigned int flags, + tree decl) { if (! TARGET_ELF) - default_no_named_section (name, flags); + default_no_named_section (name, flags, decl); else - default_elf_asm_named_section (name, flags); + default_elf_asm_named_section (name, flags, decl); } /* The LEGITIMATE_PIC_OPERAND_P worker. */ diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h index a5ae08e2499..402311c6bb1 100644 --- a/gcc/config/darwin-protos.h +++ b/gcc/config/darwin-protos.h @@ -69,7 +69,7 @@ extern void machopic_select_rtx_section (enum machine_mode, rtx, unsigned HOST_WIDE_INT); extern void darwin_unique_section (tree decl, int reloc); -extern void darwin_asm_named_section (const char *, unsigned int); +extern void darwin_asm_named_section (const char *, unsigned int, tree); extern unsigned int darwin_section_type_flags (tree, const char *, int); extern void darwin_non_lazy_pcrel (FILE *, rtx); diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index 6bab55445bc..249ebab247b 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -1187,7 +1187,9 @@ darwin_globalize_label (FILE *stream, const char *name) } void -darwin_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED) +darwin_asm_named_section (const char *name, + unsigned int flags ATTRIBUTE_UNUSED, + tree decl ATTRIBUTE_UNUSED) { fprintf (asm_out_file, ".section %s\n", name); } diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index 6cec395483c..564eecdfca2 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -114,7 +114,7 @@ static tree h8300_handle_fndecl_attribute (tree *, tree, tree, int, bool *); static tree h8300_handle_eightbit_data_attribute (tree *, tree, tree, int, bool *); static tree h8300_handle_tiny_data_attribute (tree *, tree, tree, int, bool *); #ifndef OBJECT_FORMAT_ELF -static void h8300_asm_named_section (const char *, unsigned int); +static void h8300_asm_named_section (const char *, unsigned int, tree); #endif static int h8300_and_costs (rtx); static int h8300_shift_costs (rtx); @@ -5889,7 +5889,8 @@ h8300_reorg (void) #ifndef OBJECT_FORMAT_ELF static void -h8300_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED) +h8300_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED, + tree decl) { /* ??? Perhaps we should be using default_coff_asm_named_section. */ fprintf (asm_out_file, "\t.section %s\n", name); diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 1c87da6385d..d663b0938a3 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -206,7 +206,7 @@ extern int ix86_constant_alignment (tree, int); extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *); extern unsigned int i386_pe_section_type_flags (tree, const char *, int); -extern void i386_pe_asm_named_section (const char *, unsigned int); +extern void i386_pe_asm_named_section (const char *, unsigned int, tree); extern int x86_field_alignment (tree, int); #endif diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index 7e32ca94257..676a34af429 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -622,7 +622,8 @@ i386_pe_section_type_flags (tree decl, const char *name, int reloc) } void -i386_pe_asm_named_section (const char *name, unsigned int flags) +i386_pe_asm_named_section (const char *name, unsigned int flags, + tree decl ATTRIBUTE_UNUSED) { char flagchars[8], *f = flagchars; diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index dd469c3a7df..d85c7c60c09 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -108,7 +108,7 @@ static const char *singlemove_string (rtx *); static void m68k_output_function_prologue (FILE *, HOST_WIDE_INT); static void m68k_output_function_epilogue (FILE *, HOST_WIDE_INT); #ifdef M68K_TARGET_COFF -static void m68k_coff_asm_named_section (const char *, unsigned int); +static void m68k_coff_asm_named_section (const char *, unsigned int, tree); #endif /* M68K_TARGET_COFF */ static void m68k_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree); @@ -3324,7 +3324,8 @@ output_xorsi3 (rtx *operands) /* Output assembly to switch to section NAME with attribute FLAGS. */ static void -m68k_coff_asm_named_section (const char *name, unsigned int flags) +m68k_coff_asm_named_section (const char *name, unsigned int flags, + tree decl ATTRIBUTE_UNUSED) { char flagchar; diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c index d121848209a..bdcbde99de5 100644 --- a/gcc/config/mcore/mcore.c +++ b/gcc/config/mcore/mcore.c @@ -138,7 +138,7 @@ const struct attribute_spec mcore_attribute_table[]; static tree mcore_handle_naked_attribute (tree *, tree, tree, int, bool *); #ifdef OBJECT_FORMAT_ELF static void mcore_asm_named_section (const char *, - unsigned int); + unsigned int, tree); #endif static void mcore_unique_section (tree, int); static void mcore_encode_section_info (tree, rtx, int); @@ -3424,7 +3424,9 @@ mcore_naked_function_p (void) #ifdef OBJECT_FORMAT_ELF static void -mcore_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED) +mcore_asm_named_section (const char *name, + unsigned int flags ATTRIBUTE_UNUSED, + tree decl ATTRIBUTE_UNUSED) { fprintf (asm_out_file, "\t.section %s\n", name); } diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index b47ccf08575..322a7863a48 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -16932,7 +16932,8 @@ rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name) } static void -rs6000_xcoff_asm_named_section (const char *name, unsigned int flags) +rs6000_xcoff_asm_named_section (const char *name, unsigned int flags, + tree decl ATTRIBUTE_UNUSED) { int smclass; static const char * const suffix[3] = { "PR", "RO", "RW" }; diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index dd441bac342..63d3f01cdca 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -304,7 +304,7 @@ static void emit_restore_regs (void); static void sparc_asm_function_prologue (FILE *, HOST_WIDE_INT); static void sparc_asm_function_epilogue (FILE *, HOST_WIDE_INT); #ifdef OBJECT_FORMAT_ELF -static void sparc_elf_asm_named_section (const char *, unsigned int); +static void sparc_elf_asm_named_section (const char *, unsigned int, tree); #endif static int sparc_adjust_cost (rtx, rtx, rtx, int); @@ -8060,13 +8060,14 @@ sparc_profile_hook (int labelno) #ifdef OBJECT_FORMAT_ELF static void -sparc_elf_asm_named_section (const char *name, unsigned int flags) +sparc_elf_asm_named_section (const char *name, unsigned int flags, + tree decl) { if (flags & SECTION_MERGE) { /* entsize cannot be expressed in this section attributes encoding style. */ - default_elf_asm_named_section (name, flags); + default_elf_asm_named_section (name, flags, decl); return; } diff --git a/gcc/configure b/gcc/configure index f5d20bfd1d5..8a20fd34a8a 100755 --- a/gcc/configure +++ b/gcc/configure @@ -10835,12 +10835,117 @@ fi echo "$as_me:$LINENO: result: $gcc_cv_as_shf_merge" >&5 echo "${ECHO_T}$gcc_cv_as_shf_merge" >&6 +if test $gcc_cv_as_shf_merge = no; then + echo "$as_me:$LINENO: checking assembler for section merging support" >&5 +echo $ECHO_N "checking assembler for section merging support... $ECHO_C" >&6 +if test "${gcc_cv_as_shf_merge+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + gcc_cv_as_shf_merge=no + if test $in_tree_gas = yes; then + if test $in_tree_gas_is_elf = yes \ + && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 12 \) \* 1000 + 0` + then gcc_cv_as_shf_merge=yes +fi + elif test x$gcc_cv_as != x; then + echo '.section .rodata.str, "aMS", %progbits, 1' > conftest.s + if { ac_try='$gcc_cv_as --fatal-warnings -o conftest.o conftest.s >&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } + then + gcc_cv_as_shf_merge=yes + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +echo "$as_me:$LINENO: result: $gcc_cv_as_shf_merge" >&5 +echo "${ECHO_T}$gcc_cv_as_shf_merge" >&6 + +fi cat >>confdefs.h <<_ACEOF #define HAVE_GAS_SHF_MERGE `if test $gcc_cv_as_shf_merge = yes; then echo 1; else echo 0; fi` _ACEOF +echo "$as_me:$LINENO: checking assembler for COMDAT group support" >&5 +echo $ECHO_N "checking assembler for COMDAT group support... $ECHO_C" >&6 +if test "${gcc_cv_as_comdat_group+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + gcc_cv_as_comdat_group=no + if test $in_tree_gas = yes; then + if test $in_tree_gas_is_elf = yes \ + && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 15 \) \* 1000 + 91` + then gcc_cv_as_comdat_group=yes +fi + elif test x$gcc_cv_as != x; then + echo '.section .text,"axG",@progbits,.foo,comdat' > conftest.s + if { ac_try='$gcc_cv_as --fatal-warnings -o conftest.o conftest.s >&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } + then + gcc_cv_as_comdat_group=yes + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +echo "$as_me:$LINENO: result: $gcc_cv_as_comdat_group" >&5 +echo "${ECHO_T}$gcc_cv_as_comdat_group" >&6 + +if test $gcc_cv_as_comdat_group = yes; then + gcc_cv_as_comdat_group_percent=no +else + echo "$as_me:$LINENO: checking assembler for COMDAT group support" >&5 +echo $ECHO_N "checking assembler for COMDAT group support... $ECHO_C" >&6 +if test "${gcc_cv_as_comdat_group_percent+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + gcc_cv_as_comdat_group_percent=no + if test $in_tree_gas = yes; then + if test $in_tree_gas_is_elf = yes \ + && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 15 \) \* 1000 + 91` + then gcc_cv_as_comdat_group_percent=yes +fi + elif test x$gcc_cv_as != x; then + echo '.section .text,"axG",%progbits,.foo,comdat' > conftest.s + if { ac_try='$gcc_cv_as --fatal-warnings -o conftest.o conftest.s >&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } + then + gcc_cv_as_comdat_group_percent=yes + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +echo "$as_me:$LINENO: result: $gcc_cv_as_comdat_group_percent" >&5 +echo "${ECHO_T}$gcc_cv_as_comdat_group_percent" >&6 + +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_GAS_COMDAT_GROUP `if test $gcc_cv_as_comdat_group = yes || test $gcc_cv_as_comdat_group_percent = yes; then echo 1; else echo 0; fi` +_ACEOF + + # Thread-local storage - the check is heavily parametrized. conftest_s= tls_first_major= diff --git a/gcc/configure.ac b/gcc/configure.ac index 94887f6bced..1ae739e7af2 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -2218,10 +2218,29 @@ fi gcc_GAS_CHECK_FEATURE(section merging support, gcc_cv_as_shf_merge, [elf,2,12,0], [--fatal-warnings], [.section .rodata.str, "aMS", @progbits, 1]) +if test $gcc_cv_as_shf_merge = no; then + gcc_GAS_CHECK_FEATURE(section merging support, gcc_cv_as_shf_merge, + [elf,2,12,0], [--fatal-warnings], + [.section .rodata.str, "aMS", %progbits, 1]) +fi AC_DEFINE_UNQUOTED(HAVE_GAS_SHF_MERGE, [`if test $gcc_cv_as_shf_merge = yes; then echo 1; else echo 0; fi`], [Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.]) +gcc_GAS_CHECK_FEATURE(COMDAT group support, gcc_cv_as_comdat_group, + [elf,2,15,91], [--fatal-warnings], + [.section .text,"axG",@progbits,.foo,comdat]) +if test $gcc_cv_as_comdat_group = yes; then + gcc_cv_as_comdat_group_percent=no +else + gcc_GAS_CHECK_FEATURE(COMDAT group support, gcc_cv_as_comdat_group_percent, + [elf,2,15,91], [--fatal-warnings], + [.section .text,"axG",%progbits,.foo,comdat]) +fi +AC_DEFINE_UNQUOTED(HAVE_GAS_COMDAT_GROUP, + [`if test $gcc_cv_as_comdat_group = yes || test $gcc_cv_as_comdat_group_percent = yes; then echo 1; else echo 0; fi`], +[Define 0/1 if your assembler supports COMDAT group.]) + # Thread-local storage - the check is heavily parametrized. conftest_s= tls_first_major= diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f886a1e0227..2be37070e5f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-09-15 Mark Mitchell + + * cp-objcp-common.h (LANG_HOOKS_COMDAT_GROUP): Define. + * cp-tree.h (cxx_comdat_group): Declare. + * decl.c (cxx_comdat_group): New function. + 2004-09-15 Nathan Sidwell * search.c (get_pure_virtuals): Remove unused variables. diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h index 1599080e896..a6ab3832a8f 100644 --- a/gcc/cp/cp-objcp-common.h +++ b/gcc/cp/cp-objcp-common.h @@ -92,6 +92,8 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t, #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl #undef LANG_HOOKS_WRITE_GLOBALS #define LANG_HOOKS_WRITE_GLOBALS lhd_do_nothing +#undef LANG_HOOKS_COMDAT_GROUP +#define LANG_HOOKS_COMDAT_GROUP cxx_comdat_group #undef LANG_HOOKS_FUNCTION_INIT #define LANG_HOOKS_FUNCTION_INIT cxx_push_function_context diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5d788af0d1b..22ac16589a4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3789,6 +3789,7 @@ extern tree builtin_function (const char *name, tree type, const char *libname, tree attrs); extern tree check_elaborated_type_specifier (enum tag_types, tree, bool); extern void warn_extern_redeclared_static (tree, tree); +extern const char *cxx_comdat_group (tree); extern bool cp_missing_noreturn_ok_p (tree); extern void initialize_artificial_var (tree, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6128598f8b8..e56023bbce6 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10883,4 +10883,24 @@ cp_missing_noreturn_ok_p (tree decl) return DECL_MAIN_P (decl); } +/* Return the COMDAT group into which DECL should be placed. */ + +const char * +cxx_comdat_group (tree decl) +{ + tree name; + + /* Virtual tables, construction virtual tables, and virtual table + tables all go in a single COMDAT group, named after the primary + virtual table. */ + if (TREE_CODE (decl) == VAR_DECL && DECL_VTABLE_OR_VTT_P (decl)) + name = DECL_ASSEMBLER_NAME (CLASSTYPE_VTABLES (DECL_CONTEXT (decl))); + /* For all other DECLs, the COMDAT group is the mangled name of the + declaration itself. */ + else + name = DECL_ASSEMBLER_NAME (decl); + + return IDENTIFIER_POINTER (name); +} + #include "gt-cp-decl.h" diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index 087fe419dae..8b57a0311ab 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -65,6 +65,7 @@ extern void lhd_incomplete_type_error (tree, tree); extern tree lhd_type_promotes_to (tree); extern void lhd_register_builtin_type (tree, const char *); extern bool lhd_decl_ok_for_sibcall (tree); +extern const char *lhd_comdat_group (tree); extern tree lhd_expr_size (tree); extern bool lhd_decl_uninit (tree); extern tree lhd_get_callee_fndecl (tree); @@ -234,6 +235,7 @@ extern tree lhd_make_node (enum tree_code); #define LANG_HOOKS_WRITE_GLOBALS write_global_declarations #define LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE NULL #define LANG_HOOKS_DECL_OK_FOR_SIBCALL lhd_decl_ok_for_sibcall +#define LANG_HOOKS_COMDAT_GROUP lhd_comdat_group #define LANG_HOOKS_DECLS { \ LANG_HOOKS_GLOBAL_BINDINGS_P, \ @@ -244,6 +246,7 @@ extern tree lhd_make_node (enum tree_code); LANG_HOOKS_WRITE_GLOBALS, \ LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE, \ LANG_HOOKS_DECL_OK_FOR_SIBCALL, \ + LANG_HOOKS_COMDAT_GROUP \ } /* The whole thing. The structure is defined in langhooks.h. */ diff --git a/gcc/langhooks.c b/gcc/langhooks.c index 309bef57794..b1fd5b4df2c 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -456,6 +456,14 @@ lhd_decl_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED) return true; } +/* Return the COMDAT group into which DECL should be placed. */ + +const char * +lhd_comdat_group (tree decl) +{ + return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); +} + /* lang_hooks.decls.final_write_globals: perform final processing on global variables. */ void diff --git a/gcc/langhooks.h b/gcc/langhooks.h index 98532521e5e..1b2dae10564 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -183,6 +183,15 @@ struct lang_hooks_for_decls /* True if this decl may be called via a sibcall. */ bool (*ok_for_sibcall) (tree); + + /* Return the COMDAT group into which this DECL should be placed. + It is known that the DECL belongs in *some* COMDAT group when + this hook is called. The return value will be used immediately, + but not explicitly deallocated, so implementations should not use + xmalloc to allocate the string returned. (Typically, the return + value will be the string already stored in an + IDENTIFIER_NODE.) */ + const char * (*comdat_group) (tree); }; /* Language-specific hooks. See langhooks-def.h for defaults. */ diff --git a/gcc/output.h b/gcc/output.h index 1e1d1defa31..989a8dc174e 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -478,15 +478,17 @@ extern void no_asm_to_stream (FILE *); extern unsigned int get_named_section_flags (const char *); extern bool set_named_section_flags (const char *, unsigned int); -extern void named_section_flags (const char *, unsigned int); +#define named_section_flags(NAME, FLAGS) \ + named_section_real((NAME), (FLAGS), /*decl=*/NULL_TREE) +extern void named_section_real (const char *, unsigned int, tree); extern bool named_section_first_declaration (const char *); extern unsigned int default_section_type_flags (tree, const char *, int); extern unsigned int default_section_type_flags_1 (tree, const char *, int, int); -extern void default_no_named_section (const char *, unsigned int); -extern void default_elf_asm_named_section (const char *, unsigned int); -extern void default_coff_asm_named_section (const char *, unsigned int); -extern void default_pe_asm_named_section (const char *, unsigned int); +extern void default_no_named_section (const char *, unsigned int, tree); +extern void default_elf_asm_named_section (const char *, unsigned int, tree); +extern void default_coff_asm_named_section (const char *, unsigned int, tree); +extern void default_pe_asm_named_section (const char *, unsigned int, tree); extern void default_stabs_asm_out_destructor (rtx, int); extern void default_named_section_asm_out_destructor (rtx, int); diff --git a/gcc/target.h b/gcc/target.h index acb1814bcc3..a6d69e1938e 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -107,9 +107,10 @@ struct gcc_target /* Output the assembler code for function exit. */ void (* function_epilogue) (FILE *, HOST_WIDE_INT); - /* Switch to an arbitrary section NAME with attributes as - specified by FLAGS. */ - void (* named_section) (const char *, unsigned int); + /* Tell assembler to change to section NAME with attributes FLAGS. + If DECL is non-NULL, it is the VAR_DECL or FUNCTION_DECL with + which this section is associated. */ + void (* named_section) (const char *name, unsigned int flags, tree decl); /* Switch to the section that holds the exception table. */ void (* exception_section) (void); diff --git a/gcc/varasm.c b/gcc/varasm.c index 1561dc7b781..e3b53da45f3 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -417,17 +417,19 @@ set_named_section_flags (const char *section, unsigned int flags) return true; } -/* Tell assembler to change to section NAME with attributes FLAGS. */ +/* Tell assembler to change to section NAME with attributes FLAGS. If + DECL is non-NULL, it is the VAR_DECL or FUNCTION_DECL with which + this section is associated. */ void -named_section_flags (const char *name, unsigned int flags) +named_section_real (const char *name, unsigned int flags, tree decl) { if (in_section != in_named || strcmp (name, in_named_name) != 0) { if (! set_named_section_flags (name, flags)) abort (); - targetm.asm_out.named_section (name, flags); + targetm.asm_out.named_section (name, flags, decl); if (flags & SECTION_FORGET) in_section = no_section; @@ -478,7 +480,7 @@ named_section (tree decl, const char *name, int reloc) error ("%J%D causes a section type conflict", decl, decl); } - named_section_flags (name, flags); + named_section_real (name, flags, decl); } /* If required, set DECL_SECTION_NAME to a unique name. */ @@ -4582,7 +4584,8 @@ default_section_type_flags_1 (tree decl, const char *name, int reloc, void default_no_named_section (const char *name ATTRIBUTE_UNUSED, - unsigned int flags ATTRIBUTE_UNUSED) + unsigned int flags ATTRIBUTE_UNUSED, + tree decl ATTRIBUTE_UNUSED) { /* Some object formats don't support named sections at all. The front-end should already have flagged this as an error. */ @@ -4590,11 +4593,17 @@ default_no_named_section (const char *name ATTRIBUTE_UNUSED, } void -default_elf_asm_named_section (const char *name, unsigned int flags) +default_elf_asm_named_section (const char *name, unsigned int flags, + tree decl ATTRIBUTE_UNUSED) { char flagchars[10], *f = flagchars; - if (! named_section_first_declaration (name)) + /* If we have already declared this section, we can use an + abbreviated form to switch back to it -- unless this section is + part of a COMDAT groups, in which case GAS requires the full + declaration every time. */ + if (!(HAVE_GAS_COMDAT_GROUP && (flags & SECTION_LINKONCE)) + && ! named_section_first_declaration (name)) { fprintf (asm_out_file, "\t.section\t%s\n", name); return; @@ -4614,6 +4623,8 @@ default_elf_asm_named_section (const char *name, unsigned int flags) *f++ = 'S'; if (flags & SECTION_TLS) *f++ = 'T'; + if (HAVE_GAS_COMDAT_GROUP && (flags & SECTION_LINKONCE)) + *f++ = 'G'; *f = '\0'; fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars); @@ -4621,23 +4632,35 @@ default_elf_asm_named_section (const char *name, unsigned int flags) if (!(flags & SECTION_NOTYPE)) { const char *type; + const char *format; if (flags & SECTION_BSS) type = "nobits"; else type = "progbits"; - fprintf (asm_out_file, ",@%s", type); + format = ",@%s"; +#ifdef ASM_COMMENT_START + /* On platforms that use "@" as the assembly comment character, + use "%" instead. */ + if (strcmp (ASM_COMMENT_START, "@") == 0) + format = ",%%%s"; +#endif + fprintf (asm_out_file, format, type); if (flags & SECTION_ENTSIZE) fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE); + if (HAVE_GAS_COMDAT_GROUP && (flags & SECTION_LINKONCE)) + fprintf (asm_out_file, ",%s,comdat", + lang_hooks.decls.comdat_group (decl)); } putc ('\n', asm_out_file); } void -default_coff_asm_named_section (const char *name, unsigned int flags) +default_coff_asm_named_section (const char *name, unsigned int flags, + tree decl ATTRIBUTE_UNUSED) { char flagchars[8], *f = flagchars; @@ -4651,9 +4674,10 @@ default_coff_asm_named_section (const char *name, unsigned int flags) } void -default_pe_asm_named_section (const char *name, unsigned int flags) +default_pe_asm_named_section (const char *name, unsigned int flags, + tree decl) { - default_coff_asm_named_section (name, flags); + default_coff_asm_named_section (name, flags, decl); if (flags & SECTION_LINKONCE) {