aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiong Wang <jiong.wang@arm.com>2015-07-10 12:20:54 +0000
committerJiong Wang <jiwang@gcc.gnu.org>2015-07-10 12:20:54 +0000
commit53021678c582ec1afd38f0ed03fde6c433d639df (patch)
tree142087cbadbd7533a8e1d71109873929f13e6f5c
parent9fdcd34e0fc48867dfc4d00dad09bdcbb4562db1 (diff)
downloadgcc-53021678c582ec1afd38f0ed03fde6c433d639df.zip
gcc-53021678c582ec1afd38f0ed03fde6c433d639df.tar.gz
gcc-53021678c582ec1afd38f0ed03fde6c433d639df.tar.bz2
[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
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/aarch64/aarch64.c36
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/got_mem_hoist_1.c21
4 files changed, 60 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 56cbc5f..643b4f5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index f382591..37f42fa 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8eab126..cc7988b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.target/aarch64/got_mem_hoist_1.c b/gcc/testsuite/gcc.target/aarch64/got_mem_hoist_1.c
new file mode 100644
index 0000000..6d29718
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/got_mem_hoist_1.c
@@ -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" } } */