[ARC] Improves and fixes for small data support.

Add alignment check for short load/store instructions used for sdata,
as they request 32-bit aligned short immediate.  Use sdata symbol
alignment information and emit scalled loads/stores whenever is
possible. The scalled address will extend the access range for sdata
symbols.  Allow 64-bit datum into small data section, if double
load/store instructions are present.

gcc/
2017-04-12  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc-protos.h (compact_sda_memory_operand): Update
	prototype.
	* config/arc/arc.c (arc_print_operand): Output scalled address for
	sdata whenever is possible.
	(arc_in_small_data_p): Allow sdata for 64bit datum when double
	load/stores are available.
	(compact_sda_memory_operand): Check for the alignment required by
	code density instructions.
	* config/arc/arc.md (movsi_insn): Use newly introduced Us0
	constraint.
	* config/arc/constraints.md (Usd): Update constraint.
	(Us0): New constraint.
	(Usc): Update constraint.

gcc/testsuite/
2017-04-12  Claudiu Zissulescu  <claziss@synopsys.com>

	* gcc.target/arc/sdata-3.c: New file.

From-SVN: r251562
This commit is contained in:
Claudiu Zissulescu 2017-08-31 15:52:31 +02:00 committed by Claudiu Zissulescu
parent a621861e39
commit b6fb793374
7 changed files with 126 additions and 12 deletions

View file

@ -1,3 +1,19 @@
2017-08-31 Claudiu Zissulescu <claziss@synopsys.com>
* config/arc/arc-protos.h (compact_sda_memory_operand): Update
prototype.
* config/arc/arc.c (arc_print_operand): Output scalled address for
sdata whenever is possible.
(arc_in_small_data_p): Allow sdata for 64bit datum when double
load/stores are available.
(compact_sda_memory_operand): Check for the alignment required by
code density instructions.
* config/arc/arc.md (movsi_insn): Use newly introduced Us0
constraint.
* config/arc/constraints.md (Usd): Update constraint.
(Us0): New constraint.
(Usc): Update constraint.
2017-08-31 Richard Biener <rguenther@suse.de>
PR middle-end/82054

View file

@ -27,7 +27,7 @@ extern struct rtx_def *gen_compare_reg (rtx, machine_mode);
/* Declarations for various fns used in the .md file. */
extern void arc_output_function_epilogue (FILE *, HOST_WIDE_INT, int);
extern const char *output_shift (rtx *);
extern bool compact_sda_memory_operand (rtx op,machine_mode mode);
extern bool compact_sda_memory_operand (rtx, machine_mode, bool);
extern bool arc_double_limm_p (rtx);
extern void arc_print_operand (FILE *, rtx, int);
extern void arc_print_operand_address (FILE *, rtx);

View file

@ -3804,6 +3804,26 @@ arc_print_operand (FILE *file, rtx x, int code)
fputs (".as", file);
output_scaled = 1;
}
else if (LEGITIMATE_SMALL_DATA_ADDRESS_P (addr)
&& GET_MODE_SIZE (GET_MODE (x)) > 1)
{
tree decl = NULL_TREE;
int align = 0;
if (GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
decl = SYMBOL_REF_DECL (XEXP (addr, 1));
else if (GET_CODE (XEXP (XEXP (XEXP (addr, 1), 0), 0))
== SYMBOL_REF)
decl = SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr, 1), 0), 0));
if (decl)
align = DECL_ALIGN (decl);
align = align / BITS_PER_UNIT;
if ((GET_MODE_SIZE (GET_MODE (x)) == 2)
&& align && ((align & 1) == 0))
fputs (".as", file);
if ((GET_MODE_SIZE (GET_MODE (x)) >= 4)
&& align && ((align & 3) == 0))
fputs (".as", file);
}
break;
case REG:
break;
@ -7475,12 +7495,10 @@ arc_in_small_data_p (const_tree decl)
{
HOST_WIDE_INT size;
/* Strings and functions are never in small data area. */
if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
return false;
/* We don't yet generate small-data references for -mabicalls. See related
-G handling in override_options. */
if (TARGET_NO_SDATA_SET)
return false;
@ -7499,7 +7517,7 @@ arc_in_small_data_p (const_tree decl)
return true;
}
/* Only global variables go into sdata section for now. */
else if (1)
else
{
/* Don't put constants into the small data section: we want them
to be in ROM rather than RAM. */
@ -7529,9 +7547,6 @@ arc_in_small_data_p (const_tree decl)
size = int_size_in_bytes (TREE_TYPE (decl));
/* if (AGGREGATE_TYPE_P (TREE_TYPE (decl))) */
/* return false; */
/* Allow only <=4B long data types into sdata. */
return (size > 0 && size <= 4);
}
@ -7623,10 +7638,13 @@ small_data_pattern (rtx op, machine_mode)
/* volatile cache option still to be handled. */
bool
compact_sda_memory_operand (rtx op, machine_mode mode)
compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
{
rtx addr;
int size;
tree decl = NULL_TREE;
int align = 0;
int mask = 0;
/* Eliminate non-memory operations. */
if (GET_CODE (op) != MEM)
@ -7644,7 +7662,35 @@ compact_sda_memory_operand (rtx op, machine_mode mode)
/* Decode the address now. */
addr = XEXP (op, 0);
return LEGITIMATE_SMALL_DATA_ADDRESS_P (addr);
if (!LEGITIMATE_SMALL_DATA_ADDRESS_P (addr))
return false;
if (!short_p || size == 1)
return true;
/* Now check for the alignment, the short loads using gp require the
addresses to be aligned. */
if (GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
decl = SYMBOL_REF_DECL (XEXP (addr, 1));
else if (GET_CODE (XEXP (XEXP (XEXP (addr, 1), 0), 0)) == SYMBOL_REF)
decl = SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr, 1), 0), 0));
if (decl)
align = DECL_ALIGN (decl);
align = align / BITS_PER_UNIT;
switch (mode)
{
case E_HImode:
mask = 1;
break;
default:
mask = 3;
break;
}
if (align && ((align & mask) == 0))
return true;
return false;
}
/* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */

View file

@ -355,7 +355,7 @@
"@internal
A valid _small-data_ memory operand for ARCompact instructions"
(and (match_code "mem")
(match_test "compact_sda_memory_operand (op, VOIDmode)")))
(match_test "compact_sda_memory_operand (op, VOIDmode, true)")))
(define_memory_constraint "Usc"
"@internal
@ -363,7 +363,7 @@
(and (match_code "mem")
(match_test "!CONSTANT_P (XEXP (op,0))")
;; ??? the assembler rejects stores of immediates to small data.
(match_test "!compact_sda_memory_operand (op, VOIDmode)")))
(match_test "!compact_sda_memory_operand (op, VOIDmode, false)")))
(define_constraint "Us<"
"@internal

View file

@ -1,3 +1,8 @@
2017-08-31 Claudiu Zissulescu <claziss@synopsys.com>
* gcc.target/arc/sdata-3.c: New file.
* gcc.target/arc/sdata-4.c: Likewise.
2017-08-31 Richard Biener <rguenther@suse.de>
PR middle-end/82054

View file

@ -0,0 +1,32 @@
/* Check if sdata access is done correctly, specially
for variables which are having a different alignment
than the default data type indicates. */
/* { dg-do compile } */
/* { dg-options "-O2" } */
int g_a __attribute__ ((aligned (1)));
int g_b;
short g_c;
char g_d;
#define TEST(name, optype) \
void test_ ## name (optype x) \
{ \
g_ ## name += x; \
}
TEST (a, int)
TEST (b, int)
TEST (c, short)
TEST (d, char)
/* { dg-final { scan-assembler "ld r2,\\\[gp,@g_a@sda\\\]" } } */
/* { dg-final { scan-assembler "ld.as r2,\\\[gp,@g_b@sda\\\]" } } */
/* { dg-final { scan-assembler "ld\[hw\]\\\.as r2,\\\[gp,@g_c@sda\\\]" } } */
/* { dg-final { scan-assembler "ldb r2,\\\[gp,@g_d@sda\\\]" } } */
/* { dg-final { scan-assembler "st r0,\\\[gp,@g_a@sda\\\]" } } */
/* { dg-final { scan-assembler "st_s r0,\\\[gp,@g_b@sda\\\]" { target { arcem || archs } } } } */
/* { dg-final { scan-assembler "st\\\.as r0,\\\[gp,@g_b@sda\\\]" { target { arc700 || arc6xx } } } } */
/* { dg-final { scan-assembler "st\[hw\]\\\.as r0,\\\[gp,@g_c@sda\\\]" } } */
/* { dg-final { scan-assembler "stb r0,\\\[gp,@g_d@sda\\\]" } } */

View file

@ -0,0 +1,15 @@
/* Check if sdata access is done correctly, specially
for variables which are having a different alignment
than the default data type indicates. */
/* { dg-do compile } */
/* { dg-options "-O2" } */
short gA __attribute__ ((aligned(1)));
void foo (void)
{
gA += gA + 3;
}
/* { dg-final { scan-assembler-not "ld\[wh\]_s r0,\\\[gp" } } */
/* { dg-final { scan-assembler-not "st\[wh\]\\\.as.*gp" } } */