diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2015-01-23 20:15:56 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2015-01-23 20:15:56 +0000 |
commit | 5c8bae594cdf2d3e215f95bc723921001d84f312 (patch) | |
tree | 451cc1f1d8cf2a23371918dfd5368bbda134ce06 /gcc | |
parent | 6c4d60f80aae979c4c317e5274babd404429f4cf (diff) | |
download | gcc-5c8bae594cdf2d3e215f95bc723921001d84f312.zip gcc-5c8bae594cdf2d3e215f95bc723921001d84f312.tar.gz gcc-5c8bae594cdf2d3e215f95bc723921001d84f312.tar.bz2 |
re PR rtl-optimization/64317 (Ineffective allocation of PIC base register)
2015-01-23 Vladimir Makarov <vmakarov@redhat.com>
PR target/64317
* lra-lives.c (make_hard_regno_born): Add parameter. Don't make
REAL_PIC_OFFSET_TABLE_REGNUM conflicting with pic offset pseudo.
(mark_regno_live, process_bb_lives): Pass new paramater value to
make_hard_regno_born.
2015-01-23 Vladimir Makarov <vmakarov@redhat.com>
PR target/64317
* gcc.target/i386/pr64317.c: New test.
From-SVN: r220060
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/lra-lives.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr64317.c | 24 |
4 files changed, 58 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 34e8ad1..57d08a8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-01-23 Vladimir Makarov <vmakarov@redhat.com> + + PR target/64317 + * lra-lives.c (make_hard_regno_born): Add parameter. Don't make + REAL_PIC_OFFSET_TABLE_REGNUM conflicting with pic offset pseudo. + (mark_regno_live, process_bb_lives): Pass new paramater value to + make_hard_regno_born. + 2015-01-23 Jakub Jelinek <jakub@redhat.com> PR rtl-optimization/63637 diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index 50d3969..9dfffb6 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -264,10 +264,12 @@ lra_intersected_live_ranges_p (lra_live_range_t r1, lra_live_range_t r2) } /* The function processing birth of hard register REGNO. It updates - living hard regs, conflict hard regs for living pseudos, and - START_LIVING. */ + living hard regs, START_LIVING, and conflict hard regs for living + pseudos. Conflict hard regs for the pic pseudo is not updated if + REGNO is REAL_PIC_OFFSET_TABLE_REGNUM and CHECK_PIC_PSEUDO_P is + true. */ static void -make_hard_regno_born (int regno) +make_hard_regno_born (int regno, bool check_pic_pseudo_p ATTRIBUTE_UNUSED) { unsigned int i; @@ -277,7 +279,13 @@ make_hard_regno_born (int regno) SET_HARD_REG_BIT (hard_regs_live, regno); sparseset_set_bit (start_living, regno); EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i) - SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno); +#ifdef REAL_PIC_OFFSET_TABLE_REGNUM + if (! check_pic_pseudo_p + || regno != REAL_PIC_OFFSET_TABLE_REGNUM + || pic_offset_table_rtx == NULL + || i != REGNO (pic_offset_table_rtx)) +#endif + SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno); } /* Process the death of hard register REGNO. This updates @@ -352,7 +360,7 @@ mark_regno_live (int regno, machine_mode mode, int point) for (last = regno + hard_regno_nregs[regno][mode]; regno < last; regno++) - make_hard_regno_born (regno); + make_hard_regno_born (regno, false); } else { @@ -833,7 +841,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type != OP_IN) - make_hard_regno_born (reg->regno); + make_hard_regno_born (reg->regno, false); sparseset_copy (unused_set, start_living); @@ -892,12 +900,13 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type == OP_IN) - make_hard_regno_born (reg->regno); + make_hard_regno_born (reg->regno, false); if (curr_id->arg_hard_regs != NULL) - /* Make argument hard registers live. */ + /* Make argument hard registers live. Don't create conflict + of used REAL_PIC_OFFSET_TABLE_REGNUM and the pic pseudo. */ for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) - make_hard_regno_born (regno); + make_hard_regno_born (regno, true); sparseset_and_compl (dead_set, start_living, start_dying); @@ -953,7 +962,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) if (regno == INVALID_REGNUM) break; - make_hard_regno_born (regno); + make_hard_regno_born (regno, false); } #endif @@ -968,7 +977,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, px) lra_reg_info[px].no_stack_p = true; for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++) - make_hard_regno_born (px); + make_hard_regno_born (px, false); #endif /* No need to record conflicts for call clobbered regs if we have nonlocal labels around, as we don't ever try to @@ -976,7 +985,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) if (!cfun->has_nonlocal_label && bb_has_abnormal_call_pred (bb)) for (px = 0; px < FIRST_PSEUDO_REGISTER; px++) if (call_used_regs[px]) - make_hard_regno_born (px); + make_hard_regno_born (px, false); } bool live_change_p = false; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 39a1741..ef497e4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-01-23 Vladimir Makarov <vmakarov@redhat.com> + + PR target/64317 + * gcc.target/i386/pr64317.c: New test. + 2015-01-23 Jakub Jelinek <jakub@redhat.com> PR rtl-optimization/63637 diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c new file mode 100644 index 0000000..46c3c6f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr64317.c @@ -0,0 +1,24 @@ +/* { dg-do compile { target { ia32 } } } */ +/* { dg-options "-O2 -fPIE -pie" } */ +/* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */ +/* { dg-final { scan-assembler "movl\[ \\t\]+c@GOT\[(\]%ebx\[)\]" } } */ +/* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */ +long c; + +int bar(); + +int foo (unsigned int iters) +{ + unsigned int i; + + int res = 0; + static long t1; + + for (i = 0; i < iters; i++) + { + res = bar(); + t1 = c + res; + } + + return t1 + res; +} |