/* IRA hard register and memory cost calculation for allocnos.
- Copyright (C) 2006, 2007, 2008
+ Copyright (C) 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
Contributed by Vladimir Makarov <vmakarov@redhat.com>.
/* Allocated buffers for allocno_pref. */
static enum reg_class *allocno_pref_buffer;
+/* Record register class of each allocno with the same regno. */
+static enum reg_class *common_classes;
+
/* Execution frequency of the current insn. */
static int frequency;
sri.extra_cost = 0;
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)
- return (move_cost[mode][secondary_class][rclass] + sri.extra_cost
- + copy_cost (x, mode, secondary_class, to_p, &sri));
+ {
+ if (!move_cost[mode])
+ init_move_cost (mode);
+ return (move_cost[mode][secondary_class][rclass] + sri.extra_cost
+ + copy_cost (x, mode, secondary_class, to_p, &sri));
+ }
/* For memory, use the memory move cost, for (hard) registers, use
the cost to move between the register classes, and use 2 for
if (MEM_P (x) || rclass == NO_REGS)
return sri.extra_cost + ira_memory_move_cost[mode][rclass][to_p != 0];
else if (REG_P (x))
- return
- (sri.extra_cost + move_cost[mode][REGNO_REG_CLASS (REGNO (x))][rclass]);
+ {
+ if (!move_cost[mode])
+ init_move_cost (mode);
+ return (sri.extra_cost + move_cost[mode][REGNO_REG_CLASS (REGNO (x))][rclass]);
+ }
else
/* If this is a constant, we may eventually want to call rtx_cost
here. */
{
enum reg_class classes[MAX_RECOG_OPERANDS];
int allows_mem[MAX_RECOG_OPERANDS];
- int rclass;
+ enum reg_class rclass;
int alt_fail = 0;
int alt_cost = 0, op_cost_add;
needs to do a copy, which is one insn. */
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++)
{
rclass = cost_classes[k];
pp->cost[k]
- = ((recog_data.operand_type[i] != OP_OUT
- ? ira_may_move_in_cost[mode][rclass]
- [classes[i]] * frequency : 0)
- + (recog_data.operand_type[i] != OP_IN
- ? ira_may_move_out_cost[mode][classes[i]]
- [rclass] * frequency : 0));
+ = (((recog_data.operand_type[i] != OP_OUT
+ ? ira_get_may_move_cost (mode, rclass,
+ classes[i], true) : 0)
+ + (recog_data.operand_type[i] != OP_IN
+ ? ira_get_may_move_cost (mode, classes[i],
+ rclass, false) : 0))
+ * frequency);
}
/* If the alternative actually allows memory, make
: 0));
else if (ira_reg_class_intersect
[pref_class][classes[i]] == NO_REGS)
- alt_cost += (ira_register_move_cost
- [mode][pref_class][classes[i]]);
+ alt_cost += ira_get_register_move_cost (mode,
+ pref_class,
+ classes[i]);
}
if (REGNO (ops[i]) != REGNO (ops[j])
&& ! find_reg_note (insn, REG_DEAD, op))
{
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++)
{
rclass = cost_classes[k];
pp->cost[k]
- = ((recog_data.operand_type[i] != OP_OUT
- ? ira_may_move_in_cost[mode][rclass]
- [classes[i]] * frequency : 0)
- + (recog_data.operand_type[i] != OP_IN
- ? ira_may_move_out_cost[mode][classes[i]]
- [rclass] * frequency : 0));
+ = (((recog_data.operand_type[i] != OP_OUT
+ ? ira_get_may_move_cost (mode, rclass,
+ classes[i], true) : 0)
+ + (recog_data.operand_type[i] != OP_IN
+ ? ira_get_may_move_cost (mode, classes[i],
+ rclass, false) : 0))
+ * frequency);
}
/* If the alternative actually allows memory, make
: 0));
else if (ira_reg_class_intersect[pref_class][classes[i]]
== NO_REGS)
- alt_cost += (ira_register_move_cost
- [mode][pref_class][classes[i]]);
+ alt_cost += ira_get_register_move_cost (mode,
+ pref_class,
+ classes[i]);
}
}
}
{
unsigned int regno = REGNO (ops[!i]);
enum machine_mode mode = GET_MODE (ops[!i]);
- int rclass;
+ enum reg_class rclass;
unsigned int nr;
if (regno < FIRST_PSEUDO_REGISTER)
case REG:
{
struct costs *pp;
- int i, k;
+ enum reg_class i;
+ int k;
if (REGNO (x) < FIRST_PSEUDO_REGISTER)
break;
ALLOCNO_NUM (ira_curr_regno_allocno_map
[REGNO (x)]));
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++)
{
i = cost_classes[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;
{
fprintf (f, " %s:%d", reg_class_names[rclass],
COSTS_OF_ALLOCNO (allocno_costs, i)->cost[k]);
- if (flag_ira_algorithm == IRA_ALGORITHM_REGIONAL
- || flag_ira_algorithm == IRA_ALGORITHM_MIXED)
+ if (flag_ira_region == IRA_REGION_ALL
+ || flag_ira_region == IRA_REGION_MIXED)
fprintf (f, ",%d", COSTS_OF_ALLOCNO (total_costs, i)->cost[k]);
}
}
int rclass, a_num, parent_a_num;
ira_loop_tree_node_t parent;
int best_cost, allocno_cost;
- enum reg_class best, alt_class, common_class;
+ enum reg_class best, alt_class;
#ifdef FORBIDDEN_INC_DEC_CLASSES
int inc_dec_p = false;
#endif
a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
{
a_num = ALLOCNO_NUM (a);
- if ((flag_ira_algorithm == IRA_ALGORITHM_REGIONAL
- || flag_ira_algorithm == IRA_ALGORITHM_MIXED)
+ if ((flag_ira_region == IRA_REGION_ALL
+ || flag_ira_region == IRA_REGION_MIXED)
&& (parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) != NULL
&& (parent_a = parent->regno_allocno_map[i]) != NULL
/* There are no caps yet. */
> reg_class_size[alt_class]))
alt_class = reg_class_subunion[alt_class][rclass];
}
+ alt_class = ira_class_translate[alt_class];
if (pass == flag_expensive_optimizations)
{
if (best_cost > temp_costs->mem_cost)
i, reg_class_names[best], reg_class_names[alt_class]);
}
if (best_cost > temp_costs->mem_cost)
- common_class = NO_REGS;
+ common_classes[i] = NO_REGS;
+ else if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
+ /* Make the common class the biggest class of best and
+ alt_class. */
+ common_classes[i] = alt_class == NO_REGS ? best : alt_class;
else
/* Make the common class a cover class. Remember all
allocnos with the same regno should have the same cover
class. */
- common_class = ira_class_translate[best];
+ common_classes[i] = ira_class_translate[best];
for (a = ira_regno_allocno_map[i];
a != NULL;
a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
{
a_num = ALLOCNO_NUM (a);
- if (common_class == NO_REGS)
+ if (common_classes[i] == NO_REGS)
best = NO_REGS;
else
{
for (k = 0; k < cost_classes_num; k++)
{
rclass = cost_classes[k];
- if (! ira_class_subset_p[rclass][common_class])
+ if (! ira_class_subset_p[rclass][common_classes[i]])
continue;
/* Ignore classes that are too small for this
operand or invalid for an operand that was
}
ALLOCNO_COVER_CLASS_COST (a) = allocno_cost;
}
+ ira_assert (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY
+ || ira_class_translate[best] == common_classes[i]);
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL
&& (pass == 0 || allocno_pref[a_num] != best))
{
ALLOCNO_LOOP_TREE_NODE (a)->loop->num);
fprintf (ira_dump_file, ") best %s, cover %s\n",
reg_class_names[best],
- reg_class_names[ira_class_translate[best]]);
+ reg_class_names[common_classes[i]]);
}
allocno_pref[a_num] = best;
}
continue;
mode = ALLOCNO_MODE (a);
hard_reg_class = REGNO_REG_CLASS (hard_regno);
- cost = (to_p ? ira_register_move_cost[mode][hard_reg_class][rclass]
- : ira_register_move_cost[mode][rclass][hard_reg_class]) * freq;
+ cost
+ = (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,
ALLOCNO_COVER_CLASS_COST (a));
ira_allocate_and_set_costs (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a),
{
i = ALLOCNO_NUM (a);
mode = ALLOCNO_MODE (a);
- cover_class = ira_class_translate[allocno_pref[i]];
+ cover_class = common_classes[ALLOCNO_REGNO (a)];
ira_assert (allocno_pref[i] == NO_REGS || cover_class != NO_REGS);
ALLOCNO_MEMORY_COST (a) = COSTS_OF_ALLOCNO (allocno_costs, i)->mem_cost;
ira_set_allocno_cover_class (a, cover_class);
void
ira_costs (void)
{
- ira_allocno_t a;
- ira_allocno_iterator ai;
-
allocno_costs = (struct costs *) ira_allocate (max_struct_costs_size
* ira_allocnos_num);
total_costs = (struct costs *) ira_allocate (max_struct_costs_size
allocno_pref_buffer
= (enum reg_class *) ira_allocate (sizeof (enum reg_class)
* ira_allocnos_num);
+ common_classes
+ = (enum reg_class *) ira_allocate (sizeof (enum reg_class)
+ * max_reg_num ());
find_allocno_class_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 (allocno_pref_buffer);
ira_free (total_costs);
ira_free (allocno_costs);