summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/ira-color.c43
-rw-r--r--gcc/ira-costs.c8
-rw-r--r--gcc/ira-int.h8
-rw-r--r--gcc/ira.c18
5 files changed, 72 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dabaf4eda27..41c3db20a36 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index 7a1073b0bf2..eb87b0e419b 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -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;
diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c
index 39ef33a541c..12d3ed67fa7 100644
--- a/gcc/ira-costs.c
+++ b/gcc/ira-costs.c
@@ -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]
diff --git a/gcc/ira-int.h b/gcc/ira-int.h
index 6a6c4831c00..1db9b411e0b 100644
--- a/gcc/ira-int.h
+++ b/gcc/ira-int.h
@@ -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;
}
diff --git a/gcc/ira.c b/gcc/ira.c
index b54762e8962..e4be8b52f71 100644
--- a/gcc/ira.c
+++ b/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);