From 5c8bae594cdf2d3e215f95bc723921001d84f312 Mon Sep 17 00:00:00 2001 From: Vladimir Makarov Date: Fri, 23 Jan 2015 20:15:56 +0000 Subject: [PATCH] re PR rtl-optimization/64317 (Ineffective allocation of PIC base register) 2015-01-23 Vladimir Makarov 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 PR target/64317 * gcc.target/i386/pr64317.c: New test. From-SVN: r220060 --- gcc/ChangeLog | 8 ++++++++ gcc/lra-lives.c | 33 +++++++++++++++++++++------------ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/i386/pr64317.c | 24 ++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr64317.c 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 + + 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 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 + + PR target/64317 + * gcc.target/i386/pr64317.c: New test. + 2015-01-23 Jakub Jelinek 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; +} -- 2.7.4