S/390: New option -mpic-data-is-text-relative
For hotpatching it might be required to introduce new .text parts while keep using the existing .data/.bss sections. To make this work the backend needs to be prevented from using relative addressing between code and data. This only works when already building PIC since the addressing will then be handling via GOT. gcc/testsuite/ChangeLog: 2017-06-28 Andreas Krebbel <krebbel@linux.vnet.ibm.com> * gcc.target/s390/nodatarel-1.c: New test. gcc/ChangeLog: 2017-06-28 Andreas Krebbel <krebbel@linux.vnet.ibm.com> * config/s390/predicates.md: Use s390_rel_address_ok_p. * config/s390/s390-protos.h: Add prototype of s390_rel_address_ok_p. * config/s390/s390.c (s390_got_symbol): New function. (s390_rel_address_ok_p): New function. (legitimize_pic_address): Use s390_rel_address_ok_p. (s390_load_got): Use s390_got_symbol. (s390_option_override): Issue error if -mno-pic-data-is-text-relative is used without -fpic/-fPIC. * config/s390/s390.h (TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE): New macro. * config/s390/s390.opt: New option mpic-data-is-text-relative. From-SVN: r249720
This commit is contained in:
parent
8801653208
commit
935b5226c3
8 changed files with 159 additions and 14 deletions
|
@ -1,3 +1,18 @@
|
|||
2017-06-28 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
|
||||
|
||||
* config/s390/predicates.md: Use s390_rel_address_ok_p.
|
||||
* config/s390/s390-protos.h: Add prototype of
|
||||
s390_rel_address_ok_p.
|
||||
* config/s390/s390.c (s390_got_symbol): New function.
|
||||
(s390_rel_address_ok_p): New function.
|
||||
(legitimize_pic_address): Use s390_rel_address_ok_p.
|
||||
(s390_load_got): Use s390_got_symbol.
|
||||
(s390_option_override): Issue error if
|
||||
-mno-pic-data-is-text-relative is used without -fpic/-fPIC.
|
||||
* config/s390/s390.h (TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE):
|
||||
New macro.
|
||||
* config/s390/s390.opt: New option mpic-data-is-text-relative.
|
||||
|
||||
2017-06-27 Andrew Pinski <apinski@cavium.com>
|
||||
|
||||
* match.pd (X >/>=/</<= 0 ? 1.0 : -1.0): New patterns.
|
||||
|
|
|
@ -131,10 +131,10 @@
|
|||
/* Allow labels and local symbols. */
|
||||
if (GET_CODE (op) == LABEL_REF)
|
||||
return true;
|
||||
if (GET_CODE (op) == SYMBOL_REF)
|
||||
if (SYMBOL_REF_P (op))
|
||||
return (!SYMBOL_FLAG_NOTALIGN2_P (op)
|
||||
&& SYMBOL_REF_TLS_MODEL (op) == 0
|
||||
&& (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
|
||||
&& s390_rel_address_ok_p (op));
|
||||
|
||||
/* Everything else must have a CONST, so strip it. */
|
||||
if (GET_CODE (op) != CONST)
|
||||
|
@ -156,10 +156,11 @@
|
|||
/* Labels and local symbols allowed here as well. */
|
||||
if (GET_CODE (op) == LABEL_REF)
|
||||
return true;
|
||||
if (GET_CODE (op) == SYMBOL_REF)
|
||||
if (SYMBOL_REF_P (op))
|
||||
return (!SYMBOL_FLAG_NOTALIGN2_P (op)
|
||||
&& SYMBOL_REF_TLS_MODEL (op) == 0
|
||||
&& (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
|
||||
&& s390_rel_address_ok_p (op));
|
||||
|
||||
|
||||
/* Now we must have a @GOTENT offset or @PLT stub
|
||||
or an @INDNTPOFF TLS offset. */
|
||||
|
|
|
@ -79,6 +79,7 @@ extern bool s390_bytemask_vector_p (rtx, unsigned *);
|
|||
extern bool s390_split_ok_p (rtx, rtx, machine_mode, int);
|
||||
extern bool s390_overlap_p (rtx, rtx, HOST_WIDE_INT);
|
||||
extern bool s390_offset_p (rtx, rtx, rtx);
|
||||
extern bool s390_rel_address_ok_p (rtx);
|
||||
extern int tls_symbolic_operand (rtx);
|
||||
|
||||
extern bool s390_match_ccmode (rtx_insn *, machine_mode);
|
||||
|
|
|
@ -1179,6 +1179,23 @@ s390_label_align (rtx_insn *label)
|
|||
return align_labels_log;
|
||||
}
|
||||
|
||||
static GTY(()) rtx got_symbol;
|
||||
|
||||
/* Return the GOT table symbol. The symbol will be created when the
|
||||
function is invoked for the first time. */
|
||||
|
||||
static rtx
|
||||
s390_got_symbol (void)
|
||||
{
|
||||
if (!got_symbol)
|
||||
{
|
||||
got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
|
||||
SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
|
||||
}
|
||||
|
||||
return got_symbol;
|
||||
}
|
||||
|
||||
static machine_mode
|
||||
s390_libgcc_cmp_return_mode (void)
|
||||
{
|
||||
|
@ -4496,6 +4513,26 @@ s390_load_address (rtx dst, rtx src)
|
|||
emit_insn (gen_force_la_31 (dst, src));
|
||||
}
|
||||
|
||||
/* Return true if it ok to use SYMBOL_REF in a relative address. */
|
||||
|
||||
bool
|
||||
s390_rel_address_ok_p (rtx symbol_ref)
|
||||
{
|
||||
tree decl;
|
||||
|
||||
if (symbol_ref == s390_got_symbol () || CONSTANT_POOL_ADDRESS_P (symbol_ref))
|
||||
return true;
|
||||
|
||||
decl = SYMBOL_REF_DECL (symbol_ref);
|
||||
|
||||
if (!flag_pic || SYMBOL_REF_LOCAL_P (symbol_ref))
|
||||
return (s390_pic_data_is_text_relative
|
||||
|| (decl
|
||||
&& TREE_CODE (decl) == FUNCTION_DECL));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return a legitimate reference for ORIG (an address) using the
|
||||
register REG. If REG is 0, a new pseudo is generated.
|
||||
|
||||
|
@ -4533,7 +4570,7 @@ legitimize_pic_address (rtx orig, rtx reg)
|
|||
}
|
||||
|
||||
if ((GET_CODE (addr) == LABEL_REF
|
||||
|| (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr))
|
||||
|| (SYMBOL_REF_P (addr) && s390_rel_address_ok_p (addr))
|
||||
|| (GET_CODE (addr) == UNSPEC &&
|
||||
(XINT (addr, 1) == UNSPEC_GOTENT
|
||||
|| (TARGET_CPU_ZARCH && XINT (addr, 1) == UNSPEC_PLT))))
|
||||
|
@ -10791,7 +10828,6 @@ restore_gprs (rtx base, int offset, int first, int last)
|
|||
|
||||
/* Return insn sequence to load the GOT register. */
|
||||
|
||||
static GTY(()) rtx got_symbol;
|
||||
rtx_insn *
|
||||
s390_load_got (void)
|
||||
{
|
||||
|
@ -10803,23 +10839,17 @@ s390_load_got (void)
|
|||
aren't usable. */
|
||||
rtx got_rtx = gen_rtx_REG (Pmode, 12);
|
||||
|
||||
if (!got_symbol)
|
||||
{
|
||||
got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
|
||||
SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
|
||||
}
|
||||
|
||||
start_sequence ();
|
||||
|
||||
if (TARGET_CPU_ZARCH)
|
||||
{
|
||||
emit_move_insn (got_rtx, got_symbol);
|
||||
emit_move_insn (got_rtx, s390_got_symbol ());
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx offset;
|
||||
|
||||
offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
|
||||
offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, s390_got_symbol ()),
|
||||
UNSPEC_LTREL_OFFSET);
|
||||
offset = gen_rtx_CONST (Pmode, offset);
|
||||
offset = force_const_mem (Pmode, offset);
|
||||
|
@ -14911,6 +14941,9 @@ s390_option_override (void)
|
|||
if (flag_prefetch_loop_arrays < 0 && HAVE_prefetch && optimize >= 3)
|
||||
flag_prefetch_loop_arrays = 1;
|
||||
|
||||
if (!s390_pic_data_is_text_relative && !flag_pic)
|
||||
error ("-mno-pic-data-is-text-relative cannot be used without -fpic/-fPIC");
|
||||
|
||||
if (TARGET_TPF)
|
||||
{
|
||||
/* Don't emit DWARF3/4 unless specifically selected. The TPF
|
||||
|
|
|
@ -946,6 +946,10 @@ CUMULATIVE_ARGS;
|
|||
|
||||
#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
|
||||
|
||||
#ifndef TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE
|
||||
#define TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Assembler file format. */
|
||||
|
||||
|
|
|
@ -226,3 +226,7 @@ values are small, non-negative integers. The default branch cost is
|
|||
mlra
|
||||
Target Report Var(s390_lra_flag) Init(1) Save
|
||||
Use LRA instead of reload.
|
||||
|
||||
mpic-data-is-text-relative
|
||||
Target Report Var(s390_pic_data_is_text_relative) Init(TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE)
|
||||
Assume data segments are relative to text segment.
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2017-06-28 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
|
||||
|
||||
* gcc.target/s390/nodatarel-1.c: New test.
|
||||
|
||||
2017-06-27 Jerry DeLisle <jvdelisle@gcc.gnu.org>
|
||||
|
||||
PR fortran/80164
|
||||
|
|
83
gcc/testsuite/gcc.target/s390/nodatarel-1.c
Normal file
83
gcc/testsuite/gcc.target/s390/nodatarel-1.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* Test -mno-pic-data-is-text-relative option. No relative addressing
|
||||
of elements in .data and .bss are allowed with that option. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O3 -fno-optimize-sibling-calls -fpic -mno-pic-data-is-text-relative -march=z10 -mtune=z9-109 -mzarch" } */
|
||||
|
||||
static int a = 3;
|
||||
|
||||
/* With -mno-pic-data-is-text-relative these must be addressed via
|
||||
GOT. */
|
||||
|
||||
int __attribute__((noinline,noclone))
|
||||
foo ()
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
static int __attribute__((noinline,noclone))
|
||||
foostatic (void)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
/* Just to make a potentially modified. */
|
||||
|
||||
void
|
||||
bar (int b)
|
||||
{
|
||||
a = b;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-times "a@GOTENT" 3 } } */
|
||||
|
||||
/* The exrl target is a label_ref which should not be affected at
|
||||
all. */
|
||||
|
||||
void
|
||||
mymemcpy (char *dst, char *src, long size)
|
||||
{
|
||||
__builtin_memcpy (dst, src, size);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "exrl" } } */
|
||||
|
||||
|
||||
/* PLT slots can still be addressed relatively. */
|
||||
|
||||
int
|
||||
callfoo ()
|
||||
{
|
||||
return foo ();
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-times "foo@PLT" 1 } } */
|
||||
|
||||
|
||||
/* GOT entries can still be addressed relatively. */
|
||||
|
||||
void *
|
||||
fooptr ()
|
||||
{
|
||||
return &foo;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-times "foo@GOTENT" 1 } } */
|
||||
|
||||
|
||||
/* A static function can be addressed relatively. */
|
||||
|
||||
int
|
||||
callfoostatic ()
|
||||
{
|
||||
return foostatic ();
|
||||
}
|
||||
|
||||
void *
|
||||
foostaticptr ()
|
||||
{
|
||||
return &foostatic;
|
||||
}
|
||||
|
||||
|
||||
/* { dg-final { scan-assembler-not "foostatic@" } } */
|
Loading…
Add table
Reference in a new issue