re PR target/59710 (Nios2: Missing gprel optimization)

2015-01-15  Sandra Loosemore  <sandra@codesourcery.com>

	PR target/59710

	gcc/
	* doc/invoke.texi (Option Summary): Document new Nios II
	-mgpopt= syntax.
	(Nios II Options): Likewise.
	* config/nios2/nios2.opt: Add -mgpopt= option support.
	Modify existing -mgpopt and -mno-gpopt options to be aliases.
	* config/nios2/nios2-opts.h (enum nios2_gpopt_type): New.
	* config/nios2/nios2.c (nios2_option_override): Adjust
	-mgpopt defaulting.
	(nios2_in_small_data_p): Return true for explicit small data
	sections even with -G0.
	(nios2_symbol_ref_in_small_data_p): Adjust to handle new -mgpopt=
	option choices.

	gcc/testsuite/
	* gcc.target/nios2/gpopt-all.c: New test case.
	* gcc.target/nios2/gpopt-local.c: New test case.
	* gcc.target/nios2/gpopt-global.c: New test case.
	* gcc.target/nios2/gpopt-data.c: New test case.
	* gcc.target/nios2/gpopt-none.c: New test case.

From-SVN: r219700
This commit is contained in:
Sandra Loosemore 2015-01-15 19:43:24 -05:00 committed by Sandra Loosemore
parent 23470a893c
commit 56314783c3
11 changed files with 367 additions and 25 deletions

View file

@ -1,3 +1,19 @@
2015-01-15 Sandra Loosemore <sandra@codesourcery.com>
PR target/59710
* doc/invoke.texi (Option Summary): Document new Nios II
-mgpopt= syntax.
(Nios II Options): Likewise.
* config/nios2/nios2.opt: Add -mgpopt= option support.
Modify existing -mgpopt and -mno-gpopt options to be aliases.
* config/nios2/nios2-opts.h (enum nios2_gpopt_type): New.
* config/nios2/nios2.c (nios2_option_override): Adjust
-mgpopt defaulting.
(nios2_in_small_data_p): Return true for explicit small data
sections even with -G0.
(nios2_symbol_ref_in_small_data_p): Adjust to handle new -mgpopt=
option choices.
2015-01-15 Jan Hubicka <hubicka@ucw.cz>
PR ipa/64612

View file

@ -20,6 +20,18 @@ along with GCC; see the file COPYING3. If not see
#ifndef NIOS2_OPTS_H
#define NIOS2_OPTS_H
/* Enumerate the possible -mgpopt choices. */
enum nios2_gpopt_type
{
gpopt_unspecified = -1,
gpopt_none,
gpopt_local,
gpopt_global,
gpopt_data,
gpopt_all
};
/* Enumeration of all FPU insn codes. */
#define N2FPU_ALL_CODES \
N2FPU_CODE(fadds) N2FPU_CODE(fsubs) N2FPU_CODE(fmuls) N2FPU_CODE(fdivs) \

View file

@ -1038,9 +1038,14 @@ nios2_option_override (void)
= (global_options_set.x_g_switch_value
? g_switch_value : NIOS2_DEFAULT_GVALUE);
/* Default to -mgpopt unless -fpic or -fPIC. */
if (TARGET_GPOPT == -1 && flag_pic)
TARGET_GPOPT = 0;
if (nios2_gpopt_option == gpopt_unspecified)
{
/* Default to -mgpopt unless -fpic or -fPIC. */
if (flag_pic)
nios2_gpopt_option = gpopt_none;
else
nios2_gpopt_option = gpopt_local;
}
/* If we don't have mul, we don't have mulx either! */
if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
@ -1657,8 +1662,7 @@ nios2_in_small_data_p (const_tree exp)
if (DECL_SECTION_NAME (exp))
{
const char *section = DECL_SECTION_NAME (exp);
if (nios2_section_threshold > 0
&& nios2_small_section_name_p (section))
if (nios2_small_section_name_p (section))
return true;
}
else
@ -1681,19 +1685,63 @@ nios2_in_small_data_p (const_tree exp)
bool
nios2_symbol_ref_in_small_data_p (rtx sym)
{
gcc_assert (GET_CODE (sym) == SYMBOL_REF);
return
(TARGET_GPOPT
/* GP-relative access cannot be used for externally defined symbols,
because the compilation unit that defines the symbol may place it
in a section that cannot be reached from GP. */
&& !SYMBOL_REF_EXTERNAL_P (sym)
/* True if a symbol is both small and not weak. */
&& SYMBOL_REF_SMALL_P (sym)
&& !(SYMBOL_REF_DECL (sym) && DECL_WEAK (SYMBOL_REF_DECL (sym)))
/* TLS variables are not accessed through the GP. */
&& SYMBOL_REF_TLS_MODEL (sym) == 0);
tree decl;
gcc_assert (GET_CODE (sym) == SYMBOL_REF);
decl = SYMBOL_REF_DECL (sym);
/* TLS variables are not accessed through the GP. */
if (SYMBOL_REF_TLS_MODEL (sym) != 0)
return false;
/* If the user has explicitly placed the symbol in a small data section
via an attribute, generate gp-relative addressing even if the symbol
is external, weak, or larger than we'd automatically put in the
small data section. OTOH, if the symbol is located in some
non-small-data section, we can't use gp-relative accesses on it
unless the user has requested gpopt_data or gpopt_all. */
switch (nios2_gpopt_option)
{
case gpopt_none:
/* Don't generate a gp-relative addressing mode if that's been
disabled. */
return false;
case gpopt_local:
/* Use GP-relative addressing for small data symbols that are
not external or weak, plus any symbols that have explicitly
been placed in a small data section. */
if (decl && DECL_SECTION_NAME (decl))
return nios2_small_section_name_p (DECL_SECTION_NAME (decl));
return (SYMBOL_REF_SMALL_P (sym)
&& !SYMBOL_REF_EXTERNAL_P (sym)
&& !(decl && DECL_WEAK (decl)));
case gpopt_global:
/* Use GP-relative addressing for small data symbols, even if
they are external or weak. Note that SYMBOL_REF_SMALL_P
is also true of symbols that have explicitly been placed
in a small data section. */
return SYMBOL_REF_SMALL_P (sym);
case gpopt_data:
/* Use GP-relative addressing for all data symbols regardless
of the object size, but not for code symbols. This option
is equivalent to the user asserting that the entire data
section is accessible from the GP. */
return !SYMBOL_REF_FUNCTION_P (sym);
case gpopt_all:
/* Use GP-relative addressing for everything, including code.
Effectively, the user has asserted that the entire program
fits within the 64K range of the GP offset. */
return true;
default:
/* We shouldn't get here. */
return false;
}
}
/* Implement TARGET_SECTION_TYPE_FLAGS. */

View file

@ -58,9 +58,36 @@ mcache-volatile
Target Report RejectNegative Undocumented InverseMask(BYPASS_CACHE_VOLATILE)
Volatile memory accesses do not use I/O load/store instructions
mgpopt=
Target RejectNegative Joined Enum(nios2_gpopt_type) Var(nios2_gpopt_option) Init(gpopt_unspecified)
Enable/disable GP-relative addressing.
Enum
Name(nios2_gpopt_type) Type(enum nios2_gpopt_type)
Valid options for GP-relative addressing (for -mgpopt):
EnumValue
Enum(nios2_gpopt_type) String(none) Value(gpopt_none)
EnumValue
Enum(nios2_gpopt_type) String(local) Value(gpopt_local)
EnumValue
Enum(nios2_gpopt_type) String(global) Value(gpopt_global)
EnumValue
Enum(nios2_gpopt_type) String(data) Value(gpopt_data)
EnumValue
Enum(nios2_gpopt_type) String(all) Value(gpopt_all)
mgpopt
Target Report Var(TARGET_GPOPT) Init(-1)
Use GP-relative addressing to access small data
Target Report RejectNegative Var(nios2_gpopt_option, gpopt_local)
Equivalent to -mgpopt=local.
mno-gpopt
Target Report RejectNegative Var(nios2_gpopt_option, gpopt_none)
Equivalent to -mgpopt=none.
meb
Target Report RejectNegative Mask(BIG_ENDIAN)

View file

@ -869,7 +869,8 @@ Objective-C and Objective-C++ Dialects}.
-mex9 -mctor-dtor -mrelax}
@emph{Nios II Options}
@gccoptlist{-G @var{num} -mgpopt -mno-gpopt -mel -meb @gol
@gccoptlist{-G @var{num} -mgpopt=@var{option} -mgpopt -mno-gpopt @gol
-mel -meb @gol
-mno-bypass-cache -mbypass-cache @gol
-mno-cache-volatile -mcache-volatile @gol
-mno-fast-sw-div -mfast-sw-div @gol
@ -19214,15 +19215,54 @@ Put global and static objects less than or equal to @var{num} bytes
into the small data or BSS sections instead of the normal data or BSS
sections. The default value of @var{num} is 8.
@item -mgpopt=@var{option}
@item -mgpopt
@itemx -mno-gpopt
@opindex mgpopt
@opindex mno-gpopt
Generate (do not generate) GP-relative accesses for objects in the
small data or BSS sections. The default is @option{-mgpopt} except
when @option{-fpic} or @option{-fPIC} is specified to generate
position-independent code. Note that the Nios II ABI does not permit
GP-relative accesses from shared libraries.
Generate (do not generate) GP-relative accesses. The following
@var{option} names are recognized:
@table @samp
@item none
Do not generate GP-relative accesses.
@item local
Generate GP-relative accesses for small data objects that are not
external or weak. Also use GP-relative addressing for objects that
have been explicitly placed in a small data section via a @code{section}
attribute.
@item global
As for @samp{local}, but also generate GP-relative accesses for
small data objects that are external or weak. If you use this option,
you must ensure that all parts of your program (including libraries) are
compiled with the same @option{-G} setting.
@item data
Generate GP-relative accesses for all data objects in the program. If you
use this option, the entire data and BSS segments
of your program must fit in 64K of memory and you must use an appropriate
linker script to allocate them within the addressible range of the
global pointer.
@item all
Generate GP-relative addresses for function pointers as well as data
pointers. If you use this option, the entire text, data, and BSS segments
of your program must fit in 64K of memory and you must use an appropriate
linker script to allocate them within the addressible range of the
global pointer.
@end table
@option{-mgpopt} is equivalent to @option{-mgpopt=local}, and
@option{-mno-gpopt} is equivalent to @option{-mgpopt=none}.
The default is @option{-mgpopt} except when @option{-fpic} or
@option{-fPIC} is specified to generate position-independent code.
Note that the Nios II ABI does not permit GP-relative accesses from
shared libraries.
You may need to specify @option{-mno-gpopt} explicitly when building
programs that include large amounts of small data, including large

View file

@ -1,3 +1,12 @@
2015-01-15 Sandra Loosemore <sandra@codesourcery.com>
PR target/59710
* gcc.target/nios2/gpopt-all.c: New test case.
* gcc.target/nios2/gpopt-local.c: New test case.
* gcc.target/nios2/gpopt-global.c: New test case.
* gcc.target/nios2/gpopt-data.c: New test case.
* gcc.target/nios2/gpopt-none.c: New test case.
2015-01-15 Jakub Jelinek <jakub@redhat.com>
* g++.dg/ubsan/vptr-1.C: New test.

View file

@ -0,0 +1,38 @@
/* { dg-do compile } */
/* { dg-options "-O -mgpopt=all" } */
extern int a __attribute__ ((section (".sdata")));
static volatile int b __attribute__ ((section (".sdata"))) = 1;
extern int c __attribute__ ((section (".data")));
static volatile int d __attribute__ ((section (".data"))) = 2;
extern int e;
static volatile int f = 3;
volatile int g __attribute__ ((weak)) = 4;
extern int h[100];
static int i[100];
static int j[100] __attribute__ ((section (".sdata")));
typedef int (*ftype) (int);
extern int foo (int);
extern int bar (int, int*, int*, int*, ftype);
int baz (void)
{
return bar (a + b + c + d + e + f + g, h, i, j, foo);
}
/* { dg-final { scan-assembler "%gprel\\(a\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(b\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(c\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(d\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(e\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(f\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(g\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(h\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(i\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(j\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(foo\\)" } } */

View file

@ -0,0 +1,38 @@
/* { dg-do compile } */
/* { dg-options "-O -mgpopt=data" } */
extern int a __attribute__ ((section (".sdata")));
static volatile int b __attribute__ ((section (".sdata"))) = 1;
extern int c __attribute__ ((section (".data")));
static volatile int d __attribute__ ((section (".data"))) = 2;
extern int e;
static volatile int f = 3;
volatile int g __attribute__ ((weak)) = 4;
extern int h[100];
static int i[100];
static int j[100] __attribute__ ((section (".sdata")));
typedef int (*ftype) (int);
extern int foo (int);
extern int bar (int, int*, int*, int*, ftype);
int baz (void)
{
return bar (a + b + c + d + e + f + g, h, i, j, foo);
}
/* { dg-final { scan-assembler "%gprel\\(a\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(b\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(c\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(d\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(e\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(f\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(g\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(h\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(i\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(j\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(foo\\)" } } */

View file

@ -0,0 +1,38 @@
/* { dg-do compile } */
/* { dg-options "-O -mgpopt=global" } */
extern int a __attribute__ ((section (".sdata")));
static volatile int b __attribute__ ((section (".sdata"))) = 1;
extern int c __attribute__ ((section (".data")));
static volatile int d __attribute__ ((section (".data"))) = 2;
extern int e;
static volatile int f = 3;
volatile int g __attribute__ ((weak)) = 4;
extern int h[100];
static int i[100];
static int j[100] __attribute__ ((section (".sdata")));
typedef int (*ftype) (int);
extern int foo (int);
extern int bar (int, int*, int*, int*, ftype);
int baz (void)
{
return bar (a + b + c + d + e + f + g, h, i, j, foo);
}
/* { dg-final { scan-assembler "%gprel\\(a\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(b\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(c\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(d\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(e\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(f\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(g\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(h\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(i\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(j\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(foo\\)" } } */

View file

@ -0,0 +1,38 @@
/* { dg-do compile } */
/* { dg-options "-O -mgpopt=local" } */
extern int a __attribute__ ((section (".sdata")));
static volatile int b __attribute__ ((section (".sdata"))) = 1;
extern int c __attribute__ ((section (".data")));
static volatile int d __attribute__ ((section (".data"))) = 2;
extern int e;
static volatile int f = 3;
volatile int g __attribute__ ((weak)) = 4;
extern int h[100];
static int i[100];
static int j[100] __attribute__ ((section (".sdata")));
typedef int (*ftype) (int);
extern int foo (int);
extern int bar (int, int*, int*, int*, ftype);
int baz (void)
{
return bar (a + b + c + d + e + f + g, h, i, j, foo);
}
/* { dg-final { scan-assembler "%gprel\\(a\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(b\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(c\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(d\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(e\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(f\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(g\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(h\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(i\\)" } } */
/* { dg-final { scan-assembler "%gprel\\(j\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(foo\\)" } } */

View file

@ -0,0 +1,38 @@
/* { dg-do compile } */
/* { dg-options "-O -mgpopt=none" } */
extern int a __attribute__ ((section (".sdata")));
static volatile int b __attribute__ ((section (".sdata"))) = 1;
extern int c __attribute__ ((section (".data")));
static volatile int d __attribute__ ((section (".data"))) = 2;
extern int e;
static volatile int f = 3;
volatile int g __attribute__ ((weak)) = 4;
extern int h[100];
static int i[100];
static int j[100] __attribute__ ((section (".sdata")));
typedef int (*ftype) (int);
extern int foo (int);
extern int bar (int, int*, int*, int*, ftype);
int baz (void)
{
return bar (a + b + c + d + e + f + g, h, i, j, foo);
}
/* { dg-final { scan-assembler-not "%gprel\\(a\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(b\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(c\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(d\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(e\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(f\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(g\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(h\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(i\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(j\\)" } } */
/* { dg-final { scan-assembler-not "%gprel\\(foo\\)" } } */