mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-08 19:20:44 +08:00
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
This commit is contained in:
parent
99114bbfa1
commit
9181a6e5b0
@ -1,3 +1,26 @@
|
||||
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>
|
||||
Igor Zamyatin <igor.zamyatin@intel.com>
|
||||
|
||||
|
@ -1519,6 +1519,26 @@ check_hard_reg_p (ira_allocno_t a, int hard_regno,
|
||||
}
|
||||
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
|
||||
@ -1547,7 +1567,7 @@ static bool
|
||||
assign_hard_reg (ira_allocno_t a, bool retry_p)
|
||||
{
|
||||
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 *a_costs;
|
||||
enum reg_class aclass;
|
||||
@ -1716,16 +1736,14 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
|
||||
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;
|
||||
}
|
||||
@ -1748,7 +1766,10 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
|
||||
}
|
||||
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)
|
||||
@ -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
|
||||
[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;
|
||||
@ -4467,7 +4488,7 @@ fast_allocation (void)
|
||||
&& 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;
|
||||
|
@ -2072,9 +2072,9 @@ ira_tune_allocno_costs (void)
|
||||
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;
|
||||
@ -2084,7 +2084,7 @@ ira_tune_allocno_costs (void)
|
||||
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]
|
||||
|
@ -1323,17 +1323,17 @@ hard_reg_set_size (HARD_REG_SET set)
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
static inline bool
|
||||
ira_hard_reg_not_in_set_p (int hard_regno, enum machine_mode mode,
|
||||
HARD_REG_SET hard_regset)
|
||||
ira_hard_reg_in_set_p (int hard_regno, enum machine_mode mode,
|
||||
HARD_REG_SET hard_regset)
|
||||
{
|
||||
int i;
|
||||
|
||||
ira_assert (hard_regno >= 0);
|
||||
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 true;
|
||||
}
|
||||
|
18
gcc/ira.c
18
gcc/ira.c
@ -1953,8 +1953,8 @@ setup_reg_renumber (void)
|
||||
reg_class_contents[pclass]);
|
||||
}
|
||||
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 (!optimize || flag_caller_saves
|
||||
|| regno >= ira_reg_equiv_len
|
||||
@ -1992,10 +1992,10 @@ setup_allocno_assignment_flags (void)
|
||||
|| ALLOCNO_EMIT_DATA (a)->mem_optimized_dest_p
|
||||
|| (ALLOCNO_MEMORY_COST (a)
|
||||
- ALLOCNO_CLASS_COST (a)) < 0);
|
||||
ira_assert (hard_regno < 0
|
||||
|| ! ira_hard_reg_not_in_set_p (hard_regno, ALLOCNO_MODE (a),
|
||||
reg_class_contents
|
||||
[ALLOCNO_CLASS (a)]));
|
||||
ira_assert
|
||||
(hard_regno < 0
|
||||
|| ira_hard_reg_in_set_p (hard_regno, ALLOCNO_MODE (a),
|
||||
reg_class_contents[ALLOCNO_CLASS (a)]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2013,9 +2013,9 @@ calculate_allocation_cost (void)
|
||||
{
|
||||
hard_regno = ALLOCNO_HARD_REGNO (a);
|
||||
ira_assert (hard_regno < 0
|
||||
|| ! ira_hard_reg_not_in_set_p
|
||||
(hard_regno, ALLOCNO_MODE (a),
|
||||
reg_class_contents[ALLOCNO_CLASS (a)]));
|
||||
|| (ira_hard_reg_in_set_p
|
||||
(hard_regno, ALLOCNO_MODE (a),
|
||||
reg_class_contents[ALLOCNO_CLASS (a)])));
|
||||
if (hard_regno < 0)
|
||||
{
|
||||
cost = ALLOCNO_MEMORY_COST (a);
|
||||
|
Loading…
x
Reference in New Issue
Block a user