From patchwork Wed May 30 18:24:38 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 162048 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id BCF09B7073 for ; Thu, 31 May 2012 04:25:06 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1339007107; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:From:To:Mail-Followup-To:Cc:Subject:References:Date: In-Reply-To:Message-ID:User-Agent:MIME-Version:Content-Type: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=ThP/tKXa8R0xijJSc9sU 5y2WvsQ=; b=oli57ikBbtrwsXfotxqeUJeJOzXmXHrbCCtHwbQEG9+Sb3n3hZ70 C/cX6iP7H52dJkF260c6K75K/kiEvdtxErr0gpOL6/91a+HUWXFpSgOLZH2S4JL8 aifdj/1dwHFsz7WtoRoZy1Qxgn+dJe3Q8cYBB7Piebd+aMgJcLhX7VI= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:From:To:Mail-Followup-To:Cc:Subject:References:Date:In-Reply-To:Message-ID:User-Agent:MIME-Version:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=OiR2x7gY4bh2R9UY+kCj/g7qjglHjL6hNPNgQFvGtUSXSItrQqw7MRenLNQo50 V3uQK6PUGD6HyGAQtXOF/IFunnrT3CryQQyNOhtwA2bKC8TQR1D4i7K3viHiG8y+ 2VTB6Z+NhIGC1+5GKovZRfkfYoApp0mNx0u+zvnNXmg3w=; Received: (qmail 27485 invoked by alias); 30 May 2012 18:25:00 -0000 Received: (qmail 27470 invoked by uid 22791); 30 May 2012 18:24:56 -0000 X-SWARE-Spam-Status: No, hits=-4.1 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, TW_EG X-Spam-Check-By: sourceware.org Received: from mail-wg0-f41.google.com (HELO mail-wg0-f41.google.com) (74.125.82.41) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 30 May 2012 18:24:42 +0000 Received: by wgbds1 with SMTP id ds1so3674723wgb.2 for ; Wed, 30 May 2012 11:24:40 -0700 (PDT) Received: by 10.216.210.229 with SMTP id u79mr3095687weo.31.1338402280455; Wed, 30 May 2012 11:24:40 -0700 (PDT) Received: from localhost (rsandifo.gotadsl.co.uk. [82.133.89.107]) by mx.google.com with ESMTPS id j4sm36608880wiz.1.2012.05.30.11.24.38 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 30 May 2012 11:24:39 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, vmakarov@redhat.com, rdsandiford@googlemail.com Cc: vmakarov@redhat.com Subject: [3/7] Tidy IRA move costs References: <87d35lh72w.fsf@talisman.home> Date: Wed, 30 May 2012 19:24:38 +0100 In-Reply-To: <87d35lh72w.fsf@talisman.home> (Richard Sandiford's message of "Wed, 30 May 2012 19:11:51 +0100") Message-ID: <87zk8pfrx5.fsf@talisman.home> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org After the preceding patch, only ira_init_register_move_cost uses the regclass costs directly. This patch moves them to IRA and makes init_move_cost static to it. This is just a stepping stone to make the later patches easier to review. Richard gcc/ * 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. Index: gcc/regs.h =================================================================== --- gcc/regs.h 2012-05-29 19:11:06.079795522 +0100 +++ gcc/regs.h 2012-05-29 19:27:41.214766589 +0100 @@ -240,8 +240,6 @@ #define HARD_REGNO_CALLER_SAVE_MODE(REGN #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 @@ #define have_regs_of_mode \ (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 \ Index: gcc/ira-int.h =================================================================== --- gcc/ira-int.h 2012-05-29 19:11:06.079795522 +0100 +++ gcc/ira-int.h 2012-05-29 19:27:41.207766589 +0100 @@ -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 @@ #define this_target_ira_int (&default_ta #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 \ Index: gcc/rtl.h =================================================================== --- gcc/rtl.h 2012-05-29 19:11:06.080795522 +0100 +++ gcc/rtl.h 2012-05-29 19:27:41.216766589 +0100 @@ -2045,8 +2045,6 @@ extern rtx remove_free_EXPR_LIST_node (r /* 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. */ Index: gcc/reginfo.c =================================================================== --- gcc/reginfo.c 2012-05-29 19:11:06.079795522 +0100 +++ gcc/reginfo.c 2012-05-29 19:27:41.213766589 +0100 @@ -122,9 +122,6 @@ static const char *const initial_reg_nam /* 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 = ®_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 = ®_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. Index: gcc/ira.c =================================================================== --- gcc/ira.c 2012-05-29 19:19:03.148781651 +0100 +++ gcc/ira.c 2012-05-29 19:27:44.126766505 +0100 @@ -423,6 +423,8 @@ struct ira_spilled_reg_stack_slot *ira_s /* 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 = ®_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 = ®_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]);