summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/ira-int.h23
-rw-r--r--gcc/ira.c112
-rw-r--r--gcc/reginfo.c111
-rw-r--r--gcc/regs.h23
-rw-r--r--gcc/rtl.h2
6 files changed, 142 insertions, 138 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3b5849cefcc..1db6942bfc2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
2012-05-31 Richard Sandiford <rdsandiford@googlemail.com>
+ * regs.h (move_table, move_cost, may_move_in_cost, may_move_out_cost):
+ Move these definitions and associated target_globals fields to...
+ * ira-int.h: ...here.
+ * rtl.h (init_move_cost): Delete.
+ * reginfo.c (last_mode_for_init_move_cost, init_move_cost): Move to...
+ * ira.c: ...here, making the latter static.
+
+2012-05-31 Richard Sandiford <rdsandiford@googlemail.com>
+
* ira-costs.c (copy_cost): Use ira_init_register_move_cost_if_necessary
and ira_register_move_cost instead of init_move_cost and move_cost.
diff --git a/gcc/ira-int.h b/gcc/ira-int.h
index 02bec132614..1b68c2fda40 100644
--- a/gcc/ira-int.h
+++ b/gcc/ira-int.h
@@ -75,6 +75,8 @@ DEF_VEC_ALLOC_P(ira_copy_t, heap);
/* Typedef for pointer to the subsequent structure. */
typedef struct ira_loop_tree_node *ira_loop_tree_node_t;
+typedef unsigned short move_table[N_REG_CLASSES];
+
/* In general case, IRA is a regional allocator. The regions are
nested and form a tree. Currently regions are natural loops. The
following structure describes loop tree node (representing basic
@@ -767,6 +769,21 @@ struct target_ira_int {
HARD_REG_SET (x_ira_reg_mode_hard_regset
[FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES]);
+ /* Maximum cost of moving from a register in one class to a register
+ in another class. Based on TARGET_REGISTER_MOVE_COST. */
+ move_table *x_move_cost[MAX_MACHINE_MODE];
+
+ /* Similar, but here we don't have to move if the first index is a
+ subset of the second so in that case the cost is zero. */
+ move_table *x_may_move_in_cost[MAX_MACHINE_MODE];
+
+ /* Similar, but here we don't have to move if the first index is a
+ superset of the second so in that case the cost is zero. */
+ move_table *x_may_move_out_cost[MAX_MACHINE_MODE];
+
+ /* Keep track of the last mode we initialized move costs for. */
+ int x_last_mode_for_init_move_cost;
+
/* Array based on TARGET_REGISTER_MOVE_COST. Don't use
ira_register_move_cost directly. Use function of
ira_get_may_move_cost instead. */
@@ -888,6 +905,12 @@ extern struct target_ira_int *this_target_ira_int;
#define ira_reg_mode_hard_regset \
(this_target_ira_int->x_ira_reg_mode_hard_regset)
+#define move_cost \
+ (this_target_ira_int->x_move_cost)
+#define may_move_in_cost \
+ (this_target_ira_int->x_may_move_in_cost)
+#define may_move_out_cost \
+ (this_target_ira_int->x_may_move_out_cost)
#define ira_register_move_cost \
(this_target_ira_int->x_ira_register_move_cost)
#define ira_max_memory_move_cost \
diff --git a/gcc/ira.c b/gcc/ira.c
index 3732c8db281..f141712dcaa 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -423,6 +423,8 @@ HARD_REG_SET eliminable_regset;
/* Temporary hard reg set used for a different calculation. */
static HARD_REG_SET temp_hard_regset;
+#define last_mode_for_init_move_cost \
+ (this_target_ira_int->x_last_mode_for_init_move_cost)
/* The function sets up the map IRA_REG_MODE_HARD_REGSET. */
@@ -1455,8 +1457,96 @@ clarify_prohibited_class_mode_regs (void)
}
}
}
-
+/* Initialize may_move_cost and friends for mode M. */
+
+static void
+init_move_cost (enum machine_mode m)
+{
+ static unsigned short last_move_cost[N_REG_CLASSES][N_REG_CLASSES];
+ bool all_match = true;
+ unsigned int i, j;
+
+ gcc_assert (have_regs_of_mode[m]);
+ for (i = 0; i < N_REG_CLASSES; i++)
+ if (contains_reg_of_mode[i][m])
+ for (j = 0; j < N_REG_CLASSES; j++)
+ {
+ int cost;
+ if (!contains_reg_of_mode[j][m])
+ cost = 65535;
+ else
+ {
+ cost = register_move_cost (m, (enum reg_class) i,
+ (enum reg_class) j);
+ gcc_assert (cost < 65535);
+ }
+ all_match &= (last_move_cost[i][j] == cost);
+ last_move_cost[i][j] = cost;
+ }
+ if (all_match && last_mode_for_init_move_cost != -1)
+ {
+ move_cost[m] = move_cost[last_mode_for_init_move_cost];
+ may_move_in_cost[m] = may_move_in_cost[last_mode_for_init_move_cost];
+ may_move_out_cost[m] = may_move_out_cost[last_mode_for_init_move_cost];
+ return;
+ }
+ last_mode_for_init_move_cost = m;
+ move_cost[m] = (move_table *)xmalloc (sizeof (move_table)
+ * N_REG_CLASSES);
+ may_move_in_cost[m] = (move_table *)xmalloc (sizeof (move_table)
+ * N_REG_CLASSES);
+ may_move_out_cost[m] = (move_table *)xmalloc (sizeof (move_table)
+ * N_REG_CLASSES);
+ for (i = 0; i < N_REG_CLASSES; i++)
+ if (contains_reg_of_mode[i][m])
+ for (j = 0; j < N_REG_CLASSES; j++)
+ {
+ int cost;
+ enum reg_class *p1, *p2;
+
+ if (last_move_cost[i][j] == 65535)
+ {
+ move_cost[m][i][j] = 65535;
+ may_move_in_cost[m][i][j] = 65535;
+ may_move_out_cost[m][i][j] = 65535;
+ }
+ else
+ {
+ cost = last_move_cost[i][j];
+
+ for (p2 = &reg_class_subclasses[j][0];
+ *p2 != LIM_REG_CLASSES; p2++)
+ if (*p2 != i && contains_reg_of_mode[*p2][m])
+ cost = MAX (cost, move_cost[m][i][*p2]);
+
+ for (p1 = &reg_class_subclasses[i][0];
+ *p1 != LIM_REG_CLASSES; p1++)
+ if (*p1 != j && contains_reg_of_mode[*p1][m])
+ cost = MAX (cost, move_cost[m][*p1][j]);
+
+ gcc_assert (cost <= 65535);
+ move_cost[m][i][j] = cost;
+
+ if (reg_class_subset_p ((enum reg_class) i, (enum reg_class) j))
+ may_move_in_cost[m][i][j] = 0;
+ else
+ may_move_in_cost[m][i][j] = cost;
+
+ if (reg_class_subset_p ((enum reg_class) j, (enum reg_class) i))
+ may_move_out_cost[m][i][j] = 0;
+ else
+ may_move_out_cost[m][i][j] = cost;
+ }
+ }
+ else
+ for (j = 0; j < N_REG_CLASSES; j++)
+ {
+ move_cost[m][i][j] = 65535;
+ may_move_in_cost[m][i][j] = 65535;
+ may_move_out_cost[m][i][j] = 65535;
+ }
+}
/* Allocate and initialize IRA_REGISTER_MOVE_COST,
IRA_MAX_REGISTER_MOVE_COST, IRA_MAY_MOVE_IN_COST,
@@ -1577,8 +1667,26 @@ ira_init_once (void)
static void
free_register_move_costs (void)
{
- int mode;
+ int mode, i;
+ /* Reset move_cost and friends, making sure we only free shared
+ table entries once. */
+ for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
+ if (move_cost[mode])
+ {
+ for (i = 0; i < mode && move_cost[i] != move_cost[mode]; i++)
+ ;
+ if (i == mode)
+ {
+ free (move_cost[mode]);
+ free (may_move_in_cost[mode]);
+ free (may_move_out_cost[mode]);
+ }
+ }
+ memset (move_cost, 0, sizeof move_cost);
+ memset (may_move_in_cost, 0, sizeof may_move_in_cost);
+ memset (may_move_out_cost, 0, sizeof may_move_out_cost);
+ last_mode_for_init_move_cost = -1;
for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
{
free (ira_max_register_move_cost[mode]);
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index f3a08f523c2..4fa0d04ce9c 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -122,9 +122,6 @@ static const char *const initial_reg_names[] = REGISTER_NAMES;
/* Array containing all of the register class names. */
const char * reg_class_names[] = REG_CLASS_NAMES;
-#define last_mode_for_init_move_cost \
- (this_target_regs->x_last_mode_for_init_move_cost)
-
/* No more global register variables may be declared; true once
reginfo has been initialized. */
static int no_global_reg_vars = 0;
@@ -197,95 +194,6 @@ init_reg_sets (void)
SET_HARD_REG_SET (operand_reg_set);
}
-/* Initialize may_move_cost and friends for mode M. */
-void
-init_move_cost (enum machine_mode m)
-{
- static unsigned short last_move_cost[N_REG_CLASSES][N_REG_CLASSES];
- bool all_match = true;
- unsigned int i, j;
-
- gcc_assert (have_regs_of_mode[m]);
- for (i = 0; i < N_REG_CLASSES; i++)
- if (contains_reg_of_mode[i][m])
- for (j = 0; j < N_REG_CLASSES; j++)
- {
- int cost;
- if (!contains_reg_of_mode[j][m])
- cost = 65535;
- else
- {
- cost = register_move_cost (m, (enum reg_class) i,
- (enum reg_class) j);
- gcc_assert (cost < 65535);
- }
- all_match &= (last_move_cost[i][j] == cost);
- last_move_cost[i][j] = cost;
- }
- if (all_match && last_mode_for_init_move_cost != -1)
- {
- move_cost[m] = move_cost[last_mode_for_init_move_cost];
- may_move_in_cost[m] = may_move_in_cost[last_mode_for_init_move_cost];
- may_move_out_cost[m] = may_move_out_cost[last_mode_for_init_move_cost];
- return;
- }
- last_mode_for_init_move_cost = m;
- move_cost[m] = (move_table *)xmalloc (sizeof (move_table)
- * N_REG_CLASSES);
- may_move_in_cost[m] = (move_table *)xmalloc (sizeof (move_table)
- * N_REG_CLASSES);
- may_move_out_cost[m] = (move_table *)xmalloc (sizeof (move_table)
- * N_REG_CLASSES);
- for (i = 0; i < N_REG_CLASSES; i++)
- if (contains_reg_of_mode[i][m])
- for (j = 0; j < N_REG_CLASSES; j++)
- {
- int cost;
- enum reg_class *p1, *p2;
-
- if (last_move_cost[i][j] == 65535)
- {
- move_cost[m][i][j] = 65535;
- may_move_in_cost[m][i][j] = 65535;
- may_move_out_cost[m][i][j] = 65535;
- }
- else
- {
- cost = last_move_cost[i][j];
-
- for (p2 = &reg_class_subclasses[j][0];
- *p2 != LIM_REG_CLASSES; p2++)
- if (*p2 != i && contains_reg_of_mode[*p2][m])
- cost = MAX (cost, move_cost[m][i][*p2]);
-
- for (p1 = &reg_class_subclasses[i][0];
- *p1 != LIM_REG_CLASSES; p1++)
- if (*p1 != j && contains_reg_of_mode[*p1][m])
- cost = MAX (cost, move_cost[m][*p1][j]);
-
- gcc_assert (cost <= 65535);
- move_cost[m][i][j] = cost;
-
- if (reg_class_subset_p ((enum reg_class) i, (enum reg_class) j))
- may_move_in_cost[m][i][j] = 0;
- else
- may_move_in_cost[m][i][j] = cost;
-
- if (reg_class_subset_p ((enum reg_class) j, (enum reg_class) i))
- may_move_out_cost[m][i][j] = 0;
- else
- may_move_out_cost[m][i][j] = cost;
- }
- }
- else
- for (j = 0; j < N_REG_CLASSES; j++)
- {
- move_cost[m][i][j] = 65535;
- may_move_in_cost[m][i][j] = 65535;
- may_move_out_cost[m][i][j] = 65535;
- }
-}
-
/* We need to save copies of some of the register information which
can be munged by command-line switches so we can restore it during
subsequent back-end reinitialization. */
@@ -575,25 +483,6 @@ init_reg_sets_1 (void)
have_regs_of_mode [m] = 1;
}
}
-
- /* Reset move_cost and friends, making sure we only free shared
- table entries once. */
- for (i = 0; i < MAX_MACHINE_MODE; i++)
- if (move_cost[i])
- {
- for (j = 0; j < i && move_cost[i] != move_cost[j]; j++)
- ;
- if (i == j)
- {
- free (move_cost[i]);
- free (may_move_in_cost[i]);
- free (may_move_out_cost[i]);
- }
- }
- memset (move_cost, 0, sizeof move_cost);
- memset (may_move_in_cost, 0, sizeof may_move_in_cost);
- memset (may_move_out_cost, 0, sizeof may_move_out_cost);
- last_mode_for_init_move_cost = -1;
}
/* Compute the table of register modes.
diff --git a/gcc/regs.h b/gcc/regs.h
index d18bf0aa3c1..24f410c6b07 100644
--- a/gcc/regs.h
+++ b/gcc/regs.h
@@ -240,8 +240,6 @@ extern int caller_save_needed;
#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) 0
#endif
-typedef unsigned short move_table[N_REG_CLASSES];
-
/* Target-dependent globals. */
struct target_regs {
/* For each starting hard register, the number of consecutive hard
@@ -261,21 +259,6 @@ struct target_regs {
/* 1 if the corresponding class contains a register of the given mode. */
char x_contains_reg_of_mode[N_REG_CLASSES][MAX_MACHINE_MODE];
- /* Maximum cost of moving from a register in one class to a register
- in another class. Based on TARGET_REGISTER_MOVE_COST. */
- move_table *x_move_cost[MAX_MACHINE_MODE];
-
- /* Similar, but here we don't have to move if the first index is a
- subset of the second so in that case the cost is zero. */
- move_table *x_may_move_in_cost[MAX_MACHINE_MODE];
-
- /* Similar, but here we don't have to move if the first index is a
- superset of the second so in that case the cost is zero. */
- move_table *x_may_move_out_cost[MAX_MACHINE_MODE];
-
- /* Keep track of the last mode we initialized move costs for. */
- int x_last_mode_for_init_move_cost;
-
/* Record for each mode whether we can move a register directly to or
from an object of that mode in memory. If we can't, we won't try
to use that mode directly when accessing a field of that mode. */
@@ -301,12 +284,6 @@ extern struct target_regs *this_target_regs;
(this_target_regs->x_have_regs_of_mode)
#define contains_reg_of_mode \
(this_target_regs->x_contains_reg_of_mode)
-#define move_cost \
- (this_target_regs->x_move_cost)
-#define may_move_in_cost \
- (this_target_regs->x_may_move_in_cost)
-#define may_move_out_cost \
- (this_target_regs->x_may_move_out_cost)
#define direct_load \
(this_target_regs->x_direct_load)
#define direct_store \
diff --git a/gcc/rtl.h b/gcc/rtl.h
index ae5157e54c0..1d71971335a 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2044,8 +2044,6 @@ extern rtx remove_free_EXPR_LIST_node (rtx *);
/* reginfo.c */
-/* Initialize may_move_cost and friends for mode M. */
-extern void init_move_cost (enum machine_mode);
/* Resize reg info. */
extern bool resize_reg_info (void);
/* Free up register info memory. */