This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
rs6000 -fdata-sections
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 4 Dec 2001 16:59:48 +1030
- Subject: rs6000 -fdata-sections
This simple testcase illustrates a problem with current powerpc-linux-gcc
on both mainline and branch.
$ cat static.c
const int a[10000] = {1, 2, };
$ powerpc-linux-gcc -O2 -ffunction-sections -fdata-sections -S static.c
$ cat static.s
.file "static.c"
.globl a
.section .sdata.a,"a",@progbits
.align 2
.type a,@object
.size a,40000
a:
.long 1
.long 2
.space 39992
.ident "GCC: (GNU) 3.0.3 20011127 (prerelease)"
'a' certainly shouldn't go into .sdata
The nub of the problem is that this expression
sec = ((TREE_CODE (decl) == FUNCTION_DECL ? 0 : 1)
+ (readonly ? 0 : 2)
+ (needs_sdata ? 1 : 0)
+ (DECL_INITIAL (decl) == 0
|| DECL_INITIAL (decl) == error_mark_node) ? 4 : 0);
is missing parentheses around the last term, but I didn't find that until
I'd simplified things as in the following patch. At least in my opinion
it's simpler and gcc seems to agree, generating smaller and likely faster
code.
* config/rs6000/rs6000.c (rs6000_unique_section): Simplify and
correct code selecting section.
OK for mainline and branch? Or should I just fix the missing parens on
the branch?
Oh yeah, bootstrapping powerpc-linux at the moment.
--
Alan Modra
*** gcc/config/rs6000/rs6000.c~ Tue Dec 4 07:49:51 2001
--- gcc/config/rs6000/rs6000.c Tue Dec 4 15:03:53 2001
*************** rs6000_unique_section (decl, reloc)
*** 9451,9504 ****
tree decl;
int reloc;
{
! int size = int_size_in_bytes (TREE_TYPE (decl));
! int needs_sdata;
! int readonly;
int len;
int sec;
const char *name;
char *string;
const char *prefix;
! static const char *const prefixes[7][2] =
{
! { ".text.", ".gnu.linkonce.t." },
! { ".rodata.", ".gnu.linkonce.r." },
! { ".sdata2.", ".gnu.linkonce.s2." },
! { ".data.", ".gnu.linkonce.d." },
! { ".sdata.", ".gnu.linkonce.s." },
! { ".bss.", ".gnu.linkonce.b." },
! { ".sbss.", ".gnu.linkonce.sb." }
};
-
- needs_sdata = (TREE_CODE (decl) != FUNCTION_DECL
- && size > 0
- && size <= g_switch_value
- && rs6000_sdata != SDATA_NONE
- && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
! if (TREE_CODE (decl) == STRING_CST)
! readonly = ! flag_writable_strings;
! else if (TREE_CODE (decl) == VAR_DECL)
! readonly = (! (flag_pic && reloc)
! && TREE_READONLY (decl)
! && ! TREE_SIDE_EFFECTS (decl)
! && DECL_INITIAL (decl)
! && DECL_INITIAL (decl) != error_mark_node
! && TREE_CONSTANT (DECL_INITIAL (decl)));
else
! readonly = 1;
! if (needs_sdata && rs6000_sdata != SDATA_EABI)
! readonly = 0;
! sec = ((TREE_CODE (decl) == FUNCTION_DECL ? 0 : 1)
! + (readonly ? 0 : 2)
! + (needs_sdata ? 1 : 0)
! + (DECL_INITIAL (decl) == 0
! || DECL_INITIAL (decl) == error_mark_node) ? 4 : 0);
STRIP_NAME_ENCODING (name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
! prefix = prefixes[sec][DECL_ONE_ONLY (decl)];
len = strlen (name) + strlen (prefix);
string = alloca (len + 1);
--- 9451,9509 ----
tree decl;
int reloc;
{
! int size;
int len;
int sec;
const char *name;
char *string;
const char *prefix;
! static const char *const prefixes[14] =
{
! ".rodata.", ".gnu.linkonce.r.",
! ".sdata2.", ".gnu.linkonce.s2.",
! ".data.", ".gnu.linkonce.d.",
! ".sdata.", ".gnu.linkonce.s.",
! ".bss.", ".gnu.linkonce.b.",
! ".sbss.", ".gnu.linkonce.sb.",
! ".text.", ".gnu.linkonce.t."
};
! if (TREE_CODE (decl) == FUNCTION_DECL)
! sec = 12;
else
! {
! if (DECL_INITIAL (decl) == 0
! || DECL_INITIAL (decl) == error_mark_node)
! sec = 8;
! else if ((TREE_CODE (decl) == STRING_CST
! && flag_writable_strings)
! || (TREE_CODE (decl) == VAR_DECL
! && ((flag_pic && reloc)
! || ! TREE_READONLY (decl)
! || TREE_SIDE_EFFECTS (decl)
! || ! TREE_CONSTANT (DECL_INITIAL (decl)))))
! sec = 4;
! else
! sec = 0;
! size = int_size_in_bytes (TREE_TYPE (decl));
! if (size > 0
! && size <= g_switch_value
! && rs6000_sdata != SDATA_NONE
! && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
! {
! if (sec == 0 && rs6000_sdata != SDATA_EABI)
! sec = 4;
! sec += 2;
! }
! }
!
! if (DECL_ONE_ONLY (decl))
! sec += 1;
STRIP_NAME_ENCODING (name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
! prefix = prefixes[sec];
len = strlen (name) + strlen (prefix);
string = alloca (len + 1);