Commit 886a64f9 by Georg-Johann Lay Committed by Georg-Johann Lay

re PR target/43746 (-fmerge-constants and -fmerge-all-constants don't work at AVR target)

gcc/
	PR target/43746
	* config/avr/avr.c (AVR_SECTION_PROGMEM): New Define.
	(progmem_section): New Variable.
	(avr_asm_init_sections): Initialize it.
	(TARGET_ASM_SELECT_SECTION): Define to...
	(avr_asm_select_section): ... this new Function.
	(avr_replace_prefix): New Function.
	(avr_asm_function_rodata_section): Use it.
	(avr_insert_attributes): Don't add section attribute for PROGMEM.
	(avr_section_type_flags): Use avr_progmem_p instead of section
	name to detect if object is in PROGMEM.
	(avr_asm_named_section): Set section name prefix for objects in
	PROGMEM.

testsuite/
	PR target/43746
	* testsuite/gcc.target/avr/torture/avr-torture.exp
	(AVR_TORTURE_OPTIONS): Add test cases "-O2 -fdata-sections" and
	"-O2 -fmerge-all-constants".

From-SVN: r178779
parent dc72b313
2011-09-12 Georg-Johann Lay <avr@gjlay.de>
PR target/43746
* config/avr/avr.c (AVR_SECTION_PROGMEM): New Define.
(progmem_section): New Variable.
(avr_asm_init_sections): Initialize it.
(TARGET_ASM_SELECT_SECTION): Define to...
(avr_asm_select_section): ... this new Function.
(avr_replace_prefix): New Function.
(avr_asm_function_rodata_section): Use it.
(avr_insert_attributes): Don't add section attribute for PROGMEM.
(avr_section_type_flags): Use avr_progmem_p instead of section
name to detect if object is in PROGMEM.
(avr_asm_named_section): Set section name prefix for objects in
PROGMEM.
2011-09-12 Jakub Jelinek <jakub@redhat.com> 2011-09-12 Jakub Jelinek <jakub@redhat.com>
PR bootstrap/50352 PR bootstrap/50352
...@@ -54,6 +54,8 @@ ...@@ -54,6 +54,8 @@
/* Return true if STR starts with PREFIX and false, otherwise. */ /* Return true if STR starts with PREFIX and false, otherwise. */
#define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX))) #define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX)))
#define AVR_SECTION_PROGMEM (SECTION_MACH_DEP << 0)
static void avr_option_override (void); static void avr_option_override (void);
static int avr_naked_function_p (tree); static int avr_naked_function_p (tree);
static int interrupt_function_p (tree); static int interrupt_function_p (tree);
...@@ -114,6 +116,7 @@ static bool avr_function_ok_for_sibcall (tree, tree); ...@@ -114,6 +116,7 @@ static bool avr_function_ok_for_sibcall (tree, tree);
static void avr_asm_named_section (const char *name, unsigned int flags, tree decl); static void avr_asm_named_section (const char *name, unsigned int flags, tree decl);
static void avr_encode_section_info (tree, rtx, int); static void avr_encode_section_info (tree, rtx, int);
static section* avr_asm_function_rodata_section (tree); static section* avr_asm_function_rodata_section (tree);
static section* avr_asm_select_section (tree, int, unsigned HOST_WIDE_INT);
/* Allocate registers from r25 to r8 for parameters for function calls. */ /* Allocate registers from r25 to r8 for parameters for function calls. */
#define FIRST_CUM_REG 26 #define FIRST_CUM_REG 26
...@@ -139,6 +142,9 @@ const struct mcu_type_s *avr_current_device; ...@@ -139,6 +142,9 @@ const struct mcu_type_s *avr_current_device;
/* Section to put switch tables in. */ /* Section to put switch tables in. */
static GTY(()) section *progmem_swtable_section; static GTY(()) section *progmem_swtable_section;
/* Unnamed section associated to __attribute__((progmem)) aka. PROGMEM. */
static GTY(()) section *progmem_section;
/* To track if code will use .bss and/or .data. */ /* To track if code will use .bss and/or .data. */
bool avr_need_clear_bss_p = false; bool avr_need_clear_bss_p = false;
bool avr_need_copy_data_p = false; bool avr_need_copy_data_p = false;
...@@ -206,6 +212,8 @@ static const struct attribute_spec avr_attribute_table[] = ...@@ -206,6 +212,8 @@ static const struct attribute_spec avr_attribute_table[] =
#define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
#undef TARGET_ENCODE_SECTION_INFO #undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO avr_encode_section_info #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
#undef TARGET_ASM_SELECT_SECTION
#define TARGET_ASM_SELECT_SECTION avr_asm_select_section
#undef TARGET_REGISTER_MOVE_COST #undef TARGET_REGISTER_MOVE_COST
#define TARGET_REGISTER_MOVE_COST avr_register_move_cost #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
...@@ -270,6 +278,31 @@ static const struct attribute_spec avr_attribute_table[] = ...@@ -270,6 +278,31 @@ static const struct attribute_spec avr_attribute_table[] =
struct gcc_target targetm = TARGET_INITIALIZER; struct gcc_target targetm = TARGET_INITIALIZER;
/* Custom function to replace string prefix.
Return a ggc-allocated string with strlen (OLD_PREFIX) characters removed
from the start of OLD_STR and then prepended with NEW_PREFIX. */
static inline const char*
avr_replace_prefix (const char *old_str,
const char *old_prefix, const char *new_prefix)
{
char *new_str;
size_t len = strlen (old_str) + strlen (new_prefix) - strlen (old_prefix);
gcc_assert (strlen (old_prefix) <= strlen (old_str));
/* Unfortunately, ggc_alloc_string returns a const char* and thus cannot be
used here. */
new_str = (char*) ggc_alloc_atomic (1 + len);
strcat (stpcpy (new_str, new_prefix), old_str + strlen (old_prefix));
return (const char*) new_str;
}
static void static void
avr_option_override (void) avr_option_override (void)
{ {
...@@ -5034,15 +5067,7 @@ avr_insert_attributes (tree node, tree *attributes) ...@@ -5034,15 +5067,7 @@ avr_insert_attributes (tree node, tree *attributes)
if (error_mark_node == node0) if (error_mark_node == node0)
return; return;
if (TYPE_READONLY (node0)) if (!TYPE_READONLY (node0))
{
static const char dsec[] = ".progmem.data";
*attributes = tree_cons (get_identifier ("section"),
build_tree_list (NULL, build_string (strlen (dsec), dsec)),
*attributes);
}
else
{ {
error ("variable %q+D must be const in order to be put into" error ("variable %q+D must be const in order to be put into"
" read-only section by means of %<__attribute__((progmem))%>", " read-only section by means of %<__attribute__((progmem))%>",
...@@ -5119,6 +5144,10 @@ avr_asm_init_sections (void) ...@@ -5119,6 +5144,10 @@ avr_asm_init_sections (void)
",\"ax\",@progbits"); ",\"ax\",@progbits");
} }
progmem_section
= get_unnamed_section (0, output_section_asm_op,
"\t.section\t.progmem.data,\"a\",@progbits");
/* Override section callbacks to keep track of `avr_need_clear_bss_p' /* Override section callbacks to keep track of `avr_need_clear_bss_p'
resp. `avr_need_copy_data_p'. */ resp. `avr_need_copy_data_p'. */
...@@ -5173,11 +5202,7 @@ avr_asm_function_rodata_section (tree decl) ...@@ -5173,11 +5202,7 @@ avr_asm_function_rodata_section (tree decl)
if (STR_PREFIX_P (name, old_prefix)) if (STR_PREFIX_P (name, old_prefix))
{ {
char *rname = (char*) alloca (1 + strlen (name) const char *rname = avr_replace_prefix (name, old_prefix, new_prefix);
+ strlen (new_prefix)
- strlen (old_prefix));
strcat (stpcpy (rname, new_prefix), name + strlen (old_prefix));
flags &= ~SECTION_CODE; flags &= ~SECTION_CODE;
flags |= AVR_HAVE_JMP_CALL ? 0 : SECTION_CODE; flags |= AVR_HAVE_JMP_CALL ? 0 : SECTION_CODE;
...@@ -5197,6 +5222,22 @@ avr_asm_function_rodata_section (tree decl) ...@@ -5197,6 +5222,22 @@ avr_asm_function_rodata_section (tree decl)
static void static void
avr_asm_named_section (const char *name, unsigned int flags, tree decl) avr_asm_named_section (const char *name, unsigned int flags, tree decl)
{ {
if (flags & AVR_SECTION_PROGMEM)
{
const char *old_prefix = ".rodata";
const char *new_prefix = ".progmem.data";
const char *sname = new_prefix;
if (STR_PREFIX_P (name, old_prefix))
{
sname = avr_replace_prefix (name, old_prefix, new_prefix);
}
default_elf_asm_named_section (sname, flags, decl);
return;
}
if (!avr_need_copy_data_p) if (!avr_need_copy_data_p)
avr_need_copy_data_p = (STR_PREFIX_P (name, ".data") avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
|| STR_PREFIX_P (name, ".rodata") || STR_PREFIX_P (name, ".rodata")
...@@ -5223,8 +5264,12 @@ avr_section_type_flags (tree decl, const char *name, int reloc) ...@@ -5223,8 +5264,12 @@ avr_section_type_flags (tree decl, const char *name, int reloc)
".noinit section"); ".noinit section");
} }
if (STR_PREFIX_P (name, ".progmem.data")) if (decl && DECL_P (decl)
flags &= ~SECTION_WRITE; && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
{
flags &= ~SECTION_WRITE;
flags |= AVR_SECTION_PROGMEM;
}
return flags; return flags;
} }
...@@ -5254,6 +5299,36 @@ avr_encode_section_info (tree decl, rtx rtl, ...@@ -5254,6 +5299,36 @@ avr_encode_section_info (tree decl, rtx rtl,
} }
/* Implement `TARGET_ASM_SELECT_SECTION' */
static section *
avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
{
section * sect = default_elf_select_section (decl, reloc, align);
if (decl && DECL_P (decl)
&& avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
{
if (sect->common.flags & SECTION_NAMED)
{
const char * name = sect->named.name;
const char * old_prefix = ".rodata";
const char * new_prefix = ".progmem.data";
if (STR_PREFIX_P (name, old_prefix))
{
const char *sname = avr_replace_prefix (name, old_prefix, new_prefix);
return get_section (sname, sect->common.flags, sect->named.decl);
}
}
return progmem_section;
}
return sect;
}
/* Implement `TARGET_ASM_FILE_START'. */ /* Implement `TARGET_ASM_FILE_START'. */
/* Outputs some appropriate text to go at the start of an assembler /* Outputs some appropriate text to go at the start of an assembler
file. */ file. */
......
2011-09-12 Georg-Johann Lay <avr@gjlay.de>
PR target/43746
* testsuite/gcc.target/avr/torture/avr-torture.exp
(AVR_TORTURE_OPTIONS): Add test cases "-O2 -fdata-sections" and
"-O2 -fmerge-all-constants".
2011-09-11 Thomas Koenig <tkoenig@gcc.gnu.org> 2011-09-11 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/50327 PR fortran/50327
......
# Copyright (C) 2008 Free Software Foundation, Inc. # Copyright (C) 2008 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or # the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see # along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>. # <http://www.gnu.org/licenses/>.
# GCC testsuite that uses the `gcc-dg.exp' driver, looping over # GCC testsuite that uses the `gcc-dg.exp' driver, looping over
# optimization options. # optimization options.
# Exit immediately if this isn't a AVR target. # Exit immediately if this isn't a AVR target.
if { ![istarget avr-*-*] } then { if { ![istarget avr-*-*] } then {
return return
} }
# Load support procs. # Load support procs.
load_lib gcc-dg.exp load_lib gcc-dg.exp
# If a testcase doesn't have special options, use these. # If a testcase doesn't have special options, use these.
global DEFAULT_CFLAGS global DEFAULT_CFLAGS
if ![info exists DEFAULT_CFLAGS] then { if ![info exists DEFAULT_CFLAGS] then {
set DEFAULT_CFLAGS " -ansi -pedantic-errors" set DEFAULT_CFLAGS " -ansi -pedantic-errors"
} }
# Initialize `dg'. # Initialize `dg'.
dg-init dg-init
set AVR_TORTURE_OPTIONS [list \ set AVR_TORTURE_OPTIONS [list \
{ -O0 } \ { -O0 } \
{ -O1 } \ { -O1 } \
{ -O2 } \ { -O2 } \
{ -O2 -mcall-prologues } \ { -O2 -mcall-prologues } \
{ -Os -fomit-frame-pointer } \ { -O2 -fdata-sections } \
{ -Os -fomit-frame-pointer -finline-functions } \ { -O2 -fmerge-all-constants } \
{ -O3 -g } \ { -Os -fomit-frame-pointer } \
{ -Os -mcall-prologues} ] { -Os -fomit-frame-pointer -finline-functions } \
{ -O3 -g } \
{ -Os -mcall-prologues} ]
#Initialize use of torture lists.
torture-init
#Initialize use of torture lists.
set-torture-options $AVR_TORTURE_OPTIONS torture-init
set-torture-options $AVR_TORTURE_OPTIONS
# Main loop.
gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{\[cS\],cpp}]] $DEFAULT_CFLAGS
# Main loop.
# Finalize use of torture lists. gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{\[cS\],cpp}]] $DEFAULT_CFLAGS
torture-finish
# Finalize use of torture lists.
# All done. torture-finish
dg-finish
# All done.
dg-finish
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment