[AArch64] Mark GOT related MEM rtx as const to help RTL loop IV

gcc/
    * config/aarch64/aarch64.c (aarch64_load_symref_appropriately): Mark mem
    as READONLY and NOTRAP for PIC symbol.

  gcc/testsuite/
    * gcc.target/aarch64/got_mem_hoist_1.c: New test.

From-SVN: r225669
This commit is contained in:
Jiong Wang 2015-07-10 12:20:54 +00:00 committed by Jiong Wang
parent 9fdcd34e0f
commit 53021678c5
4 changed files with 60 additions and 6 deletions

View File

@ -1,3 +1,8 @@
2015-07-10 Jiong Wang <jiong.wang@arm.com>
* config/aarch64/aarch64.c (aarch64_load_symref_appropriately): Mark mem
as READONLY and NOTRAP for PIC symbol.
2015-07-10 Andrew MacLeod <amacleod@redhat.com> 2015-07-10 Andrew MacLeod <amacleod@redhat.com>
* gimple-predict.h: New file. * gimple-predict.h: New file.

View File

@ -890,6 +890,8 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
{ {
machine_mode mode = GET_MODE (dest); machine_mode mode = GET_MODE (dest);
rtx gp_rtx = pic_offset_table_rtx; rtx gp_rtx = pic_offset_table_rtx;
rtx insn;
rtx mem;
/* NOTE: pic_offset_table_rtx can be NULL_RTX, because we can reach /* NOTE: pic_offset_table_rtx can be NULL_RTX, because we can reach
here before rtl expand. Tree IVOPT will generate rtl pattern to here before rtl expand. Tree IVOPT will generate rtl pattern to
@ -933,16 +935,27 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
if (mode == ptr_mode) if (mode == ptr_mode)
{ {
if (mode == DImode) if (mode == DImode)
emit_insn (gen_ldr_got_small_28k_di (dest, gp_rtx, imm)); insn = gen_ldr_got_small_28k_di (dest, gp_rtx, imm);
else else
emit_insn (gen_ldr_got_small_28k_si (dest, gp_rtx, imm)); insn = gen_ldr_got_small_28k_si (dest, gp_rtx, imm);
mem = XVECEXP (SET_SRC (insn), 0, 0);
} }
else else
{ {
gcc_assert (mode == Pmode); gcc_assert (mode == Pmode);
emit_insn (gen_ldr_got_small_28k_sidi (dest, gp_rtx, imm));
insn = gen_ldr_got_small_28k_sidi (dest, gp_rtx, imm);
mem = XVECEXP (XEXP (SET_SRC (insn), 0), 0, 0);
} }
/* The operand is expected to be MEM. Whenever the related insn
pattern changed, above code which calculate mem should be
updated. */
gcc_assert (GET_CODE (mem) == MEM);
MEM_READONLY_P (mem) = 1;
MEM_NOTRAP_P (mem) = 1;
emit_insn (insn);
return; return;
} }
@ -955,6 +968,9 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
DImode if dest is dereferenced to access the memeory. DImode if dest is dereferenced to access the memeory.
This is why we have to handle three different ldr_got_small This is why we have to handle three different ldr_got_small
patterns here (two patterns for ILP32). */ patterns here (two patterns for ILP32). */
rtx insn;
rtx mem;
rtx tmp_reg = dest; rtx tmp_reg = dest;
machine_mode mode = GET_MODE (dest); machine_mode mode = GET_MODE (dest);
@ -965,16 +981,24 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
if (mode == ptr_mode) if (mode == ptr_mode)
{ {
if (mode == DImode) if (mode == DImode)
emit_insn (gen_ldr_got_small_di (dest, tmp_reg, imm)); insn = gen_ldr_got_small_di (dest, tmp_reg, imm);
else else
emit_insn (gen_ldr_got_small_si (dest, tmp_reg, imm)); insn = gen_ldr_got_small_si (dest, tmp_reg, imm);
mem = XVECEXP (SET_SRC (insn), 0, 0);
} }
else else
{ {
gcc_assert (mode == Pmode); gcc_assert (mode == Pmode);
emit_insn (gen_ldr_got_small_sidi (dest, tmp_reg, imm));
insn = gen_ldr_got_small_sidi (dest, tmp_reg, imm);
mem = XVECEXP (XEXP (SET_SRC (insn), 0), 0, 0);
} }
gcc_assert (GET_CODE (mem) == MEM);
MEM_READONLY_P (mem) = 1;
MEM_NOTRAP_P (mem) = 1;
emit_insn (insn);
return; return;
} }

View File

@ -1,3 +1,7 @@
2015-07-10 Jiong Wang <jiong.wang@arm.com>
* gcc.target/aarch64/got_mem_hoist_1.c: New test.
2015-07-10 Christophe Lyon <christophe.lyon@linaro.org> 2015-07-10 Christophe Lyon <christophe.lyon@linaro.org>
* gcc.target/arm/attr_thumb.c: Skip if Thumb is not supported. * gcc.target/arm/attr_thumb.c: Skip if Thumb is not supported.

View File

@ -0,0 +1,21 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fpic -fdump-rtl-loop2_invariant" } */
int bar (int);
int cal (void *);
int
foo (int a, int bound)
{
int i = 0;
int sum = 0;
for (i; i < bound; i++)
sum = cal (bar);
return sum;
}
/* The insn which loads function address from GOT table should be moved out
of the loop. */
/* { dg-final { scan-rtl-dump "Decided" "loop2_invariant" } } */