From f7ace4bcd32b0127e0f50c2a6b6fd838fd356c9f Mon Sep 17 00:00:00 2001 From: law <law@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Thu, 20 May 2010 22:49:07 +0000 Subject: [PATCH] * ira.c (ira_non_ordered_class_hard_regs): Define. (setup_class_hard_regs): Initialize ira_non_ordered_class_hard_regs. * ira-int.h (ira_non_ordered_class_hard_regs): Declare. * ira-costs.c (ira_tune_allocno_costs_and_cover_classes): Increase cost of unaligned hard regs when allocating multi-reg pseudos. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159644 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++++ gcc/ira-costs.c | 27 +++++++++++++++++++++++++++ gcc/ira-int.h | 5 +++++ gcc/ira.c | 14 +++++++++++++- 4 files changed, 53 insertions(+), 1 deletions(-) diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index 76aadff..6942931 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -1773,5 +1773,32 @@ ira_tune_allocno_costs_and_cover_classes (void) } if (min_cost != INT_MAX) ALLOCNO_COVER_CLASS_COST (a) = min_cost; + + /* Some targets allow pseudos to be allocated to unaligned + sequences of hard registers. However, selecting an unaligned + sequence can unnecessarily restrict later allocations. So + increase the cost of unaligned hard regs to encourage the use + of aligned hard regs. */ + { + int nregs, index; + + if ((nregs = ira_reg_class_nregs[cover_class][ALLOCNO_MODE (a)]) > 1) + { + ira_allocate_and_set_costs + (&ALLOCNO_HARD_REG_COSTS (a), cover_class, + ALLOCNO_COVER_CLASS_COST (a)); + reg_costs = ALLOCNO_HARD_REG_COSTS (a); + for (j = n - 1; j >= 0; j--) + { + if (j % nregs != 0) + { + regno = ira_non_ordered_class_hard_regs[cover_class][j]; + index = ira_class_hard_reg_index[cover_class][regno]; + ira_assert (index != 0); + reg_costs[index] += ALLOCNO_FREQ (a); + } + } + } + } } } diff --git a/gcc/ira-int.h b/gcc/ira-int.h index a32c837..6ee7393 100644 --- a/gcc/ira-int.h +++ b/gcc/ira-int.h @@ -743,6 +743,11 @@ extern move_table *ira_may_move_out_cost[MAX_MACHINE_MODE]; allocation. */ extern int ira_class_subset_p[N_REG_CLASSES][N_REG_CLASSES]; +/* Array of the number of hard registers of given class which are + available for allocation. The order is defined by the the hard + register numbers. */ +extern short ira_non_ordered_class_hard_regs[N_REG_CLASSES][FIRST_PSEUDO_REGISTER]; + /* Index (in ira_class_hard_regs) for given register class and hard register (in general case a hard register can belong to several register classes). The index is negative for hard registers diff --git a/gcc/ira.c b/gcc/ira.c index 8e34392..372539e 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -413,6 +413,11 @@ static HARD_REG_SET no_unit_alloc_regs; allocation order. */ short ira_class_hard_regs[N_REG_CLASSES][FIRST_PSEUDO_REGISTER]; +/* Array of the number of hard registers of given class which are + available for allocation. The order is defined by the + the hard register numbers. */ +short ira_non_ordered_class_hard_regs[N_REG_CLASSES][FIRST_PSEUDO_REGISTER]; + /* The number of elements of the above array for given register class. */ int ira_class_hard_regs_num[N_REG_CLASSES]; @@ -437,7 +442,10 @@ setup_class_hard_regs (void) AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); CLEAR_HARD_REG_SET (processed_hard_reg_set); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - ira_class_hard_reg_index[cl][0] = -1; + { + ira_non_ordered_class_hard_regs[cl][0] = -1; + ira_class_hard_reg_index[cl][0] = -1; + } for (n = 0, i = 0; i < FIRST_PSEUDO_REGISTER; i++) { #ifdef REG_ALLOC_ORDER @@ -457,6 +465,10 @@ setup_class_hard_regs (void) } } ira_class_hard_regs_num[cl] = n; + for (n = 0, i = 0; i < FIRST_PSEUDO_REGISTER; i++) + if (TEST_HARD_REG_BIT (temp_hard_regset, i)) + ira_non_ordered_class_hard_regs[cl][n++] = i; + ira_assert (ira_class_hard_regs_num[cl] == n); } } -- 1.7.3.4