Commit 5c8bae59 by Vladimir Makarov Committed by Vladimir Makarov

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
parent 6c4d60f8
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> 2015-01-23 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/63637 PR rtl-optimization/63637
......
...@@ -264,10 +264,12 @@ lra_intersected_live_ranges_p (lra_live_range_t r1, lra_live_range_t r2) ...@@ -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 /* The function processing birth of hard register REGNO. It updates
living hard regs, conflict hard regs for living pseudos, and living hard regs, START_LIVING, and conflict hard regs for living
START_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 static void
make_hard_regno_born (int regno) make_hard_regno_born (int regno, bool check_pic_pseudo_p ATTRIBUTE_UNUSED)
{ {
unsigned int i; unsigned int i;
...@@ -277,7 +279,13 @@ make_hard_regno_born (int regno) ...@@ -277,7 +279,13 @@ make_hard_regno_born (int regno)
SET_HARD_REG_BIT (hard_regs_live, regno); SET_HARD_REG_BIT (hard_regs_live, regno);
sparseset_set_bit (start_living, regno); sparseset_set_bit (start_living, regno);
EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i) 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 /* Process the death of hard register REGNO. This updates
...@@ -352,7 +360,7 @@ mark_regno_live (int regno, machine_mode mode, int point) ...@@ -352,7 +360,7 @@ mark_regno_live (int regno, machine_mode mode, int point)
for (last = regno + hard_regno_nregs[regno][mode]; for (last = regno + hard_regno_nregs[regno][mode];
regno < last; regno < last;
regno++) regno++)
make_hard_regno_born (regno); make_hard_regno_born (regno, false);
} }
else else
{ {
...@@ -833,7 +841,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) ...@@ -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) for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
if (reg->type != OP_IN) if (reg->type != OP_IN)
make_hard_regno_born (reg->regno); make_hard_regno_born (reg->regno, false);
sparseset_copy (unused_set, start_living); sparseset_copy (unused_set, start_living);
...@@ -892,12 +900,13 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) ...@@ -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) for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
if (reg->type == OP_IN) 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) 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++) 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); 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) ...@@ -953,7 +962,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
if (regno == INVALID_REGNUM) if (regno == INVALID_REGNUM)
break; break;
make_hard_regno_born (regno); make_hard_regno_born (regno, false);
} }
#endif #endif
...@@ -968,7 +977,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) ...@@ -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) EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, px)
lra_reg_info[px].no_stack_p = true; lra_reg_info[px].no_stack_p = true;
for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++) for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++)
make_hard_regno_born (px); make_hard_regno_born (px, false);
#endif #endif
/* No need to record conflicts for call clobbered regs if we /* No need to record conflicts for call clobbered regs if we
have nonlocal labels around, as we don't ever try to 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) ...@@ -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)) if (!cfun->has_nonlocal_label && bb_has_abnormal_call_pred (bb))
for (px = 0; px < FIRST_PSEUDO_REGISTER; px++) for (px = 0; px < FIRST_PSEUDO_REGISTER; px++)
if (call_used_regs[px]) if (call_used_regs[px])
make_hard_regno_born (px); make_hard_regno_born (px, false);
} }
bool live_change_p = false; bool live_change_p = false;
......
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> 2015-01-23 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/63637 PR rtl-optimization/63637
......
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment