/* TRUE if we work with allocnos. Otherwise we work with pseudos. */
static bool allocno_p;
-/* Number of elements in arrays `in_inc_dec' and `costs'. */
+/* Number of elements in array `costs'. */
static int cost_elements_num;
-#ifdef FORBIDDEN_INC_DEC_CLASSES
-/* Indexed by n, is TRUE if allocno or pseudo with number N is used in
- an auto-inc or auto-dec context. */
-static bool *in_inc_dec;
-#endif
-
/* The `costs' struct records the cost of using hard registers of each
class considered for the calculation and of using memory for each
allocno or pseudo. */
int i;
PTR *slot;
HARD_REG_SET temp, temp2;
+ bool exclude_p;
if ((classes_ptr = cost_classes_aclass_cache[aclass]) == NULL)
{
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;
classes.num = 0;
for (i = 0; i < ira_important_classes_num; i++)
{
cl = ira_important_classes[i];
- 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)
- continue;
+ if (exclude_p)
+ {
+ /* Exclude no-pressure 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)
+ continue;
+ }
classes.classes[classes.num++] = cl;
}
slot = htab_find_slot (cost_classes_htab, &classes, INSERT);
classes_ptr = setup_cost_classes (&classes);
*slot = classes_ptr;
}
+ else
+ classes_ptr = (cost_classes_t) *slot;
cost_classes_mode_cache[mode] = (cost_classes_t) *slot;
}
regno_cost_classes[regno] = classes_ptr;
enum machine_mode mode = GET_MODE (ops[!i]);
cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
enum reg_class *cost_classes = cost_classes_ptr->classes;
- enum reg_class rclass;
+ reg_class_t rclass;
int nr;
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
{
rclass = cost_classes[k];
if (TEST_HARD_REG_BIT (reg_class_contents[rclass], other_regno)
- && (reg_class_size[rclass]
- == (unsigned) CLASS_MAX_NREGS (rclass, mode)))
+ && (reg_class_size[(int) rclass]
+ == ira_reg_class_max_nregs [(int) rclass][(int) mode]))
{
if (reg_class_size[rclass] == 1)
op_costs[i]->cost[k] = -frequency;
case PRE_DEC:
/* Double the importance of an allocno that is incremented or
decremented, since it would take two extra insns if it ends
- up in the wrong place. If the operand is a pseudo-register,
- show it is being used in an INC_DEC context. */
-#ifdef FORBIDDEN_INC_DEC_CLASSES
- if (REG_P (XEXP (x, 0))
- && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER)
- in_inc_dec[COST_INDEX (REGNO (XEXP (x, 0)))] = true;
-#endif
+ up in the wrong place. */
record_address_regs (mode, XEXP (x, 0), 0, code, SCRATCH, 2 * scale);
break;
&& (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != NULL_RTX
&& ((MEM_P (XEXP (note, 0)))
|| (CONSTANT_P (XEXP (note, 0))
- && LEGITIMATE_CONSTANT_P (XEXP (note, 0))
+ && targetm.legitimate_constant_p (GET_MODE (SET_DEST (set)),
+ XEXP (note, 0))
&& REG_N_SETS (REGNO (SET_DEST (set))) == 1)))
{
enum reg_class cl = GENERAL_REGS;
{
rclass = cost_classes[k];
if (contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (regno)]
-#ifdef FORBIDDEN_INC_DEC_CLASSES
- && (! in_inc_dec[i] || ! forbidden_inc_dec_class[rclass])
-#endif
#ifdef CANNOT_CHANGE_MODE_CLASS
&& ! invalid_mode_change_p (regno, (enum reg_class) rclass)
#endif
{
rclass = cost_classes[k];
if (contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (regno)]
-#ifdef FORBIDDEN_INC_DEC_CLASSES
- && (! in_inc_dec[regno] || ! forbidden_inc_dec_class[rclass])
-#endif
#ifdef CANNOT_CHANGE_MODE_CLASS
&& ! invalid_mode_change_p (regno, (enum reg_class) rclass)
#endif
enum reg_class *regno_best_class;
init_recog ();
-#ifdef FORBIDDEN_INC_DEC_CLASSES
- in_inc_dec = ira_allocate (sizeof (bool) * cost_elements_num);
-#endif /* FORBIDDEN_INC_DEC_CLASSES */
regno_best_class
= (enum reg_class *) ira_allocate (max_reg_num ()
* sizeof (enum reg_class));
/* Zero out our accumulation of the cost of each class for each
allocno. */
memset (costs, 0, cost_elements_num * struct_costs_size);
-#ifdef FORBIDDEN_INC_DEC_CLASSES
- memset (in_inc_dec, 0, cost_elements_num * sizeof (bool));
-#endif
if (allocno_p)
{
ira_loop_tree_node_t parent;
int best_cost, allocno_cost;
enum reg_class best, alt_class;
-#ifdef FORBIDDEN_INC_DEC_CLASSES
- int inc_dec_p = false;
-#endif
cost_classes_t cost_classes_ptr = regno_cost_classes[i];
enum reg_class *cost_classes = cost_classes_ptr->classes;
int *i_costs = temp_costs->cost;
{
if (regno_reg_rtx[i] == NULL_RTX)
continue;
-#ifdef FORBIDDEN_INC_DEC_CLASSES
- inc_dec_p = in_inc_dec[i];
-#endif
memcpy (temp_costs, COSTS (costs, i), struct_costs_size);
i_mem_cost = temp_costs->mem_cost;
}
i_mem_cost = INT_MAX;
else
i_mem_cost += add_cost;
-#ifdef FORBIDDEN_INC_DEC_CLASSES
- if (in_inc_dec[a_num])
- inc_dec_p = true;
-#endif
}
}
if (equiv_savings < 0)
- temp_costs->mem_cost = -equiv_savings;
+ i_mem_cost = -equiv_savings;
else if (equiv_savings > 0)
{
- temp_costs->mem_cost = 0;
+ i_mem_cost = 0;
for (k = cost_classes_ptr->num - 1; k >= 0; k--)
i_costs[k] += equiv_savings;
}
for (k = 0; k < cost_classes_ptr->num; k++)
{
rclass = cost_classes[k];
- /* Ignore classes that are too small for this operand or
- invalid for an operand that was auto-incremented. */
+ /* Ignore classes that are too small or invalid for this
+ operand. */
if (! contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (i)]
-#ifdef FORBIDDEN_INC_DEC_CLASSES
- || (inc_dec_p && forbidden_inc_dec_class[rclass])
-#endif
#ifdef CANNOT_CHANGE_MODE_CLASS
|| invalid_mode_change_p (i, (enum reg_class) rclass)
#endif
rclass = cost_classes[k];
if (! ira_class_subset_p[rclass][regno_aclass[i]])
continue;
- /* Ignore classes that are too small for this
- operand or invalid for an operand that was
- auto-incremented. */
+ /* Ignore classes that are too small or invalid
+ for this operand. */
if (! contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (i)]
-#ifdef FORBIDDEN_INC_DEC_CLASSES
- || (inc_dec_p && forbidden_inc_dec_class[rclass])
-#endif
#ifdef CANNOT_CHANGE_MODE_CLASS
|| invalid_mode_change_p (i, (enum reg_class) rclass)
#endif
}
}
ira_free (regno_best_class);
-#ifdef FORBIDDEN_INC_DEC_CLASSES
- ira_free (in_inc_dec);
-#endif
}
\f
{
int i;
- if (init_cost != NULL)
- free (init_cost);
+ free (init_cost);
init_cost = NULL;
for (i = 0; i < MAX_RECOG_OPERANDS; i++)
{
- if (op_costs[i] != NULL)
- free (op_costs[i]);
- if (this_op_costs[i] != NULL)
- free (this_op_costs[i]);
+ free (op_costs[i]);
+ free (this_op_costs[i]);
op_costs[i] = this_op_costs[i] = NULL;
}
- if (temp_costs != NULL)
- free (temp_costs);
+ free (temp_costs);
temp_costs = NULL;
}
skip_p = false;
FOR_EACH_ALLOCNO_OBJECT (a, obj, oi)
{
- if (! ira_hard_reg_not_in_set_p (regno, mode,
- OBJECT_CONFLICT_HARD_REGS
- (obj)))
+ if (ira_hard_reg_set_intersection_p (regno, mode,
+ OBJECT_CONFLICT_HARD_REGS
+ (obj)))
{
skip_p = true;
break;
continue;
rclass = REGNO_REG_CLASS (regno);
cost = 0;
- if (! ira_hard_reg_not_in_set_p (regno, mode, call_used_reg_set)
+ if (ira_hard_reg_set_intersection_p (regno, mode, call_used_reg_set)
|| HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
cost += (ALLOCNO_CALL_FREQ (a)
* (ira_memory_move_cost[mode][rclass][0]