Commit 36d070a7 by Vladimir Makarov Committed by Vladimir Makarov

re PR target/88282 (ICE in df_install_refs at gcc/df-scan.c:2379)

2018-12-04  Vladimir Makarov  <vmakarov@redhat.com>

	PR target/88282
	* ira-costs.c (exec): Try bigger class to use smaller register
	move cost.

From-SVN: r266784
parent 8f80bd89
2018-12-04 Vladimir Makarov <vmakarov@redhat.com>
PR target/88282
* ira-costs.c (exec): Try bigger class to use smaller register
move cost.
2018-12-04 Michael Ploujnikov <michael.ploujnikov@oracle.com> 2018-12-04 Michael Ploujnikov <michael.ploujnikov@oracle.com>
PR ipa/88297 PR ipa/88297
...@@ -1314,28 +1314,50 @@ record_operand_costs (rtx_insn *insn, enum reg_class *pref) ...@@ -1314,28 +1314,50 @@ record_operand_costs (rtx_insn *insn, enum reg_class *pref)
machine_mode mode = GET_MODE (SET_SRC (set)); machine_mode mode = GET_MODE (SET_SRC (set));
cost_classes_t cost_classes_ptr = regno_cost_classes[regno]; cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
enum reg_class *cost_classes = cost_classes_ptr->classes; enum reg_class *cost_classes = cost_classes_ptr->classes;
reg_class_t rclass, hard_reg_class, pref_class; reg_class_t rclass, hard_reg_class, pref_class, bigger_hard_reg_class;
int cost, k; int cost, k;
move_table *move_costs;
bool dead_p = find_regno_note (insn, REG_DEAD, REGNO (src)); bool dead_p = find_regno_note (insn, REG_DEAD, REGNO (src));
ira_init_register_move_cost_if_necessary (mode); ira_init_register_move_cost_if_necessary (mode);
move_costs = ira_register_move_cost[mode];
hard_reg_class = REGNO_REG_CLASS (other_regno); hard_reg_class = REGNO_REG_CLASS (other_regno);
bigger_hard_reg_class = ira_pressure_class_translate[hard_reg_class];
if (bigger_hard_reg_class == NO_REGS
&& (other_regno == STACK_POINTER_REGNUM
#ifdef STATIC_CHAIN_REGNUM
|| other_regno == STATIC_CHAIN_REGNUM
#endif
|| other_regno == FRAME_POINTER_REGNUM
|| other_regno == HARD_FRAME_POINTER_REGNUM))
bigger_hard_reg_class = GENERAL_REGS;
/* Target code may return any cost for mode which does not /* Target code may return any cost for mode which does not
fit the the hard reg class (e.g. DImode for AREG on fit the the hard reg class (e.g. DImode for AREG on
i386). Check this and use a bigger class to get the i386). Check this and use a bigger class to get the
right cost. */ right cost. */
if (! ira_hard_reg_in_set_p (other_regno, mode, if (! ira_hard_reg_in_set_p (other_regno, mode,
reg_class_contents[hard_reg_class])) reg_class_contents[hard_reg_class]))
hard_reg_class = ira_pressure_class_translate[hard_reg_class]; hard_reg_class = bigger_hard_reg_class;
i = regno == (int) REGNO (src) ? 1 : 0; i = regno == (int) REGNO (src) ? 1 : 0;
for (k = cost_classes_ptr->num - 1; k >= 0; k--) for (k = cost_classes_ptr->num - 1; k >= 0; k--)
{ {
rclass = cost_classes[k]; rclass = cost_classes[k];
cost = ((i == 0 cost = (i == 0
? ira_register_move_cost[mode][hard_reg_class][rclass] ? move_costs[hard_reg_class][rclass]
: ira_register_move_cost[mode][rclass][hard_reg_class]) : move_costs[rclass][hard_reg_class]);
* frequency); /* Target code might define wrong big costs for smaller
op_costs[i]->cost[k] = cost; reg classes or reg classes containing only fixed hard
regs. Try a bigger class. */
if (bigger_hard_reg_class != hard_reg_class)
{
int cost2 = (i == 0
? move_costs[bigger_hard_reg_class][rclass]
: move_costs[rclass][bigger_hard_reg_class]);
if (cost2 < cost)
cost = cost2;
}
op_costs[i]->cost[k] = cost * frequency;
/* If we have assigned a class to this allocno in our /* If we have assigned a class to this allocno in our
first pass, add a cost to this alternative first pass, add a cost to this alternative
corresponding to what we would add if this allocno corresponding to what we would add if this allocno
...@@ -1350,7 +1372,7 @@ record_operand_costs (rtx_insn *insn, enum reg_class *pref) ...@@ -1350,7 +1372,7 @@ record_operand_costs (rtx_insn *insn, enum reg_class *pref)
else if (ira_reg_class_intersect[pref_class][rclass] else if (ira_reg_class_intersect[pref_class][rclass]
== NO_REGS) == NO_REGS)
op_costs[i]->cost[k] op_costs[i]->cost[k]
+= (ira_register_move_cost[mode][pref_class][rclass] += (move_costs[pref_class][rclass]
* frequency); * frequency);
} }
/* If this insn is a single set copying operand 1 to /* If this insn is a single set copying operand 1 to
......
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