Commit 6080348f by Vladimir Makarov Committed by Vladimir Makarov

re PR rtl-optimization/39762 (IRA ICE with -msoft-float)

2009-04-16  Vladimir Makarov  <vmakarov@redhat.com>

	PR rtl-optimization/39762
	* ira-int.h (ira_register_move_cost, ira_may_move_in_cost,
	ira_may_move_out_cost): Add comments about way of their usage.
	(ira_get_register_move_cost, ira_get_may_move_cost): New
	functions.
	
	* ira-conflicts.c (process_regs_for_copy): Use function
	ira_get_register_move_cost instead of global
	ira_register_move_cost.

	* ira-color.c (update_copy_costs, calculate_allocno_spill_cost,
	color_pass, move_spill_restore, update_curr_costs): Ditto.

	* ira-lives.c (process_single_reg_class_operands): Ditto.

	* ira-emit.c (emit_move_list): Ditto.

	* ira-costs.c (copy_cost): Don't call ira_init_register_move_cost.
	(record_reg_classes): Ditto.  Use functions
	ira_get_register_move_cost and ira_get_may_move_cost instead of
	global vars ira_register_move_cost, ira_may_move_out_cost and
	ira_may_move_in_cost.
	(record_address_regs): Don't call ira_init_register_move_cost.
	Use function ira_get_may_move_cost instead of global
	ira_may_move_in_cost.
	(process_bb_node_for_hard_reg_moves): Use function
	ira_get_register_move_cost instead of global
	ira_register_move_cost.
	(ira_costs): Don't call ira_init_register_move_cost.

From-SVN: r146198
parent 646bea10
2009-04-16 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/39762
* ira-int.h (ira_register_move_cost, ira_may_move_in_cost,
ira_may_move_out_cost): Add comments about way of their usage.
(ira_get_register_move_cost, ira_get_may_move_cost): New
functions.
* ira-conflicts.c (process_regs_for_copy): Use function
ira_get_register_move_cost instead of global
ira_register_move_cost.
* ira-color.c (update_copy_costs, calculate_allocno_spill_cost,
color_pass, move_spill_restore, update_curr_costs): Ditto.
* ira-lives.c (process_single_reg_class_operands): Ditto.
* ira-emit.c (emit_move_list): Ditto.
* ira-costs.c (copy_cost): Don't call ira_init_register_move_cost.
(record_reg_classes): Ditto. Use functions
ira_get_register_move_cost and ira_get_may_move_cost instead of
global vars ira_register_move_cost, ira_may_move_out_cost and
ira_may_move_in_cost.
(record_address_regs): Don't call ira_init_register_move_cost.
Use function ira_get_may_move_cost instead of global
ira_may_move_in_cost.
(process_bb_node_for_hard_reg_moves): Use function
ira_get_register_move_cost instead of global
ira_register_move_cost.
(ira_costs): Don't call ira_init_register_move_cost.
2009-04-16 Richard Guenther <rguenther@suse.de> 2009-04-16 Richard Guenther <rguenther@suse.de>
* tree-cfg.c (verify_gimple_assign_binary): * tree-cfg.c (verify_gimple_assign_binary):
......
...@@ -285,8 +285,8 @@ update_copy_costs (ira_allocno_t allocno, bool decr_p) ...@@ -285,8 +285,8 @@ update_copy_costs (ira_allocno_t allocno, bool decr_p)
continue; continue;
cost = (cp->second == allocno cost = (cp->second == allocno
? ira_register_move_cost[mode][rclass][cover_class] ? ira_get_register_move_cost (mode, rclass, cover_class)
: ira_register_move_cost[mode][cover_class][rclass]); : ira_get_register_move_cost (mode, cover_class, rclass));
if (decr_p) if (decr_p)
cost = -cost; cost = -cost;
...@@ -1071,7 +1071,7 @@ calculate_allocno_spill_cost (ira_allocno_t a) ...@@ -1071,7 +1071,7 @@ calculate_allocno_spill_cost (ira_allocno_t a)
* ira_loop_edge_freq (loop_node, regno, true) * ira_loop_edge_freq (loop_node, regno, true)
+ ira_memory_move_cost[mode][rclass][0] + ira_memory_move_cost[mode][rclass][0]
* ira_loop_edge_freq (loop_node, regno, false)) * ira_loop_edge_freq (loop_node, regno, false))
- (ira_register_move_cost[mode][rclass][rclass] - (ira_get_register_move_cost (mode, rclass, rclass)
* (ira_loop_edge_freq (loop_node, regno, false) * (ira_loop_edge_freq (loop_node, regno, false)
+ ira_loop_edge_freq (loop_node, regno, true)))); + ira_loop_edge_freq (loop_node, regno, true))));
return cost; return cost;
...@@ -2039,7 +2039,7 @@ color_pass (ira_loop_tree_node_t loop_tree_node) ...@@ -2039,7 +2039,7 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
else else
{ {
cover_class = ALLOCNO_COVER_CLASS (subloop_allocno); cover_class = ALLOCNO_COVER_CLASS (subloop_allocno);
cost = (ira_register_move_cost[mode][rclass][rclass] cost = (ira_get_register_move_cost (mode, rclass, rclass)
* (exit_freq + enter_freq)); * (exit_freq + enter_freq));
ira_allocate_and_set_or_copy_costs ira_allocate_and_set_or_copy_costs
(&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), cover_class, (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), cover_class,
...@@ -2164,7 +2164,7 @@ move_spill_restore (void) ...@@ -2164,7 +2164,7 @@ move_spill_restore (void)
+= (ira_memory_move_cost[mode][rclass][0] * exit_freq += (ira_memory_move_cost[mode][rclass][0] * exit_freq
+ ira_memory_move_cost[mode][rclass][1] * enter_freq); + ira_memory_move_cost[mode][rclass][1] * enter_freq);
if (hard_regno2 != hard_regno) if (hard_regno2 != hard_regno)
cost -= (ira_register_move_cost[mode][rclass][rclass] cost -= (ira_get_register_move_cost (mode, rclass, rclass)
* (exit_freq + enter_freq)); * (exit_freq + enter_freq));
} }
} }
...@@ -2183,7 +2183,7 @@ move_spill_restore (void) ...@@ -2183,7 +2183,7 @@ move_spill_restore (void)
+= (ira_memory_move_cost[mode][rclass][1] * exit_freq += (ira_memory_move_cost[mode][rclass][1] * exit_freq
+ ira_memory_move_cost[mode][rclass][0] * enter_freq); + ira_memory_move_cost[mode][rclass][0] * enter_freq);
if (hard_regno2 != hard_regno) if (hard_regno2 != hard_regno)
cost -= (ira_register_move_cost[mode][rclass][rclass] cost -= (ira_get_register_move_cost (mode, rclass, rclass)
* (exit_freq + enter_freq)); * (exit_freq + enter_freq));
} }
} }
...@@ -2249,8 +2249,8 @@ update_curr_costs (ira_allocno_t a) ...@@ -2249,8 +2249,8 @@ update_curr_costs (ira_allocno_t a)
if (i < 0) if (i < 0)
continue; continue;
cost = (cp->first == a cost = (cp->first == a
? ira_register_move_cost[mode][rclass][cover_class] ? ira_get_register_move_cost (mode, rclass, cover_class)
: ira_register_move_cost[mode][cover_class][rclass]); : ira_get_register_move_cost (mode, cover_class, rclass));
ira_allocate_and_set_or_copy_costs ira_allocate_and_set_or_copy_costs
(&ALLOCNO_UPDATED_HARD_REG_COSTS (a), (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
cover_class, ALLOCNO_COVER_CLASS_COST (a), cover_class, ALLOCNO_COVER_CLASS_COST (a),
......
...@@ -411,9 +411,9 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p, ...@@ -411,9 +411,9 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
/* Can not be tied. It is not in the cover class. */ /* Can not be tied. It is not in the cover class. */
return false; return false;
if (HARD_REGISTER_P (reg1)) if (HARD_REGISTER_P (reg1))
cost = ira_register_move_cost[mode][cover_class][rclass] * freq; cost = ira_get_register_move_cost (mode, cover_class, rclass) * freq;
else else
cost = ira_register_move_cost[mode][rclass][cover_class] * freq; cost = ira_get_register_move_cost (mode, rclass, cover_class) * freq;
for (;;) for (;;)
{ {
ira_allocate_and_set_costs ira_allocate_and_set_costs
......
...@@ -138,9 +138,6 @@ copy_cost (rtx x, enum machine_mode mode, enum reg_class rclass, bool to_p, ...@@ -138,9 +138,6 @@ copy_cost (rtx x, enum machine_mode mode, enum reg_class rclass, bool to_p,
sri.extra_cost = 0; sri.extra_cost = 0;
secondary_class = targetm.secondary_reload (to_p, x, rclass, mode, &sri); secondary_class = targetm.secondary_reload (to_p, x, rclass, mode, &sri);
if (ira_register_move_cost[mode] == NULL)
ira_init_register_move_cost (mode);
if (secondary_class != NO_REGS) if (secondary_class != NO_REGS)
{ {
if (!move_cost[mode]) if (!move_cost[mode])
...@@ -294,19 +291,17 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, ...@@ -294,19 +291,17 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
needs to do a copy, which is one insn. */ needs to do a copy, which is one insn. */
struct costs *pp = this_op_costs[i]; struct costs *pp = this_op_costs[i];
if (ira_register_move_cost[mode] == NULL)
ira_init_register_move_cost (mode);
for (k = 0; k < cost_classes_num; k++) for (k = 0; k < cost_classes_num; k++)
{ {
rclass = cost_classes[k]; rclass = cost_classes[k];
pp->cost[k] pp->cost[k]
= ((recog_data.operand_type[i] != OP_OUT = (((recog_data.operand_type[i] != OP_OUT
? ira_may_move_in_cost[mode][rclass] ? ira_get_may_move_cost (mode, rclass,
[classes[i]] * frequency : 0) classes[i], true) : 0)
+ (recog_data.operand_type[i] != OP_IN + (recog_data.operand_type[i] != OP_IN
? ira_may_move_out_cost[mode][classes[i]] ? ira_get_may_move_cost (mode, classes[i],
[rclass] * frequency : 0)); rclass, false) : 0))
* frequency);
} }
/* If the alternative actually allows memory, make /* If the alternative actually allows memory, make
...@@ -342,8 +337,9 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, ...@@ -342,8 +337,9 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
: 0)); : 0));
else if (ira_reg_class_intersect else if (ira_reg_class_intersect
[pref_class][classes[i]] == NO_REGS) [pref_class][classes[i]] == NO_REGS)
alt_cost += (ira_register_move_cost alt_cost += ira_get_register_move_cost (mode,
[mode][pref_class][classes[i]]); pref_class,
classes[i]);
} }
if (REGNO (ops[i]) != REGNO (ops[j]) if (REGNO (ops[i]) != REGNO (ops[j])
&& ! find_reg_note (insn, REG_DEAD, op)) && ! find_reg_note (insn, REG_DEAD, op))
...@@ -540,19 +536,17 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, ...@@ -540,19 +536,17 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
{ {
struct costs *pp = this_op_costs[i]; struct costs *pp = this_op_costs[i];
if (ira_register_move_cost[mode] == NULL)
ira_init_register_move_cost (mode);
for (k = 0; k < cost_classes_num; k++) for (k = 0; k < cost_classes_num; k++)
{ {
rclass = cost_classes[k]; rclass = cost_classes[k];
pp->cost[k] pp->cost[k]
= ((recog_data.operand_type[i] != OP_OUT = (((recog_data.operand_type[i] != OP_OUT
? ira_may_move_in_cost[mode][rclass] ? ira_get_may_move_cost (mode, rclass,
[classes[i]] * frequency : 0) classes[i], true) : 0)
+ (recog_data.operand_type[i] != OP_IN + (recog_data.operand_type[i] != OP_IN
? ira_may_move_out_cost[mode][classes[i]] ? ira_get_may_move_cost (mode, classes[i],
[rclass] * frequency : 0)); rclass, false) : 0))
* frequency);
} }
/* If the alternative actually allows memory, make /* If the alternative actually allows memory, make
...@@ -587,8 +581,9 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, ...@@ -587,8 +581,9 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
: 0)); : 0));
else if (ira_reg_class_intersect[pref_class][classes[i]] else if (ira_reg_class_intersect[pref_class][classes[i]]
== NO_REGS) == NO_REGS)
alt_cost += (ira_register_move_cost alt_cost += ira_get_register_move_cost (mode,
[mode][pref_class][classes[i]]); pref_class,
classes[i]);
} }
} }
} }
...@@ -901,13 +896,11 @@ record_address_regs (enum machine_mode mode, rtx x, int context, ...@@ -901,13 +896,11 @@ record_address_regs (enum machine_mode mode, rtx x, int context,
ALLOCNO_NUM (ira_curr_regno_allocno_map ALLOCNO_NUM (ira_curr_regno_allocno_map
[REGNO (x)])); [REGNO (x)]));
pp->mem_cost += (ira_memory_move_cost[Pmode][rclass][1] * scale) / 2; pp->mem_cost += (ira_memory_move_cost[Pmode][rclass][1] * scale) / 2;
if (ira_register_move_cost[Pmode] == NULL)
ira_init_register_move_cost (Pmode);
for (k = 0; k < cost_classes_num; k++) for (k = 0; k < cost_classes_num; k++)
{ {
i = cost_classes[k]; i = cost_classes[k];
pp->cost[k] pp->cost[k]
+= (ira_may_move_in_cost[Pmode][i][rclass] * scale) / 2; += (ira_get_may_move_cost (Pmode, i, rclass, true) * scale) / 2;
} }
} }
break; break;
...@@ -1425,8 +1418,9 @@ process_bb_node_for_hard_reg_moves (ira_loop_tree_node_t loop_tree_node) ...@@ -1425,8 +1418,9 @@ process_bb_node_for_hard_reg_moves (ira_loop_tree_node_t loop_tree_node)
continue; continue;
mode = ALLOCNO_MODE (a); mode = ALLOCNO_MODE (a);
hard_reg_class = REGNO_REG_CLASS (hard_regno); hard_reg_class = REGNO_REG_CLASS (hard_regno);
cost = (to_p ? ira_register_move_cost[mode][hard_reg_class][rclass] cost
: ira_register_move_cost[mode][rclass][hard_reg_class]) * freq; = (to_p ? ira_get_register_move_cost (mode, hard_reg_class, rclass)
: ira_get_register_move_cost (mode, rclass, hard_reg_class)) * freq;
ira_allocate_and_set_costs (&ALLOCNO_HARD_REG_COSTS (a), rclass, ira_allocate_and_set_costs (&ALLOCNO_HARD_REG_COSTS (a), rclass,
ALLOCNO_COVER_CLASS_COST (a)); ALLOCNO_COVER_CLASS_COST (a));
ira_allocate_and_set_costs (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), ira_allocate_and_set_costs (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a),
...@@ -1579,9 +1573,6 @@ ira_finish_costs_once (void) ...@@ -1579,9 +1573,6 @@ ira_finish_costs_once (void)
void void
ira_costs (void) ira_costs (void)
{ {
ira_allocno_t a;
ira_allocno_iterator ai;
allocno_costs = (struct costs *) ira_allocate (max_struct_costs_size allocno_costs = (struct costs *) ira_allocate (max_struct_costs_size
* ira_allocnos_num); * ira_allocnos_num);
total_costs = (struct costs *) ira_allocate (max_struct_costs_size total_costs = (struct costs *) ira_allocate (max_struct_costs_size
...@@ -1594,12 +1585,6 @@ ira_costs (void) ...@@ -1594,12 +1585,6 @@ ira_costs (void)
* max_reg_num ()); * max_reg_num ());
find_allocno_class_costs (); find_allocno_class_costs ();
setup_allocno_cover_class_and_costs (); setup_allocno_cover_class_and_costs ();
/* Because we could process operands only as subregs, check mode of
the registers themselves too. */
FOR_EACH_ALLOCNO (a, ai)
if (ira_register_move_cost[ALLOCNO_MODE (a)] == NULL
&& have_regs_of_mode[ALLOCNO_MODE (a)])
ira_init_register_move_cost (ALLOCNO_MODE (a));
ira_free (common_classes); ira_free (common_classes);
ira_free (allocno_pref_buffer); ira_free (allocno_pref_buffer);
ira_free (total_costs); ira_free (total_costs);
......
...@@ -812,7 +812,8 @@ emit_move_list (move_t list, int freq) ...@@ -812,7 +812,8 @@ emit_move_list (move_t list, int freq)
} }
else else
{ {
cost = ira_register_move_cost[mode][cover_class][cover_class] * freq; cost = (ira_get_register_move_cost (mode, cover_class, cover_class)
* freq);
ira_shuffle_cost += cost; ira_shuffle_cost += cost;
} }
ira_overall_cost += cost; ira_overall_cost += cost;
......
...@@ -730,21 +730,24 @@ ira_allocno_set_iter_next (ira_allocno_set_iterator *i) ...@@ -730,21 +730,24 @@ ira_allocno_set_iter_next (ira_allocno_set_iterator *i)
extern HARD_REG_SET ira_reg_mode_hard_regset extern HARD_REG_SET ira_reg_mode_hard_regset
[FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES]; [FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES];
/* Arrays analogous to macros MEMORY_MOVE_COST and /* Arrays analogous to macros MEMORY_MOVE_COST and REGISTER_MOVE_COST.
REGISTER_MOVE_COST. */ Don't use ira_register_move_cost directly. Use function of
ira_get_may_move_cost instead. */
extern short ira_memory_move_cost[MAX_MACHINE_MODE][N_REG_CLASSES][2]; extern short ira_memory_move_cost[MAX_MACHINE_MODE][N_REG_CLASSES][2];
extern move_table *ira_register_move_cost[MAX_MACHINE_MODE]; extern move_table *ira_register_move_cost[MAX_MACHINE_MODE];
/* Similar to may_move_in_cost but it is calculated in IRA instead of /* Similar to may_move_in_cost but it is calculated in IRA instead of
regclass. Another difference we take only available hard registers regclass. Another difference we take only available hard registers
into account to figure out that one register class is a subset of into account to figure out that one register class is a subset of
the another one. */ the another one. Don't use it directly. Use function of
ira_get_may_move_cost instead. */
extern move_table *ira_may_move_in_cost[MAX_MACHINE_MODE]; extern move_table *ira_may_move_in_cost[MAX_MACHINE_MODE];
/* Similar to may_move_out_cost but it is calculated in IRA instead of /* Similar to may_move_out_cost but it is calculated in IRA instead of
regclass. Another difference we take only available hard registers regclass. Another difference we take only available hard registers
into account to figure out that one register class is a subset of into account to figure out that one register class is a subset of
the another one. */ the another one. Don't use it directly. Use function of
ira_get_may_move_cost instead. */
extern move_table *ira_may_move_out_cost[MAX_MACHINE_MODE]; extern move_table *ira_may_move_out_cost[MAX_MACHINE_MODE];
/* Register class subset relation: TRUE if the first class is a subset /* Register class subset relation: TRUE if the first class is a subset
...@@ -941,6 +944,34 @@ extern void ira_emit (bool); ...@@ -941,6 +944,34 @@ extern void ira_emit (bool);
/* Return cost of moving value of MODE from register of class FROM to
register of class TO. */
static inline int
ira_get_register_move_cost (enum machine_mode mode,
enum reg_class from, enum reg_class to)
{
if (ira_register_move_cost[mode] == NULL)
ira_init_register_move_cost (mode);
return ira_register_move_cost[mode][from][to];
}
/* Return cost of moving value of MODE from register of class FROM to
register of class TO. Return zero if IN_P is true and FROM is
subset of TO or if IN_P is false and FROM is superset of TO. */
static inline int
ira_get_may_move_cost (enum machine_mode mode,
enum reg_class from, enum reg_class to,
bool in_p)
{
if (ira_register_move_cost[mode] == NULL)
ira_init_register_move_cost (mode);
return (in_p
? ira_may_move_in_cost[mode][from][to]
: ira_may_move_out_cost[mode][from][to]);
}
/* The iterator for all allocnos. */ /* The iterator for all allocnos. */
typedef struct { typedef struct {
/* The number of the current element in IRA_ALLOCNOS. */ /* The number of the current element in IRA_ALLOCNOS. */
......
...@@ -782,10 +782,11 @@ process_single_reg_class_operands (bool in_p, int freq) ...@@ -782,10 +782,11 @@ process_single_reg_class_operands (bool in_p, int freq)
[ira_class_hard_regs[cl][0]]) >= 0 [ira_class_hard_regs[cl][0]]) >= 0
&& reg_class_size[cl] <= (unsigned) CLASS_MAX_NREGS (cl, mode)) && reg_class_size[cl] <= (unsigned) CLASS_MAX_NREGS (cl, mode))
{ {
/* ??? FREQ */ cost
cost = freq * (in_p = (freq
? ira_register_move_cost[mode][cover_class][cl] * (in_p
: ira_register_move_cost[mode][cl][cover_class]); ? ira_get_register_move_cost (mode, cover_class, cl)
: ira_get_register_move_cost (mode, cl, cover_class)));
ira_allocate_and_set_costs ira_allocate_and_set_costs
(&ALLOCNO_CONFLICT_HARD_REG_COSTS (operand_a), cover_class, 0); (&ALLOCNO_CONFLICT_HARD_REG_COSTS (operand_a), cover_class, 0);
ALLOCNO_CONFLICT_HARD_REG_COSTS (operand_a) ALLOCNO_CONFLICT_HARD_REG_COSTS (operand_a)
......
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