This option allows users to manually select what goes in the limited small data range, and still get smaller and faster small data access sequences for the selected data.
We've considered adding a new attribute, say "sdata", to let the compiler pick the sdata/sbss section name itself, but that's not strictly necessary since attribute section already does what we need. I'm not sure how the semantics of conflicting attributes should be implemented, but if others think it's a good idea, I could give it a shot. Like, if attribute((sdata, section("data"))) is given, should the variable be placed in .data but be accessed using sdata addressing modes? Should we reject that with an error? Should we warn and ignore one of the attributes? Something else? I saw comments, docs and init code that suggested the possibility of using r2/.sdata2 for small data, but I couldn't get code to be generated for such access, even with very old toolchains. I'm not sure I'm just missing how this magic comes about, or whether it hasn't been available for a very long time but nobody removed the comments/docs. Assuming I'm missing something, I put in the possibility of using r2 in the test in the patch, but I'm sure I have not exercised it to make sure I got it right. Help? I have not YET given this much testing. I'm posting it so as to give ppc maintainers an opportunity to comment on the proposed approach, in hopes of getting buy-in for the idea, if not necessarily for the patch, but I welcome alternate suggestions to enable users to choose what goes in faster sdata when there's too much data for size-based assignment to place interesting variables in sdata without overflowing its range. for gcc/ChangeLog * config/rs6000/rs6000-opts.h (SDATA_EXPLICIT): New enumerator. * config/rs6000/rs6000.c (rs6000_debug_reg_global): Handle it. (rs6000_file_start): Likewise. (rs6000_elf_in_small_data_p): Likewise. (SMALL_DATA_EABI_P): New, likewise. (SMALL_DATA_RELOC, SMALL_DATA_REG): Use it. * config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Check for and set up SDATA_EXPLICIT. * config/rs6000/sysv4.opt: Add explicit to -msdata. * doc/invoke.texi (-msdata=explicit): Document it. for gcc/testsuite/ChangeLog * gcc.target/powerpc/ppc-sdata-3.c: New. diff --git a/gcc/config/rs6000/rs6000-opts.h b/gcc/config/rs6000/rs6000-opts.h index a8194783e018..cc780f569308 100644 --- a/gcc/config/rs6000/rs6000-opts.h +++ b/gcc/config/rs6000/rs6000-opts.h @@ -120,7 +120,8 @@ enum rs6000_sdata_type { SDATA_NONE, /* No small data support. */ SDATA_DATA, /* Just put data in .sbss/.sdata, don't use relocs. */ SDATA_SYSV, /* Use r13 to point to .sdata/.sbss. */ - SDATA_EABI /* Use r13 like above, r2 points to .sdata2/.sbss2. */ + SDATA_EABI, /* Use r13 like above, r2 points to .sdata2/.sbss2. */ + SDATA_EXPLICIT /* Use r13 (or r2?) for explicit sdata. */ }; /* Type of traceback to use. */ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index ddc61bdaffe7..a679709a055f 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -2819,6 +2819,10 @@ rs6000_debug_reg_global (void) fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi"); break; + case SDATA_EXPLICIT: + fprintf (stderr, DEBUG_FMT_S, "sdata", "explicit"); + break; + } switch (rs6000_traceback) @@ -6098,6 +6102,8 @@ rs6000_file_start (void) case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break; case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break; case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break; + case SDATA_EXPLICIT: + fprintf (file, "%s -msdata=explicit", start); start = ""; break; } if (rs6000_sdata && g_switch_value) @@ -21240,8 +21246,10 @@ rs6000_output_function_entry (FILE *file, const char *fname) /* Print an operand. Recognize special options, documented below. */ #if TARGET_ELF -#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel") -#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13) +#define SMALL_DATA_EABI_P (rs6000_sdata == SDATA_EABI \ + || (rs6000_sdata == SDATA_EXPLICIT && TARGET_EABI)) +#define SMALL_DATA_RELOC (SMALL_DATA_EABI_P ? "sda21" : "sdarel") +#define SMALL_DATA_REG (SMALL_DATA_EABI_P ? 0 : 13) #else #define SMALL_DATA_RELOC "sda21" #define SMALL_DATA_REG 0 @@ -33221,6 +33229,11 @@ rs6000_elf_in_small_data_p (const_tree decl) } else { + /* Explicit mode means no implicit assignment to small data + sections. */ + if (rs6000_sdata == SDATA_EXPLICIT) + return false; + /* If we are told not to put readonly data in sdata, then don't. */ if (TREE_READONLY (decl) && rs6000_sdata != SDATA_EABI && !rs6000_readonly_in_sdata) diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h index bb19d0dcd411..83f527c57af1 100644 --- a/gcc/config/rs6000/sysv4.h +++ b/gcc/config/rs6000/sysv4.h @@ -119,6 +119,8 @@ do { \ rs6000_sdata = SDATA_DATA; \ else if (!strcmp (rs6000_sdata_name, "default")) \ rs6000_sdata = (TARGET_EABI) ? SDATA_EABI : SDATA_SYSV; \ + else if (!strcmp (rs6000_sdata_name, "explicit")) \ + rs6000_sdata = SDATA_EXPLICIT; \ else if (!strcmp (rs6000_sdata_name, "sysv")) \ rs6000_sdata = SDATA_SYSV; \ else if (!strcmp (rs6000_sdata_name, "eabi")) \ diff --git a/gcc/config/rs6000/sysv4.opt b/gcc/config/rs6000/sysv4.opt index 34fea0ddd08a..d11053e4bdaf 100644 --- a/gcc/config/rs6000/sysv4.opt +++ b/gcc/config/rs6000/sysv4.opt @@ -25,7 +25,7 @@ Target RejectNegative Joined Var(rs6000_abi_name) msdata= Target RejectNegative Joined Var(rs6000_sdata_name) --msdata=[none,data,sysv,eabi] Select method for sdata handling. +-msdata=[none,data,sysv,eabi,explicit] Select method for sdata handling. mreadonly-in-sdata Target Report Var(rs6000_readonly_in_sdata) Init(1) Save diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 444159178a76..86dbb1d8700d 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -22824,6 +22824,16 @@ On embedded PowerPC systems, put all initialized global and static data in the @code{.data} section, and all uninitialized data in the @code{.bss} section. +@item -msdata=explicit +@itemx -msdata +@opindex msdata=explicit +@opindex msdata +Put all initialized global and static data that is not assigned to an +explicit section in the @code{.data} section, and all uninitialized data +that is not assigned to an explicit section in the @code{.bss} section. +Use small data access patterns to access variables explicitly assigned +to small data sections. + @item -mblock-move-inline-limit=@var{num} @opindex mblock-move-inline-limit Inline all block moves (such as calls to @code{memcpy} or structure diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-sdata-3.c b/gcc/testsuite/gcc.target/powerpc/ppc-sdata-3.c new file mode 100644 index 000000000000..750e5ad234af --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/ppc-sdata-3.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-msdata=explicit" } */ +/* { dg-require-effective-target powerpc_eabi_ok } */ +/* { dg-require-effective-target nonpic } */ +/* { dg-final { scan-assembler "\\.section\[ \t\]\\.sdata," } } */ +/* { dg-final { scan-assembler "\\.section\[ \t\]\\.sbss," } } */ +/* { dg-final { scan-assembler "\\.section\[ \t\]\\.sdata2," } } */ +/* { dg-final { scan-assembler "\\.section\[ \t\]\\.sbss2," } } */ +/* { dg-final { scan-assembler "i@ha" } } */ +/* { dg-final { scan-assembler "j@sda(rel|21)\\((13|0)\\)" } } */ +/* { dg-final { scan-assembler "k@sda(rel|21)\\((13|0)\\)" } } */ +/* { dg-final { scan-assembler "l@sda(rel|21)\\((2|13|0)\\)" } } */ +/* { dg-final { scan-assembler "m@sda(rel|21)\\((2|13|0)\\)" } } */ + +static int i; +static int j __attribute__((section(".sbss"))); +static int k __attribute__((section(".sdata"))) = 2; +static int l __attribute__((section(".sbss2"))); +static int m __attribute__((section(".sdata2"))) = 4; +int f(void) { + return i + j + k + l + m; +} -- Alexandre Oliva, freedom fighter https://FSFLA.org/blogs/lxo Be the change, be Free! FSF Latin America board member GNU Toolchain Engineer Free Software Evangelist