From 516edfdd8a1bffdfe73a09f4813c50c6a22cba39 Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay Date: Wed, 20 Apr 2011 13:38:05 +0000 Subject: [PATCH] re PR target/18145 (Do not emit __do_copy_data or __do_clear_bss if .data or .bss is empty.) PR target/18145 * config/avr/avr.h (TARGET_ASM_INIT_SECTIONS): Delete. (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL): Delete. (ASM_OUTPUT_ALIGNED_DECL_COMMON): Define. (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Define. (TARGET_ASM_NAMED_SECTION): Change to avr_asm_named_section. * config/avr/avr-protos.h (avr_asm_output_aligned_common): New prototype. * config/avr/avr.c (TARGET_ASM_INIT_SECTIONS): Define. (avr_asm_named_section, avr_asm_output_aligned_common, avr_output_data_section_asm_op, avr_output_bss_section_asm_op): New functions to update... (avr_need_clear_bss_p, avr_need_copy_data_p): ...these new variables. (avr_asm_init_sections): Overwrite section callbacks for data_section, bss_section. (avr_file_start): Move output of __do_copy_data, __do_clear_bss from here to... (avr_file_end): ...here. From-SVN: r172769 --- gcc/ChangeLog | 24 ++++++++ gcc/config/avr/avr-protos.h | 1 + gcc/config/avr/avr.c | 108 +++++++++++++++++++++++++++++++++--- gcc/config/avr/avr.h | 19 ++----- 4 files changed, 131 insertions(+), 21 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index da88769f6ca..ca18ffa018c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +2011-04-20 Georg-Johann Lay + + PR target/18145 + + * config/avr/avr.h (TARGET_ASM_INIT_SECTIONS): Delete. + (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL): Delete. + (ASM_OUTPUT_ALIGNED_DECL_COMMON): Define. + (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Define. + (TARGET_ASM_NAMED_SECTION): Change to avr_asm_named_section. + + * config/avr/avr-protos.h (avr_asm_output_aligned_common): + New prototype. + + * config/avr/avr.c (TARGET_ASM_INIT_SECTIONS): Define. + (avr_asm_named_section, avr_asm_output_aligned_common, + avr_output_data_section_asm_op, avr_output_bss_section_asm_op): + New functions to update... + (avr_need_clear_bss_p, avr_need_copy_data_p): ...these new variables. + (avr_asm_init_sections): Overwrite section callbacks for + data_section, bss_section. + (avr_file_start): Move output of __do_copy_data, __do_clear_bss + from here to... + (avr_file_end): ...here. + 2011-04-20 Richard Guenther PR middle-end/48695 diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h index b00637e069e..2f3e93d883c 100644 --- a/gcc/config/avr/avr-protos.h +++ b/gcc/config/avr/avr-protos.h @@ -36,6 +36,7 @@ extern int avr_hard_regno_rename_ok (unsigned int, unsigned int); extern rtx avr_return_addr_rtx (int count, rtx tem); #ifdef TREE_CODE +extern void avr_asm_output_aligned_decl_common (FILE*, const_tree, const char*, unsigned HOST_WIDE_INT, unsigned int, bool); extern void asm_output_external (FILE *file, tree decl, char *name); extern int avr_progmem_p (tree decl, tree attributes); diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 500a5b287ae..9184d6cd963 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -108,6 +108,7 @@ static void avr_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static void avr_help (void); static bool avr_function_ok_for_sibcall (tree, tree); +static void avr_asm_named_section (const char *name, unsigned int flags, tree decl); /* Allocate registers from r25 to r8 for parameters for function calls. */ #define FIRST_CUM_REG 26 @@ -132,6 +133,10 @@ const struct mcu_type_s *avr_current_device; section *progmem_section; +/* To track if code will use .bss and/or .data. */ +bool avr_need_clear_bss_p = false; +bool avr_need_copy_data_p = false; + /* AVR attributes. */ static const struct attribute_spec avr_attribute_table[] = { @@ -197,6 +202,12 @@ static const struct default_options avr_option_optimization_table[] = #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes #undef TARGET_SECTION_TYPE_FLAGS #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags + +/* `TARGET_ASM_NAMED_SECTION' must be defined in avr.h. */ + +#undef TARGET_ASM_INIT_SECTIONS +#define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections + #undef TARGET_REGISTER_MOVE_COST #define TARGET_REGISTER_MOVE_COST avr_register_move_cost #undef TARGET_MEMORY_MOVE_COST @@ -5190,7 +5201,60 @@ avr_output_progmem_section_asm_op (const void *arg ATTRIBUTE_UNUSED) fprintf (asm_out_file, "\t.p2align 1\n"); } -/* Implement TARGET_ASM_INIT_SECTIONS. */ + +/* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'. */ +/* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'. */ +/* Track need of __do_clear_bss. */ + +void +avr_asm_output_aligned_decl_common (FILE * stream, const_tree decl ATTRIBUTE_UNUSED, + const char *name, unsigned HOST_WIDE_INT size, + unsigned int align, bool local_p) +{ + avr_need_clear_bss_p = true; + + if (local_p) + { + fputs ("\t.local\t", stream); + assemble_name (stream, name); + fputs ("\n", stream); + } + + fputs ("\t.comm\t", stream); + assemble_name (stream, name); + fprintf (stream, + "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n", + size, align / BITS_PER_UNIT); +} + + +/* Unnamed section callback for data_section + to track need of __do_copy_data. */ + +static void +avr_output_data_section_asm_op (const void *data) +{ + avr_need_copy_data_p = true; + + /* Dispatch to default. */ + output_section_asm_op (data); +} + + +/* Unnamed section callback for bss_section + to track need of __do_clear_bss. */ + +static void +avr_output_bss_section_asm_op (const void *data) +{ + avr_need_clear_bss_p = true; + + /* Dispatch to default. */ + output_section_asm_op (data); +} + + +/* Implement `TARGET_ASM_INIT_SECTIONS'. */ static void avr_asm_init_sections (void) @@ -5199,6 +5263,27 @@ avr_asm_init_sections (void) avr_output_progmem_section_asm_op, NULL); readonly_data_section = data_section; + + data_section->unnamed.callback = avr_output_data_section_asm_op; + bss_section->unnamed.callback = avr_output_bss_section_asm_op; +} + + +/* Implement `TARGET_ASM_NAMED_SECTION'. */ +/* Track need of __do_clear_bss, __do_copy_data for named sections. */ + +void +avr_asm_named_section (const char *name, unsigned int flags, tree decl) +{ + if (!avr_need_copy_data_p) + avr_need_copy_data_p = (0 == strncmp (name, ".data", 5) + || 0 == strncmp (name, ".rodata", 7) + || 0 == strncmp (name, ".gnu.linkonce.d", 15)); + + if (!avr_need_clear_bss_p) + avr_need_clear_bss_p = (0 == strncmp (name, ".bss", 4)); + + default_elf_asm_named_section (name, flags, decl); } static unsigned int @@ -5219,6 +5304,8 @@ avr_section_type_flags (tree decl, const char *name, int reloc) return flags; } + +/* Implement `TARGET_ASM_FILE_START'. */ /* Outputs some appropriate text to go at the start of an assembler file. */ @@ -5237,20 +5324,27 @@ avr_file_start (void) fputs ("__tmp_reg__ = 0\n" "__zero_reg__ = 1\n", asm_out_file); - - /* FIXME: output these only if there is anything in the .data / .bss - sections - some code size could be saved by not linking in the - initialization code from libgcc if one or both sections are empty. */ - fputs ("\t.global __do_copy_data\n", asm_out_file); - fputs ("\t.global __do_clear_bss\n", asm_out_file); } + +/* Implement `TARGET_ASM_FILE_END'. */ /* Outputs to the stdio stream FILE some appropriate text to go at the end of an assembler file. */ static void avr_file_end (void) { + /* Output these only if there is anything in the + .data* / .rodata* / .gnu.linkonce.* resp. .bss* + input section(s) - some code size can be saved by not + linking in the initialization code from libgcc if resp. + sections are empty. */ + + if (avr_need_copy_data_p) + fputs (".global __do_copy_data\n", asm_out_file); + + if (avr_need_clear_bss_p) + fputs (".global __do_clear_bss\n", asm_out_file); } /* Choose the order in which to allocate hard registers for diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index aaf29dc31c5..b0c1b49486e 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -460,29 +460,20 @@ do { \ #define ASM_APP_OFF "/* #NOAPP */\n" /* Switch into a generic section. */ -#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section -#define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections +#define TARGET_ASM_NAMED_SECTION avr_asm_named_section #define ASM_OUTPUT_ASCII(FILE, P, SIZE) gas_output_ascii (FILE,P,SIZE) #define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == '\n' || ((C) == '$')) -#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \ -do { \ - fputs ("\t.comm ", (STREAM)); \ - assemble_name ((STREAM), (NAME)); \ - fprintf ((STREAM), ",%lu,1\n", (unsigned long)(SIZE)); \ -} while (0) +#define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGN) \ + avr_asm_output_aligned_decl_common (STREAM, DECL, NAME, SIZE, ALIGN, false) #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN) -#define ASM_OUTPUT_LOCAL(STREAM, NAME, SIZE, ROUNDED) \ -do { \ - fputs ("\t.lcomm ", (STREAM)); \ - assemble_name ((STREAM), (NAME)); \ - fprintf ((STREAM), ",%d\n", (int)(SIZE)); \ -} while (0) +#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGN) \ + avr_asm_output_aligned_decl_common (STREAM, DECL, NAME, SIZE, ALIGN, true) #undef TYPE_ASM_OP #undef SIZE_ASM_OP -- 2.30.2