/* IRA hard register and memory cost calculation for allocnos or pseudos.
- Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 2006-2013 Free Software Foundation, Inc.
Contributed by Vladimir Makarov <vmakarov@redhat.com>.
This file is part of GCC.
COPY_HARD_REG_SET (temp, reg_class_contents[aclass]);
AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
/* We exclude classes from consideration which are subsets of
- ACLASS only if ACLASS is a pressure class or subset of a
- pressure class. It means by the definition of pressure classes
- that cost of moving between susbets of ACLASS is cheaper than
- load or store. */
- for (i = 0; i < ira_pressure_classes_num; i++)
- {
- cl = ira_pressure_classes[i];
- if (cl == aclass)
- break;
- COPY_HARD_REG_SET (temp2, reg_class_contents[cl]);
- AND_COMPL_HARD_REG_SET (temp2, ira_no_alloc_regs);
- if (hard_reg_set_subset_p (temp, temp2))
- break;
- }
- exclude_p = i < ira_pressure_classes_num;
+ ACLASS only if ACLASS is an uniform class. */
+ exclude_p = ira_uniform_class_p[aclass];
classes.num = 0;
for (i = 0; i < ira_important_classes_num; i++)
{
cl = ira_important_classes[i];
if (exclude_p)
{
- /* Exclude no-pressure classes which are subsets of
+ /* Exclude non-uniform classes which are subsets of
ACLASS. */
COPY_HARD_REG_SET (temp2, reg_class_contents[cl]);
AND_COMPL_HARD_REG_SET (temp2, ira_no_alloc_regs);
- if (! ira_reg_pressure_class_p[cl]
- && hard_reg_set_subset_p (temp2, temp) && cl != aclass)
+ if (hard_reg_set_subset_p (temp2, temp) && cl != aclass)
continue;
}
classes.classes[classes.num++] = cl;
if (secondary_class != NO_REGS)
{
- if (!move_cost[mode])
- init_move_cost (mode);
- return (move_cost[mode][(int) secondary_class][(int) rclass]
+ ira_init_register_move_cost_if_necessary (mode);
+ return (ira_register_move_cost[mode][(int) secondary_class][(int) rclass]
+ sri.extra_cost
+ copy_cost (x, mode, secondary_class, to_p, &sri));
}
+ ira_memory_move_cost[mode][(int) rclass][to_p != 0];
else if (REG_P (x))
{
- if (!move_cost[mode])
- init_move_cost (mode);
+ reg_class_t x_class = REGNO_REG_CLASS (REGNO (x));
+
+ ira_init_register_move_cost_if_necessary (mode);
return (sri.extra_cost
- + move_cost[mode][REGNO_REG_CLASS (REGNO (x))][(int) rclass]);
+ + ira_register_move_cost[mode][(int) x_class][(int) rclass]);
}
else
/* If this is a constant, we may eventually want to call rtx_cost
case 'E':
case 'F':
- if (GET_CODE (op) == CONST_DOUBLE
+ if (CONST_DOUBLE_AS_FLOAT_P (op)
|| (GET_CODE (op) == CONST_VECTOR
&& (GET_MODE_CLASS (GET_MODE (op))
== MODE_VECTOR_FLOAT)))
case 'G':
case 'H':
- if (GET_CODE (op) == CONST_DOUBLE
+ if (CONST_DOUBLE_AS_FLOAT_P (op)
&& CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, p))
win = 1;
break;
case 's':
- if (CONST_INT_P (op)
- || (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode))
+ if (CONST_SCALAR_INT_P (op))
break;
case 'i':
break;
case 'n':
- if (CONST_INT_P (op)
- || (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode))
+ if (CONST_SCALAR_INT_P (op))
win = 1;
break;
/* If the second operand is a constant integer, it doesn't
change what class the first operand must be. */
- else if (code1 == CONST_INT || code1 == CONST_DOUBLE)
+ else if (CONST_SCALAR_INT_P (arg1))
record_address_regs (mode, as, arg0, context, PLUS, code1, scale);
/* If the second operand is a symbolic constant, the first
operand must be an index register. */
COSTS (total_allocno_costs, parent_a_num)->mem_cost
+= add_cost;
+ if (i >= first_moveable_pseudo && i < last_moveable_pseudo)
+ COSTS (total_allocno_costs, parent_a_num)->mem_cost = 0;
}
a_costs = COSTS (costs, a_num)->cost;
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
i_mem_cost += add_cost;
}
}
- if (equiv_savings < 0)
+ if (i >= first_moveable_pseudo && i < last_moveable_pseudo)
+ i_mem_cost = 0;
+ else if (equiv_savings < 0)
i_mem_cost = -equiv_savings;
else if (equiv_savings > 0)
{
ira_free (total_allocno_costs);
}
-/* Entry function which defines classes for pseudos. */
+/* Entry function which defines classes for pseudos.
+ Set pseudo_classes_defined_p only if DEFINE_PSEUDO_CLASSES is true. */
void
-ira_set_pseudo_classes (FILE *dump_file)
+ira_set_pseudo_classes (bool define_pseudo_classes, FILE *dump_file)
{
allocno_p = false;
internal_flag_ira_verbose = flag_ira_verbose;
initiate_regno_cost_classes ();
find_costs_and_classes (dump_file);
finish_regno_cost_classes ();
- pseudo_classes_defined_p = true;
+ if (define_pseudo_classes)
+ pseudo_classes_defined_p = true;
+
finish_costs ();
}
mode = ALLOCNO_MODE (a);
n = ira_class_hard_regs_num[aclass];
min_cost = INT_MAX;
- if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
+ if (ALLOCNO_CALLS_CROSSED_NUM (a)
+ != ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a))
{
ira_allocate_and_set_costs
(&ALLOCNO_HARD_REG_COSTS (a), aclass,