diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 56cbc5f5040..643b4f5bff5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2015-07-10 Jiong Wang + + * config/aarch64/aarch64.c (aarch64_load_symref_appropriately): Mark mem + as READONLY and NOTRAP for PIC symbol. + 2015-07-10 Andrew MacLeod * gimple-predict.h: New file. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index f382591dcd9..37f42facb26 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 8eab126a712..cc7988b12df 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-07-10 Jiong Wang + + * gcc.target/aarch64/got_mem_hoist_1.c: New test. + 2015-07-10 Christophe Lyon * 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 00000000000..6d2971872b2 --- /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" } } */