Commit 9181a6e5 by Vladimir Makarov Committed by Vladimir Makarov

re PR rtl-optimization/50107 ([IRA, i386] allocates registers in very non-optimal way)

2011-08-17  Vladimir Makarov  <vmakarov@redhat.com>

	PR rtl-optimization/50107
	* ira-int.h (ira_hard_reg_not_in_set_p): Remove.
	(ira_hard_reg_in_set_p): New.

	* ira-color.c (calculate_saved_nregs): New.
	(assign_hard_reg): Use it.  Set up allocated_hard_reg_p for all
	hard regs.
	(allocno_reload_assign, fast_allocation): Use
	ira_hard_reg_set_intersection_p instead of
	ira_hard_reg_not_in_set_p.

	* ira.c (setup_reg_renumber): Use
	ira_hard_reg_set_intersection_p instead of
	ira_hard_reg_not_in_set_p.
	(setup_allocno_assignment_flags, calculate_allocation_cost): Use
	ira_hard_reg_in_set_p instead of ira_hard_reg_not_in_set_p.

	* ira-costs.c (ira_tune_allocno_costs): Use
	ira_hard_reg_set_intersection_p instead of
	ira_hard_reg_not_in_set_p.

From-SVN: r177865
parent 99114bbf
2011-08-17 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/50107
* ira-int.h (ira_hard_reg_not_in_set_p): Remove.
(ira_hard_reg_in_set_p): New.
* ira-color.c (calculate_saved_nregs): New.
(assign_hard_reg): Use it. Set up allocated_hard_reg_p for all
hard regs.
(allocno_reload_assign, fast_allocation): Use
ira_hard_reg_set_intersection_p instead of
ira_hard_reg_not_in_set_p.
* ira.c (setup_reg_renumber): Use
ira_hard_reg_set_intersection_p instead of
ira_hard_reg_not_in_set_p.
(setup_allocno_assignment_flags, calculate_allocation_cost): Use
ira_hard_reg_in_set_p instead of ira_hard_reg_not_in_set_p.
* ira-costs.c (ira_tune_allocno_costs): Use
ira_hard_reg_set_intersection_p instead of
ira_hard_reg_not_in_set_p.
2011-08-18 H.J. Lu <hongjiu.lu@intel.com> 2011-08-18 H.J. Lu <hongjiu.lu@intel.com>
Igor Zamyatin <igor.zamyatin@intel.com> Igor Zamyatin <igor.zamyatin@intel.com>
......
...@@ -1519,6 +1519,26 @@ check_hard_reg_p (ira_allocno_t a, int hard_regno, ...@@ -1519,6 +1519,26 @@ check_hard_reg_p (ira_allocno_t a, int hard_regno,
} }
return j == nregs; 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 /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
that the function called from function that the function called from function
...@@ -1547,7 +1567,7 @@ static bool ...@@ -1547,7 +1567,7 @@ static bool
assign_hard_reg (ira_allocno_t a, bool retry_p) assign_hard_reg (ira_allocno_t a, bool retry_p)
{ {
HARD_REG_SET conflicting_regs[2], profitable_hard_regs[2]; HARD_REG_SET conflicting_regs[2], profitable_hard_regs[2];
int i, j, hard_regno, best_hard_regno, class_size; int i, j, hard_regno, best_hard_regno, class_size, saved_nregs;
int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word; int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
int *a_costs; int *a_costs;
enum reg_class aclass; enum reg_class aclass;
...@@ -1716,16 +1736,14 @@ assign_hard_reg (ira_allocno_t a, bool retry_p) ...@@ -1716,16 +1736,14 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
cost = costs[i]; cost = costs[i];
full_cost = full_costs[i]; full_cost = full_costs[i];
#ifndef HONOR_REG_ALLOC_ORDER #ifndef HONOR_REG_ALLOC_ORDER
if (! allocated_hardreg_p[hard_regno] if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
&& ira_hard_reg_not_in_set_p (hard_regno, mode, call_used_reg_set)
&& !LOCAL_REGNO (hard_regno))
/* We need to save/restore the hard register in /* We need to save/restore the hard register in
epilogue/prologue. Therefore we increase the cost. */ epilogue/prologue. Therefore we increase the cost. */
{ {
/* ??? If only part is call clobbered. */
rclass = REGNO_REG_CLASS (hard_regno); rclass = REGNO_REG_CLASS (hard_regno);
add_cost = (ira_memory_move_cost[mode][rclass][0] add_cost = ((ira_memory_move_cost[mode][rclass][0]
+ ira_memory_move_cost[mode][rclass][1] - 1); + ira_memory_move_cost[mode][rclass][1])
* saved_nregs / hard_regno_nregs[hard_regno][mode] - 1);
cost += add_cost; cost += add_cost;
full_cost += add_cost; full_cost += add_cost;
} }
...@@ -1748,7 +1766,10 @@ assign_hard_reg (ira_allocno_t a, bool retry_p) ...@@ -1748,7 +1766,10 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
} }
fail: fail:
if (best_hard_regno >= 0) 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_HARD_REGNO (a) = best_hard_regno;
ALLOCNO_ASSIGNED_P (a) = true; ALLOCNO_ASSIGNED_P (a) = true;
if (best_hard_regno >= 0) if (best_hard_regno >= 0)
...@@ -3975,8 +3996,8 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs) ...@@ -3975,8 +3996,8 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
: ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
[aclass][hard_regno]])); [aclass][hard_regno]]));
if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
&& ! ira_hard_reg_not_in_set_p (hard_regno, ALLOCNO_MODE (a), && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
call_used_reg_set)) call_used_reg_set))
{ {
ira_assert (flag_caller_saves); ira_assert (flag_caller_saves);
caller_save_needed = 1; caller_save_needed = 1;
...@@ -4467,7 +4488,7 @@ fast_allocation (void) ...@@ -4467,7 +4488,7 @@ fast_allocation (void)
&& hard_regno <= LAST_STACK_REG) && hard_regno <= LAST_STACK_REG)
continue; continue;
#endif #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 || (TEST_HARD_REG_BIT
(ira_prohibited_class_mode_regs[aclass][mode], hard_regno))) (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
continue; continue;
......
...@@ -2072,9 +2072,9 @@ ira_tune_allocno_costs (void) ...@@ -2072,9 +2072,9 @@ ira_tune_allocno_costs (void)
skip_p = false; skip_p = false;
FOR_EACH_ALLOCNO_OBJECT (a, obj, oi) FOR_EACH_ALLOCNO_OBJECT (a, obj, oi)
{ {
if (! ira_hard_reg_not_in_set_p (regno, mode, if (ira_hard_reg_set_intersection_p (regno, mode,
OBJECT_CONFLICT_HARD_REGS OBJECT_CONFLICT_HARD_REGS
(obj))) (obj)))
{ {
skip_p = true; skip_p = true;
break; break;
...@@ -2084,7 +2084,7 @@ ira_tune_allocno_costs (void) ...@@ -2084,7 +2084,7 @@ ira_tune_allocno_costs (void)
continue; continue;
rclass = REGNO_REG_CLASS (regno); rclass = REGNO_REG_CLASS (regno);
cost = 0; 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)) || HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
cost += (ALLOCNO_CALL_FREQ (a) cost += (ALLOCNO_CALL_FREQ (a)
* (ira_memory_move_cost[mode][rclass][0] * (ira_memory_move_cost[mode][rclass][0]
......
...@@ -1323,17 +1323,17 @@ hard_reg_set_size (HARD_REG_SET set) ...@@ -1323,17 +1323,17 @@ hard_reg_set_size (HARD_REG_SET set)
} }
/* The function returns TRUE if hard registers starting with /* The function returns TRUE if hard registers starting with
HARD_REGNO and containing value of MODE are not in set HARD_REGNO and containing value of MODE are fully in set
HARD_REGSET. */ HARD_REGSET. */
static inline bool static inline bool
ira_hard_reg_not_in_set_p (int hard_regno, enum machine_mode mode, ira_hard_reg_in_set_p (int hard_regno, enum machine_mode mode,
HARD_REG_SET hard_regset) HARD_REG_SET hard_regset)
{ {
int i; int i;
ira_assert (hard_regno >= 0); ira_assert (hard_regno >= 0);
for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--) for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
if (TEST_HARD_REG_BIT (hard_regset, hard_regno + i)) if (!TEST_HARD_REG_BIT (hard_regset, hard_regno + i))
return false; return false;
return true; return true;
} }
......
...@@ -1953,8 +1953,8 @@ setup_reg_renumber (void) ...@@ -1953,8 +1953,8 @@ setup_reg_renumber (void)
reg_class_contents[pclass]); reg_class_contents[pclass]);
} }
if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
&& ! ira_hard_reg_not_in_set_p (hard_regno, ALLOCNO_MODE (a), && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
call_used_reg_set)) call_used_reg_set))
{ {
ira_assert (!optimize || flag_caller_saves ira_assert (!optimize || flag_caller_saves
|| regno >= ira_reg_equiv_len || regno >= ira_reg_equiv_len
...@@ -1992,10 +1992,10 @@ setup_allocno_assignment_flags (void) ...@@ -1992,10 +1992,10 @@ setup_allocno_assignment_flags (void)
|| ALLOCNO_EMIT_DATA (a)->mem_optimized_dest_p || ALLOCNO_EMIT_DATA (a)->mem_optimized_dest_p
|| (ALLOCNO_MEMORY_COST (a) || (ALLOCNO_MEMORY_COST (a)
- ALLOCNO_CLASS_COST (a)) < 0); - ALLOCNO_CLASS_COST (a)) < 0);
ira_assert (hard_regno < 0 ira_assert
|| ! ira_hard_reg_not_in_set_p (hard_regno, ALLOCNO_MODE (a), (hard_regno < 0
reg_class_contents || ira_hard_reg_in_set_p (hard_regno, ALLOCNO_MODE (a),
[ALLOCNO_CLASS (a)])); reg_class_contents[ALLOCNO_CLASS (a)]));
} }
} }
...@@ -2013,9 +2013,9 @@ calculate_allocation_cost (void) ...@@ -2013,9 +2013,9 @@ calculate_allocation_cost (void)
{ {
hard_regno = ALLOCNO_HARD_REGNO (a); hard_regno = ALLOCNO_HARD_REGNO (a);
ira_assert (hard_regno < 0 ira_assert (hard_regno < 0
|| ! ira_hard_reg_not_in_set_p || (ira_hard_reg_in_set_p
(hard_regno, ALLOCNO_MODE (a), (hard_regno, ALLOCNO_MODE (a),
reg_class_contents[ALLOCNO_CLASS (a)])); reg_class_contents[ALLOCNO_CLASS (a)])));
if (hard_regno < 0) if (hard_regno < 0)
{ {
cost = ALLOCNO_MEMORY_COST (a); cost = ALLOCNO_MEMORY_COST (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