enum reg_class aclass;
enum machine_mode mode;
+ /* Initial set up from allocno classes and explicitly conflicting
+ hard regs. */
EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
{
a = ira_allocnos[i];
{
COPY_HARD_REG_SET (obj_data->profitable_hard_regs,
reg_class_contents[aclass]);
- AND_COMPL_HARD_REG_SET
- (obj_data->profitable_hard_regs,
- ira_prohibited_class_mode_regs[aclass][mode]);
AND_COMPL_HARD_REG_SET (obj_data->profitable_hard_regs,
ira_no_alloc_regs);
AND_COMPL_HARD_REG_SET (obj_data->profitable_hard_regs,
}
}
}
+ /* Exclude hard regs already assigned for conflicting objects. */
EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi)
{
a = ira_allocnos[i];
}
}
}
+ /* Exclude too costly hard regs. */
EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
{
int min_cost = INT_MAX;
}
/* Set up conflicting and profitable regs (through CONFLICT_REGS and
- PROFITABLE_REGS) for each object of allocno A. */
+ PROFITABLE_REGS) for each object of allocno A. Remember that the
+ profitable regs exclude hard regs which can not hold value of mode
+ of allocno A. */
static inline void
-setup_conflict_profitable_regs (ira_allocno_t a, bool retry_p,
- HARD_REG_SET *conflict_regs,
- HARD_REG_SET *profitable_regs)
+get_conflict_profitable_regs (ira_allocno_t a, bool retry_p,
+ HARD_REG_SET *conflict_regs,
+ HARD_REG_SET *profitable_regs)
{
int i, nwords;
ira_object_t obj;
COPY_HARD_REG_SET (conflict_regs[i],
OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
if (retry_p)
- COPY_HARD_REG_SET (profitable_regs[i],
- reg_class_contents[ALLOCNO_CLASS (a)]);
+ {
+ COPY_HARD_REG_SET (profitable_regs[i],
+ reg_class_contents[ALLOCNO_CLASS (a)]);
+ AND_COMPL_HARD_REG_SET (profitable_regs[i],
+ ira_prohibited_class_mode_regs
+ [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
+ }
else
COPY_HARD_REG_SET (profitable_regs[i],
OBJECT_COLOR_DATA (obj)->profitable_hard_regs);
HARD_REG_SET *conflict_regs, HARD_REG_SET *profitable_regs)
{
int j, nwords, nregs;
+ enum reg_class aclass;
+ enum machine_mode mode;
- nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
+ aclass = ALLOCNO_CLASS (a);
+ mode = ALLOCNO_MODE (a);
+ if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode],
+ hard_regno))
+ return false;
+ nregs = hard_regno_nregs[hard_regno][mode];
nwords = ALLOCNO_NUM_OBJECTS (a);
for (j = 0; j < nregs; j++)
{
}
return j == nregs;
}
+#ifndef HONOR_REG_ALLOC_ORDER
+
+/* Return number of registers needed to be saved and restored at
+ function prologue/epilogue if we allocate HARD_REGNO to hold value
+ of MODE. */
+static int
+calculate_saved_nregs (int hard_regno, enum machine_mode mode)
+{
+ int i;
+ int nregs = 0;
+
+ ira_assert (hard_regno >= 0);
+ for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
+ if (!allocated_hardreg_p[hard_regno + i]
+ && !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i)
+ && !LOCAL_REGNO (hard_regno + i))
+ nregs++;
+ return nregs;
+}
+#endif
/* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
that the function called from function
enum machine_mode mode;
static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
#ifndef HONOR_REG_ALLOC_ORDER
+ int saved_nregs;
enum reg_class rclass;
int add_cost;
#endif
#endif
ira_assert (! ALLOCNO_ASSIGNED_P (a));
- setup_conflict_profitable_regs (a, retry_p,
- conflicting_regs, profitable_hard_regs);
+ get_conflict_profitable_regs (a, retry_p,
+ conflicting_regs, profitable_hard_regs);
aclass = ALLOCNO_CLASS (a);
class_size = ira_class_hard_regs_num[aclass];
best_hard_regno = -1;
{
hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
if (hard_regno >= 0
- && ira_class_hard_reg_index[aclass][hard_regno] >= 0)
+ && (ira_hard_reg_set_intersection_p
+ (hard_regno, ALLOCNO_MODE (conflict_a),
+ reg_class_contents[aclass])))
{
- enum machine_mode mode = ALLOCNO_MODE (conflict_a);
- int conflict_nregs = hard_regno_nregs[hard_regno][mode];
int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
+ int conflict_nregs;
+ mode = ALLOCNO_MODE (conflict_a);
+ conflict_nregs = hard_regno_nregs[hard_regno][mode];
if (conflict_nregs == n_objects && conflict_nregs > 1)
{
int num = OBJECT_SUBWORD (conflict_obj);
cost = costs[i];
full_cost = full_costs[i];
#ifndef HONOR_REG_ALLOC_ORDER
- if (! allocated_hardreg_p[hard_regno]
- && ira_hard_reg_not_in_set_p (hard_regno, mode, call_used_reg_set)
- && !LOCAL_REGNO (hard_regno))
+ if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
/* We need to save/restore the hard register in
epilogue/prologue. Therefore we increase the cost. */
{
- /* ??? If only part is call clobbered. */
rclass = REGNO_REG_CLASS (hard_regno);
- add_cost = (ira_memory_move_cost[mode][rclass][0]
- + ira_memory_move_cost[mode][rclass][1] - 1);
+ add_cost = ((ira_memory_move_cost[mode][rclass][0]
+ + ira_memory_move_cost[mode][rclass][1])
+ * saved_nregs / hard_regno_nregs[hard_regno][mode] - 1);
cost += add_cost;
full_cost += add_cost;
}
}
fail:
if (best_hard_regno >= 0)
- allocated_hardreg_p[best_hard_regno] = true;
+ {
+ for (i = hard_regno_nregs[best_hard_regno][mode] - 1; i >= 0; i--)
+ allocated_hardreg_p[best_hard_regno + 1] = true;
+ }
ALLOCNO_HARD_REGNO (a) = best_hard_regno;
ALLOCNO_ASSIGNED_P (a) = true;
if (best_hard_regno >= 0)
ira_object_t obj = ALLOCNO_OBJECT (a, k);
object_color_data_t obj_data = OBJECT_COLOR_DATA (obj);
- /* Checking only profitable hard regs. */
+ /* Checking only profitable hard regs which exclude
+ object's conflict hard regs. */
if (TEST_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
hard_regno + j)
|| ! TEST_HARD_REG_BIT (obj_data->profitable_hard_regs,
else
base_cost = allocno_costs[ira_class_hard_reg_index[aclass][hregno]];
try_p = false;
- setup_conflict_profitable_regs (a, false,
- conflicting_regs, profitable_hard_regs);
+ get_conflict_profitable_regs (a, false,
+ conflicting_regs, profitable_hard_regs);
class_size = ira_class_hard_regs_num[aclass];
/* Set up cost improvement for usage of each profitable hard
register for allocno A. */
bitmap_iterator bi;
ira_allocno_t a;
+ setup_profitable_hard_regs ();
if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
{
n = 0;
}
else
{
- setup_profitable_hard_regs ();
form_object_hard_regs_nodes_forest ();
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
print_hard_regs_forest (ira_dump_file);
: ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
[aclass][hard_regno]]));
if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
- && ! ira_hard_reg_not_in_set_p (hard_regno, ALLOCNO_MODE (a),
- call_used_reg_set))
+ && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
+ call_used_reg_set))
{
ira_assert (flag_caller_saves);
caller_save_needed = 1;
&& hard_regno <= LAST_STACK_REG)
continue;
#endif
- if (!ira_hard_reg_not_in_set_p (hard_regno, mode, conflict_hard_regs)
+ if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
|| (TEST_HARD_REG_BIT
(ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
continue;