[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>
* 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);
rtx gp_rtx = pic_offset_table_rtx;
rtx insn;
rtx mem;
/* NOTE: pic_offset_table_rtx can be NULL_RTX, because we can reach
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 == 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
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
{
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;
}
@ -955,6 +968,9 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
DImode if dest is dereferenced to access the memeory.
This is why we have to handle three different ldr_got_small
patterns here (two patterns for ILP32). */
rtx insn;
rtx mem;
rtx tmp_reg = 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 == DImode)
emit_insn (gen_ldr_got_small_di (dest, tmp_reg, imm));
insn = gen_ldr_got_small_di (dest, tmp_reg, imm);
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
{
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;
}

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>
* 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" } } */