From patchwork Mon Dec 5 17:04:16 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Makarov X-Patchwork-Id: 129366 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 324661007D4 for ; Tue, 6 Dec 2011 04:05:03 +1100 (EST) Received: (qmail 8648 invoked by alias); 5 Dec 2011 17:04:58 -0000 Received: (qmail 8606 invoked by uid 22791); 5 Dec 2011 17:04:43 -0000 X-SWARE-Spam-Status: No, hits=-7.0 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 05 Dec 2011 17:04:18 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id pB5H4HJT030653 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 5 Dec 2011 12:04:17 -0500 Received: from toll.yyz.redhat.com (unused [10.15.16.165] (may be forged)) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id pB5H4GdP028097 for ; Mon, 5 Dec 2011 12:04:17 -0500 Message-ID: <4EDCF990.7090903@redhat.com> Date: Mon, 05 Dec 2011 12:04:16 -0500 From: Vladimir Makarov User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.23) Gecko/20110928 Fedora/3.1.15-1.fc14 Thunderbird/3.1.15 MIME-Version: 1.0 To: gcc-patches Subject: patch to fix PR50775 X-IsSubscribed: yes 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 The following patch fixes PR50775. The problem is described on http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50775. The patch moves data concerning profitable regs from objects to allocnos. It was a mistake to calculate profitable regs for objects because allocno start hard register defines all its object hard registers. Most changes in the patch is mostly renaming reflecting moving the data form objects to allocnos. The patch also excludes a repeated updating conflict costs in case of multi-objects allocnos which I found when worked on PR. That was not as it was designed originally. These changes results in only 4 insignificant code changes in SPEC2000 for x86 (where there is a bigger probability for multi-objects allocnos cases than for x86-64). For programs where there are no multi-objects allocnos (most programs especially for 64-bit targets), there should be no changes in the generated code. The patch was successfully bootstrapped for x86/x86-64, ppc64, and itanium. Committed to the trunk as rev. 182015. 2011-12-05 Vladimir Makarov PR other/50775 * ira-int.h (struct ira_object): Remove add_data. (OBJECT_ADD_DATA): Remove. * ira-build.c (ira_create_object): Remove OBJECT_ADD_DATA initialization. * ira-color.c (object_hard_regs_t, object_hard_regs): Rename to allocno_hard_regs_t, allocno_hard_regs. (object_hard_regs_node_t, object_hard_regs_node): Rename to allocno_hard_regs_node_t and allocno_hard_regs_node. (struct allocno_color_data): Add new member last_process. Move profitable_hard_regs, hard_regs_node, and hard_regs_subnodes_start from object_color_data. (object_color_data_t, object_color_data, OBJECT_COLOR_DATA): Remove. (curr_allocno_process): New static variable. (object_hard_regs_eq, object_hard_regs_htab): Rename to allocno_hard_regs_eq and allocno_hard_regs_htab. (init_object_hard_regs, finish_object_hard_regs): Rename to init_allocno_hard_regs and finish_allocno_hard_regs. (object_hard_regs_compare, object_hard_regs_node_t): Rename to allocno_hard_regs_compare and allocno_hard_regs_node_t. (create_new_object_hard_regs_node): Rename to create_new_allocno_hard_regs_node. (add_new_object_hard_regs_node_to_forest): Rename to add_new_allocno_hard_regs_node_to_forest. (add_object_hard_regs_to_forest, collect_object_hard_regs_cover): Rename to add_allocno_hard_regs_to_forest and collect_allocno_hard_regs_cover. (setup_object_hard_regs_nodes_parent): Rename to setup_allocno_hard_regs_nodes_parent. (remove_unused_object_hard_regs_nodes): Rename to remove_unused_allocno_hard_regs_nodes. (enumerate_object_hard_regs_nodes, object_hard_regs_nodes_num): Rename to enumerate_allocno_hard_regs_nodes and allocno_hard_regs_nodes_num. (object_hard_regs_nodes, object_hard_regs_subnode_t): Rename to allocno_hard_regs_nodes and allocno_hard_regs_subnode_t. (object_hard_regs_subnode, object_hard_regs_subnodes): Rename to allocno_hard_regs_subnode and allocno_hard_regs_subnodes. (object_hard_regs_subnode_index): Rename to allocno_hard_regs_subnode_index. (setup_object_hard_regs_subnode_index): Rename to setup_allocno_hard_regs_subnode_index. (get_object_hard_regs_subnodes_num): Rename to get_allocno_hard_regs_subnodes_num. (form_object_hard_regs_nodes_forest): Rename to form_allocno_hard_regs_nodes_forest. (finish_object_hard_regs_nodes_tree): Rename to form_allocno_hard_regs_nodes_forest (finish_object_hard_regs_nodes_forest): Rename to finish_allocno_hard_regs_nodes_forest. (setup_left_conflict_sizes_p): Use allocno data instead of object ones. Process conflict allocnos once. (update_left_conflict_sizes_p): Use allocno data instead of object ones. Change prototype signature. (empty_profitable_hard_regs): Use allocno data instead of object ones. (setup_profitable_hard_regs): Ditto. (get_conflict_profitable_regs): Rename to get_conflict_and_start_profitable_regs. Use allocno data for profitable regs calculation. (check_hard_reg_p): Change prototype signature. Check profitable regs for allocno not the objects. (assign_hard_reg): Process conflict allocnos only once for updating conflict costs. (setup_allocno_available_regs_num): Use allocno data instead of object ones. Modify debug output. (color_pass): Remove initialization and finalization of object color data. Index: ira-int.h =================================================================== --- ira-int.h (revision 181892) +++ ira-int.h (working copy) @@ -262,9 +262,6 @@ struct ira_object ira_object structures. Otherwise, we use a bit vector indexed by conflict ID numbers. */ unsigned int conflict_vec_p : 1; - /* Different additional data. It is used to decrease size of - allocno data footprint. */ - void *add_data; }; /* A structure representing an allocno (allocation entity). Allocno @@ -499,7 +496,6 @@ allocno_emit_reg (ira_allocno_t a) #define OBJECT_MAX(O) ((O)->max) #define OBJECT_CONFLICT_ID(O) ((O)->id) #define OBJECT_LIVE_RANGES(O) ((O)->live_ranges) -#define OBJECT_ADD_DATA(O) ((O)->add_data) /* Map regno -> allocnos with given regno (see comments for allocno member `next_regno_allocno'). */ Index: ira-color.c =================================================================== --- ira-color.c (revision 181892) +++ ira-color.c (working copy) @@ -39,15 +39,15 @@ along with GCC; see the file COPYING3. #include "df.h" #include "ira-int.h" -typedef struct object_hard_regs *object_hard_regs_t; +typedef struct allocno_hard_regs *allocno_hard_regs_t; /* The structure contains information about hard registers can be - assigned to objects. Usually it is allocno profitable hard + assigned to allocnos. Usually it is allocno profitable hard registers but in some cases this set can be a bit different. Major reason of the difference is a requirement to use hard register sets that form a tree or a forest (set of trees), i.e. hard register set of a node should contain hard register sets of its subnodes. */ -struct object_hard_regs +struct allocno_hard_regs { /* Hard registers can be assigned to an allocno. */ HARD_REG_SET set; @@ -56,14 +56,14 @@ struct object_hard_regs long long int cost; }; -typedef struct object_hard_regs_node *object_hard_regs_node_t; +typedef struct allocno_hard_regs_node *allocno_hard_regs_node_t; -/* A node representing object hard registers. Such nodes form a +/* A node representing allocno hard registers. Such nodes form a forest (set of trees). Each subnode of given node in the forest - refers for hard register set (usually object profitable hard + refers for hard register set (usually allocno profitable hard register set) which is a subset of one referred from given node. */ -struct object_hard_regs_node +struct allocno_hard_regs_node { /* Set up number of the node in preorder traversing of the forest. */ int preorder_num; @@ -71,7 +71,7 @@ struct object_hard_regs_node allocno. */ int check; /* Used for calculation of conflict size of an allocno. The - conflict size of the allocno is maximal number of given object + conflict size of the allocno is maximal number of given allocno hard registers needed for allocation of the conflicting allocnos. Given allocno is trivially colored if this number plus the number of hard registers needed for given allocno is not greater than @@ -82,10 +82,10 @@ struct object_hard_regs_node /* The following member is used to form the final forest. */ bool used_p; /* Pointer to the corresponding profitable hard registers. */ - object_hard_regs_t hard_regs; + allocno_hard_regs_t hard_regs; /* Parent, first subnode, previous and next node with the same parent in the forest. */ - object_hard_regs_node_t parent, first, prev, next; + allocno_hard_regs_node_t parent, first, prev, next; }; /* To decrease footprint of ira_allocno structure we store all data @@ -98,7 +98,7 @@ struct allocno_color_data /* TRUE if it is put on the stack to make other allocnos colorable. */ unsigned int may_be_spilled_p : 1; - /* TRUE if the object is trivially colorable. */ + /* TRUE if the allocno is trivially colorable. */ unsigned int colorable_p : 1; /* Number of hard registers of the allocno class really available for the allocno allocation. It is number of the @@ -110,31 +110,18 @@ struct allocno_color_data ira_allocno_t prev_bucket_allocno; /* Used for temporary purposes. */ int temp; -}; - -/* See above. */ -typedef struct allocno_color_data *allocno_color_data_t; - -/* Container for storing allocno data concerning coloring. */ -static allocno_color_data_t allocno_color_data; - -/* Macro to access the data concerning coloring. */ -#define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a)) - -/* To decrease footprint of ira_object structure we store all data - needed only for coloring in the following structure. */ -struct object_color_data -{ + /* Used to exclude repeated processing. */ + int last_process; /* Profitable hard regs available for this pseudo allocation. It means that the set excludes unavailable hard regs and hard regs conflicting with given pseudo. They should be of the allocno class. */ HARD_REG_SET profitable_hard_regs; - /* The object hard registers node. */ - object_hard_regs_node_t hard_regs_node; - /* Array of structures object_hard_regs_subnode representing - given object hard registers node (the 1st element in the array) - and all its subnodes in the tree (forest) of object hard + /* The allocno hard registers node. */ + allocno_hard_regs_node_t hard_regs_node; + /* Array of structures allocno_hard_regs_subnode representing + given allocno hard registers node (the 1st element in the array) + and all its subnodes in the tree (forest) of allocno hard register nodes (see comments above). */ int hard_regs_subnodes_start; /* The length of the previous array. */ @@ -142,13 +129,18 @@ struct object_color_data }; /* See above. */ -typedef struct object_color_data *object_color_data_t; +typedef struct allocno_color_data *allocno_color_data_t; -/* Container for storing object data concerning coloring. */ -static object_color_data_t object_color_data; +/* Container for storing allocno data concerning coloring. */ +static allocno_color_data_t allocno_color_data; /* Macro to access the data concerning coloring. */ -#define OBJECT_COLOR_DATA(o) ((object_color_data_t) OBJECT_ADD_DATA (o)) +#define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a)) + +/* Used for finding allocno colorability to exclude repeated allocno + processing and for updating preferencing to exclude repeated + allocno processing during assignment. */ +static int curr_allocno_process; /* This file contains code for regional graph coloring, spill/restore code placement optimization, and code helping the reload pass to do @@ -177,70 +169,70 @@ static VEC(ira_allocno_t,heap) *allocno_ -/* Definition of vector of object hard registers. */ -DEF_VEC_P(object_hard_regs_t); -DEF_VEC_ALLOC_P(object_hard_regs_t, heap); +/* Definition of vector of allocno hard registers. */ +DEF_VEC_P(allocno_hard_regs_t); +DEF_VEC_ALLOC_P(allocno_hard_regs_t, heap); -/* Vector of unique object hard registers. */ -static VEC(object_hard_regs_t, heap) *object_hard_regs_vec; +/* Vector of unique allocno hard registers. */ +static VEC(allocno_hard_regs_t, heap) *allocno_hard_regs_vec; -/* Returns hash value for object hard registers V. */ +/* Returns hash value for allocno hard registers V. */ static hashval_t -object_hard_regs_hash (const void *v) +allocno_hard_regs_hash (const void *v) { - const struct object_hard_regs *hv = (const struct object_hard_regs *) v; + const struct allocno_hard_regs *hv = (const struct allocno_hard_regs *) v; return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0); } -/* Compares object hard registers V1 and V2. */ +/* Compares allocno hard registers V1 and V2. */ static int -object_hard_regs_eq (const void *v1, const void *v2) +allocno_hard_regs_eq (const void *v1, const void *v2) { - const struct object_hard_regs *hv1 = (const struct object_hard_regs *) v1; - const struct object_hard_regs *hv2 = (const struct object_hard_regs *) v2; + const struct allocno_hard_regs *hv1 = (const struct allocno_hard_regs *) v1; + const struct allocno_hard_regs *hv2 = (const struct allocno_hard_regs *) v2; return hard_reg_set_equal_p (hv1->set, hv2->set); } -/* Hash table of unique object hard registers. */ -static htab_t object_hard_regs_htab; +/* Hash table of unique allocno hard registers. */ +static htab_t allocno_hard_regs_htab; -/* Return object hard registers in the hash table equal to HV. */ -static object_hard_regs_t -find_hard_regs (object_hard_regs_t hv) +/* Return allocno hard registers in the hash table equal to HV. */ +static allocno_hard_regs_t +find_hard_regs (allocno_hard_regs_t hv) { - return (object_hard_regs_t) htab_find (object_hard_regs_htab, hv); + return (allocno_hard_regs_t) htab_find (allocno_hard_regs_htab, hv); } /* Insert allocno hard registers HV in the hash table (if it is not there yet) and return the value which in the table. */ -static object_hard_regs_t -insert_hard_regs (object_hard_regs_t hv) +static allocno_hard_regs_t +insert_hard_regs (allocno_hard_regs_t hv) { - PTR *slot = htab_find_slot (object_hard_regs_htab, hv, INSERT); + PTR *slot = htab_find_slot (allocno_hard_regs_htab, hv, INSERT); if (*slot == NULL) *slot = hv; - return (object_hard_regs_t) *slot; + return (allocno_hard_regs_t) *slot; } -/* Initialize data concerning object hard registers. */ +/* Initialize data concerning allocno hard registers. */ static void -init_object_hard_regs (void) +init_allocno_hard_regs (void) { - object_hard_regs_vec = VEC_alloc (object_hard_regs_t, heap, 200); - object_hard_regs_htab - = htab_create (200, object_hard_regs_hash, object_hard_regs_eq, NULL); + allocno_hard_regs_vec = VEC_alloc (allocno_hard_regs_t, heap, 200); + allocno_hard_regs_htab + = htab_create (200, allocno_hard_regs_hash, allocno_hard_regs_eq, NULL); } -/* Add (or update info about) object hard registers with SET and +/* Add (or update info about) allocno hard registers with SET and COST. */ -static object_hard_regs_t -add_object_hard_regs (HARD_REG_SET set, long long int cost) +static allocno_hard_regs_t +add_allocno_hard_regs (HARD_REG_SET set, long long int cost) { - struct object_hard_regs temp; - object_hard_regs_t hv; + struct allocno_hard_regs temp; + allocno_hard_regs_t hv; gcc_assert (! hard_reg_set_empty_p (set)); COPY_HARD_REG_SET (temp.set, set); @@ -248,11 +240,11 @@ add_object_hard_regs (HARD_REG_SET set, hv->cost += cost; else { - hv = ((struct object_hard_regs *) - ira_allocate (sizeof (struct object_hard_regs))); + hv = ((struct allocno_hard_regs *) + ira_allocate (sizeof (struct allocno_hard_regs))); COPY_HARD_REG_SET (hv->set, set); hv->cost = cost; - VEC_safe_push (object_hard_regs_t, heap, object_hard_regs_vec, hv); + VEC_safe_push (allocno_hard_regs_t, heap, allocno_hard_regs_vec, hv); insert_hard_regs (hv); } return hv; @@ -260,25 +252,25 @@ add_object_hard_regs (HARD_REG_SET set, /* Finalize data concerning allocno hard registers. */ static void -finish_object_hard_regs (void) +finish_allocno_hard_regs (void) { int i; - object_hard_regs_t hv; + allocno_hard_regs_t hv; for (i = 0; - VEC_iterate (object_hard_regs_t, object_hard_regs_vec, i, hv); + VEC_iterate (allocno_hard_regs_t, allocno_hard_regs_vec, i, hv); i++) ira_free (hv); - htab_delete (object_hard_regs_htab); - VEC_free (object_hard_regs_t, heap, object_hard_regs_vec); + htab_delete (allocno_hard_regs_htab); + VEC_free (allocno_hard_regs_t, heap, allocno_hard_regs_vec); } /* Sort hard regs according to their frequency of usage. */ static int -object_hard_regs_compare (const void *v1p, const void *v2p) +allocno_hard_regs_compare (const void *v1p, const void *v2p) { - object_hard_regs_t hv1 = *(const object_hard_regs_t *) v1p; - object_hard_regs_t hv2 = *(const object_hard_regs_t *) v2p; + allocno_hard_regs_t hv1 = *(const allocno_hard_regs_t *) v1p; + allocno_hard_regs_t hv2 = *(const allocno_hard_regs_t *) v2p; if (hv2->cost > hv1->cost) return 1; @@ -301,25 +293,25 @@ object_hard_regs_compare (const void *v1 static int node_check_tick; /* Roots of the forest containing hard register sets can be assigned - to objects. */ -static object_hard_regs_node_t hard_regs_roots; + to allocnos. */ +static allocno_hard_regs_node_t hard_regs_roots; -/* Definition of vector of object hard register nodes. */ -DEF_VEC_P(object_hard_regs_node_t); -DEF_VEC_ALLOC_P(object_hard_regs_node_t, heap); +/* Definition of vector of allocno hard register nodes. */ +DEF_VEC_P(allocno_hard_regs_node_t); +DEF_VEC_ALLOC_P(allocno_hard_regs_node_t, heap); /* Vector used to create the forest. */ -static VEC(object_hard_regs_node_t, heap) *hard_regs_node_vec; +static VEC(allocno_hard_regs_node_t, heap) *hard_regs_node_vec; -/* Create and return object hard registers node containing object +/* Create and return allocno hard registers node containing allocno hard registers HV. */ -static object_hard_regs_node_t -create_new_object_hard_regs_node (object_hard_regs_t hv) +static allocno_hard_regs_node_t +create_new_allocno_hard_regs_node (allocno_hard_regs_t hv) { - object_hard_regs_node_t new_node; + allocno_hard_regs_node_t new_node; - new_node = ((struct object_hard_regs_node *) - ira_allocate (sizeof (struct object_hard_regs_node))); + new_node = ((struct allocno_hard_regs_node *) + ira_allocate (sizeof (struct allocno_hard_regs_node))); new_node->check = 0; new_node->hard_regs = hv; new_node->hard_regs_num = hard_reg_set_size (hv->set); @@ -328,11 +320,11 @@ create_new_object_hard_regs_node (object return new_node; } -/* Add object hard registers node NEW_NODE to the forest on its level +/* Add allocno hard registers node NEW_NODE to the forest on its level given by ROOTS. */ static void -add_new_object_hard_regs_node_to_forest (object_hard_regs_node_t *roots, - object_hard_regs_node_t new_node) +add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t *roots, + allocno_hard_regs_node_t new_node) { new_node->next = *roots; if (new_node->next != NULL) @@ -341,58 +333,58 @@ add_new_object_hard_regs_node_to_forest *roots = new_node; } -/* Add object hard registers HV (or its best approximation if it is +/* Add allocno hard registers HV (or its best approximation if it is not possible) to the forest on its level given by ROOTS. */ static void -add_object_hard_regs_to_forest (object_hard_regs_node_t *roots, - object_hard_regs_t hv) +add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots, + allocno_hard_regs_t hv) { unsigned int i, start; - object_hard_regs_node_t node, prev, new_node; + allocno_hard_regs_node_t node, prev, new_node; HARD_REG_SET temp_set; - object_hard_regs_t hv2; + allocno_hard_regs_t hv2; - start = VEC_length (object_hard_regs_node_t, hard_regs_node_vec); + start = VEC_length (allocno_hard_regs_node_t, hard_regs_node_vec); for (node = *roots; node != NULL; node = node->next) { if (hard_reg_set_equal_p (hv->set, node->hard_regs->set)) return; if (hard_reg_set_subset_p (hv->set, node->hard_regs->set)) { - add_object_hard_regs_to_forest (&node->first, hv); + add_allocno_hard_regs_to_forest (&node->first, hv); return; } if (hard_reg_set_subset_p (node->hard_regs->set, hv->set)) - VEC_safe_push (object_hard_regs_node_t, heap, + VEC_safe_push (allocno_hard_regs_node_t, heap, hard_regs_node_vec, node); else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set)) { COPY_HARD_REG_SET (temp_set, hv->set); AND_HARD_REG_SET (temp_set, node->hard_regs->set); - hv2 = add_object_hard_regs (temp_set, hv->cost); - add_object_hard_regs_to_forest (&node->first, hv2); + hv2 = add_allocno_hard_regs (temp_set, hv->cost); + add_allocno_hard_regs_to_forest (&node->first, hv2); } } - if (VEC_length (object_hard_regs_node_t, hard_regs_node_vec) + if (VEC_length (allocno_hard_regs_node_t, hard_regs_node_vec) > start + 1) { /* Create a new node which contains nodes in hard_regs_node_vec. */ CLEAR_HARD_REG_SET (temp_set); for (i = start; - i < VEC_length (object_hard_regs_node_t, hard_regs_node_vec); + i < VEC_length (allocno_hard_regs_node_t, hard_regs_node_vec); i++) { - node = VEC_index (object_hard_regs_node_t, hard_regs_node_vec, i); + node = VEC_index (allocno_hard_regs_node_t, hard_regs_node_vec, i); IOR_HARD_REG_SET (temp_set, node->hard_regs->set); } - hv = add_object_hard_regs (temp_set, hv->cost); - new_node = create_new_object_hard_regs_node (hv); + hv = add_allocno_hard_regs (temp_set, hv->cost); + new_node = create_new_allocno_hard_regs_node (hv); prev = NULL; for (i = start; - i < VEC_length (object_hard_regs_node_t, hard_regs_node_vec); + i < VEC_length (allocno_hard_regs_node_t, hard_regs_node_vec); i++) { - node = VEC_index (object_hard_regs_node_t, hard_regs_node_vec, i); + node = VEC_index (allocno_hard_regs_node_t, hard_regs_node_vec, i); if (node->prev == NULL) *roots = node->next; else @@ -407,50 +399,50 @@ add_object_hard_regs_to_forest (object_h node->next = NULL; prev = node; } - add_new_object_hard_regs_node_to_forest (roots, new_node); + add_new_allocno_hard_regs_node_to_forest (roots, new_node); } - VEC_truncate (object_hard_regs_node_t, hard_regs_node_vec, start); + VEC_truncate (allocno_hard_regs_node_t, hard_regs_node_vec, start); } -/* Add object hard registers nodes starting with the forest level +/* Add allocno hard registers nodes starting with the forest level given by FIRST which contains biggest set inside SET. */ static void -collect_object_hard_regs_cover (object_hard_regs_node_t first, +collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first, HARD_REG_SET set) { - object_hard_regs_node_t node; + allocno_hard_regs_node_t node; ira_assert (first != NULL); for (node = first; node != NULL; node = node->next) if (hard_reg_set_subset_p (node->hard_regs->set, set)) - VEC_safe_push (object_hard_regs_node_t, heap, hard_regs_node_vec, + VEC_safe_push (allocno_hard_regs_node_t, heap, hard_regs_node_vec, node); else if (hard_reg_set_intersect_p (set, node->hard_regs->set)) - collect_object_hard_regs_cover (node->first, set); + collect_allocno_hard_regs_cover (node->first, set); } -/* Set up field parent as PARENT in all object hard registers nodes +/* Set up field parent as PARENT in all allocno hard registers nodes in forest given by FIRST. */ static void -setup_object_hard_regs_nodes_parent (object_hard_regs_node_t first, - object_hard_regs_node_t parent) +setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first, + allocno_hard_regs_node_t parent) { - object_hard_regs_node_t node; + allocno_hard_regs_node_t node; for (node = first; node != NULL; node = node->next) { node->parent = parent; - setup_object_hard_regs_nodes_parent (node->first, node); + setup_allocno_hard_regs_nodes_parent (node->first, node); } } -/* Return object hard registers node which is a first common ancestor +/* Return allocno hard registers node which is a first common ancestor node of FIRST and SECOND in the forest. */ -static object_hard_regs_node_t -first_common_ancestor_node (object_hard_regs_node_t first, - object_hard_regs_node_t second) +static allocno_hard_regs_node_t +first_common_ancestor_node (allocno_hard_regs_node_t first, + allocno_hard_regs_node_t second) { - object_hard_regs_node_t node; + allocno_hard_regs_node_t node; node_check_tick++; for (node = first; node != NULL; node = node->parent) @@ -490,14 +482,14 @@ print_hard_reg_set (FILE *f, HARD_REG_SE fprintf (f, "\n"); } -/* Print object hard register subforest given by ROOTS and its LEVEL +/* Print allocno hard register subforest given by ROOTS and its LEVEL to F. */ static void -print_hard_regs_subforest (FILE *f, object_hard_regs_node_t roots, +print_hard_regs_subforest (FILE *f, allocno_hard_regs_node_t roots, int level) { int i; - object_hard_regs_node_t node; + allocno_hard_regs_node_t node; for (node = roots; node != NULL; node = node->next) { @@ -511,7 +503,7 @@ print_hard_regs_subforest (FILE *f, obje } } -/* Print the object hard register forest to F. */ +/* Print the allocno hard register forest to F. */ static void print_hard_regs_forest (FILE *f) { @@ -519,26 +511,26 @@ print_hard_regs_forest (FILE *f) print_hard_regs_subforest (f, hard_regs_roots, 1); } -/* Print the object hard register forest to stderr. */ +/* Print the allocno hard register forest to stderr. */ void ira_debug_hard_regs_forest (void) { print_hard_regs_forest (stderr); } -/* Remove unused object hard registers nodes from forest given by its +/* Remove unused allocno hard registers nodes from forest given by its *ROOTS. */ static void -remove_unused_object_hard_regs_nodes (object_hard_regs_node_t *roots) +remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t *roots) { - object_hard_regs_node_t node, prev, next, last; + allocno_hard_regs_node_t node, prev, next, last; for (prev = NULL, node = *roots; node != NULL; node = next) { next = node->next; if (node->used_p) { - remove_unused_object_hard_regs_nodes (&node->first); + remove_unused_allocno_hard_regs_nodes (&node->first); prev = node; } else @@ -572,45 +564,45 @@ remove_unused_object_hard_regs_nodes (ob } } -/* Set up fields preorder_num starting with START_NUM in all object +/* Set up fields preorder_num starting with START_NUM in all allocno hard registers nodes in forest given by FIRST. Return biggest set PREORDER_NUM increased by 1. */ static int -enumerate_object_hard_regs_nodes (object_hard_regs_node_t first, - object_hard_regs_node_t parent, - int start_num) +enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first, + allocno_hard_regs_node_t parent, + int start_num) { - object_hard_regs_node_t node; + allocno_hard_regs_node_t node; for (node = first; node != NULL; node = node->next) { node->preorder_num = start_num++; node->parent = parent; - start_num = enumerate_object_hard_regs_nodes (node->first, node, - start_num); + start_num = enumerate_allocno_hard_regs_nodes (node->first, node, + start_num); } return start_num; } -/* Number of object hard registers nodes in the forest. */ -static int object_hard_regs_nodes_num; +/* Number of allocno hard registers nodes in the forest. */ +static int allocno_hard_regs_nodes_num; -/* Table preorder number of object hard registers node in the forest - -> the object hard registers node. */ -static object_hard_regs_node_t *object_hard_regs_nodes; +/* Table preorder number of allocno hard registers node in the forest + -> the allocno hard registers node. */ +static allocno_hard_regs_node_t *allocno_hard_regs_nodes; /* See below. */ -typedef struct object_hard_regs_subnode *object_hard_regs_subnode_t; +typedef struct allocno_hard_regs_subnode *allocno_hard_regs_subnode_t; /* The structure is used to describes all subnodes (not only immediate - ones) in the mentioned above tree for given object hard register + ones) in the mentioned above tree for given allocno hard register node. The usage of such data accelerates calculation of colorability of given allocno. */ -struct object_hard_regs_subnode +struct allocno_hard_regs_subnode { /* The conflict size of conflicting allocnos whose hard register sets are equal sets (plus supersets if given node is given - object hard registers node) of one in the given node. */ + allocno hard registers node) of one in the given node. */ int left_conflict_size; /* The summary conflict size of conflicting allocnos whose hard register sets are strict subsets of one in the given node. @@ -623,200 +615,187 @@ struct object_hard_regs_subnode short max_node_impact; }; -/* Container for hard regs subnodes of all objects. */ -static object_hard_regs_subnode_t object_hard_regs_subnodes; +/* Container for hard regs subnodes of all allocnos. */ +static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes; -/* Table (preorder number of object hard registers node in the - forest, preorder number of object hard registers subnode) -> index +/* Table (preorder number of allocno hard registers node in the + forest, preorder number of allocno hard registers subnode) -> index of the subnode relative to the node. -1 if it is not a subnode. */ -static int *object_hard_regs_subnode_index; +static int *allocno_hard_regs_subnode_index; -/* Setup arrays OBJECT_HARD_REGS_NODES and - OBJECT_HARD_REGS_SUBNODE_INDEX. */ +/* Setup arrays ALLOCNO_HARD_REGS_NODES and + ALLOCNO_HARD_REGS_SUBNODE_INDEX. */ static void -setup_object_hard_regs_subnode_index (object_hard_regs_node_t first) +setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first) { - object_hard_regs_node_t node, parent; + allocno_hard_regs_node_t node, parent; int index; for (node = first; node != NULL; node = node->next) { - object_hard_regs_nodes[node->preorder_num] = node; + allocno_hard_regs_nodes[node->preorder_num] = node; for (parent = node; parent != NULL; parent = parent->parent) { - index = parent->preorder_num * object_hard_regs_nodes_num; - object_hard_regs_subnode_index[index + node->preorder_num] + index = parent->preorder_num * allocno_hard_regs_nodes_num; + allocno_hard_regs_subnode_index[index + node->preorder_num] = node->preorder_num - parent->preorder_num; } - setup_object_hard_regs_subnode_index (node->first); + setup_allocno_hard_regs_subnode_index (node->first); } } -/* Count all object hard registers nodes in tree ROOT. */ +/* Count all allocno hard registers nodes in tree ROOT. */ static int -get_object_hard_regs_subnodes_num (object_hard_regs_node_t root) +get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root) { int len = 1; for (root = root->first; root != NULL; root = root->next) - len += get_object_hard_regs_subnodes_num (root); + len += get_allocno_hard_regs_subnodes_num (root); return len; } -/* Build the forest of object hard registers nodes and assign each +/* Build the forest of allocno hard registers nodes and assign each allocno a node from the forest. */ static void -form_object_hard_regs_nodes_forest (void) +form_allocno_hard_regs_nodes_forest (void) { unsigned int i, j, size, len; - int start, k; + int start; ira_allocno_t a; - object_hard_regs_t hv; + allocno_hard_regs_t hv; bitmap_iterator bi; HARD_REG_SET temp; - object_hard_regs_node_t node, object_hard_regs_node; + allocno_hard_regs_node_t node, allocno_hard_regs_node; + allocno_color_data_t allocno_data; node_check_tick = 0; - init_object_hard_regs (); + init_allocno_hard_regs (); hard_regs_roots = NULL; - hard_regs_node_vec = VEC_alloc (object_hard_regs_node_t, heap, 100); + hard_regs_node_vec = VEC_alloc (allocno_hard_regs_node_t, heap, 100); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, i)) { CLEAR_HARD_REG_SET (temp); SET_HARD_REG_BIT (temp, i); - hv = add_object_hard_regs (temp, 0); - node = create_new_object_hard_regs_node (hv); - add_new_object_hard_regs_node_to_forest (&hard_regs_roots, node); + hv = add_allocno_hard_regs (temp, 0); + node = create_new_allocno_hard_regs_node (hv); + add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots, node); } - start = VEC_length (object_hard_regs_t, object_hard_regs_vec); + start = VEC_length (allocno_hard_regs_t, allocno_hard_regs_vec); EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi) { a = ira_allocnos[i]; - for (k = 0; k < ALLOCNO_NUM_OBJECTS (a); k++) - { - ira_object_t obj = ALLOCNO_OBJECT (a, k); - object_color_data_t obj_data = OBJECT_COLOR_DATA (obj); - - if (hard_reg_set_empty_p (obj_data->profitable_hard_regs)) - continue; - hv = (add_object_hard_regs - (obj_data->profitable_hard_regs, - ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))); - } + allocno_data = ALLOCNO_COLOR_DATA (a); + + if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs)) + continue; + hv = (add_allocno_hard_regs + (allocno_data->profitable_hard_regs, + ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))); } SET_HARD_REG_SET (temp); AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs); - add_object_hard_regs (temp, 0); - qsort (VEC_address (object_hard_regs_t, object_hard_regs_vec) + start, - VEC_length (object_hard_regs_t, object_hard_regs_vec) - start, - sizeof (object_hard_regs_t), object_hard_regs_compare); + add_allocno_hard_regs (temp, 0); + qsort (VEC_address (allocno_hard_regs_t, allocno_hard_regs_vec) + start, + VEC_length (allocno_hard_regs_t, allocno_hard_regs_vec) - start, + sizeof (allocno_hard_regs_t), allocno_hard_regs_compare); for (i = start; - VEC_iterate (object_hard_regs_t, object_hard_regs_vec, i, hv); + VEC_iterate (allocno_hard_regs_t, allocno_hard_regs_vec, i, hv); i++) { - add_object_hard_regs_to_forest (&hard_regs_roots, hv); - ira_assert (VEC_length (object_hard_regs_node_t, + add_allocno_hard_regs_to_forest (&hard_regs_roots, hv); + ira_assert (VEC_length (allocno_hard_regs_node_t, hard_regs_node_vec) == 0); } /* We need to set up parent fields for right work of first_common_ancestor_node. */ - setup_object_hard_regs_nodes_parent (hard_regs_roots, NULL); + setup_allocno_hard_regs_nodes_parent (hard_regs_roots, NULL); EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi) { a = ira_allocnos[i]; - for (k = 0; k < ALLOCNO_NUM_OBJECTS (a); k++) - { - ira_object_t obj = ALLOCNO_OBJECT (a, k); - object_color_data_t obj_data = OBJECT_COLOR_DATA (obj); - - if (hard_reg_set_empty_p (obj_data->profitable_hard_regs)) - continue; - VEC_truncate (object_hard_regs_node_t, hard_regs_node_vec, 0); - collect_object_hard_regs_cover (hard_regs_roots, - obj_data->profitable_hard_regs); - object_hard_regs_node = NULL; - for (j = 0; - VEC_iterate (object_hard_regs_node_t, hard_regs_node_vec, - j, node); - j++) - object_hard_regs_node - = (j == 0 - ? node - : first_common_ancestor_node (node, object_hard_regs_node)); - /* That is a temporary storage. */ - object_hard_regs_node->used_p = true; - obj_data->hard_regs_node = object_hard_regs_node; - } + allocno_data = ALLOCNO_COLOR_DATA (a); + if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs)) + continue; + VEC_truncate (allocno_hard_regs_node_t, hard_regs_node_vec, 0); + collect_allocno_hard_regs_cover (hard_regs_roots, + allocno_data->profitable_hard_regs); + allocno_hard_regs_node = NULL; + for (j = 0; + VEC_iterate (allocno_hard_regs_node_t, hard_regs_node_vec, + j, node); + j++) + allocno_hard_regs_node + = (j == 0 + ? node + : first_common_ancestor_node (node, allocno_hard_regs_node)); + /* That is a temporary storage. */ + allocno_hard_regs_node->used_p = true; + allocno_data->hard_regs_node = allocno_hard_regs_node; } ira_assert (hard_regs_roots->next == NULL); hard_regs_roots->used_p = true; - remove_unused_object_hard_regs_nodes (&hard_regs_roots); - object_hard_regs_nodes_num - = enumerate_object_hard_regs_nodes (hard_regs_roots, NULL, 0); - object_hard_regs_nodes - = ((object_hard_regs_node_t *) - ira_allocate (object_hard_regs_nodes_num - * sizeof (object_hard_regs_node_t))); - size = object_hard_regs_nodes_num * object_hard_regs_nodes_num; - object_hard_regs_subnode_index + remove_unused_allocno_hard_regs_nodes (&hard_regs_roots); + allocno_hard_regs_nodes_num + = enumerate_allocno_hard_regs_nodes (hard_regs_roots, NULL, 0); + allocno_hard_regs_nodes + = ((allocno_hard_regs_node_t *) + ira_allocate (allocno_hard_regs_nodes_num + * sizeof (allocno_hard_regs_node_t))); + size = allocno_hard_regs_nodes_num * allocno_hard_regs_nodes_num; + allocno_hard_regs_subnode_index = (int *) ira_allocate (size * sizeof (int)); for (i = 0; i < size; i++) - object_hard_regs_subnode_index[i] = -1; - setup_object_hard_regs_subnode_index (hard_regs_roots); + allocno_hard_regs_subnode_index[i] = -1; + setup_allocno_hard_regs_subnode_index (hard_regs_roots); start = 0; EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi) { a = ira_allocnos[i]; - for (k = 0; k < ALLOCNO_NUM_OBJECTS (a); k++) - { - ira_object_t obj = ALLOCNO_OBJECT (a, k); - object_color_data_t obj_data = OBJECT_COLOR_DATA (obj); - - if (hard_reg_set_empty_p (obj_data->profitable_hard_regs)) - continue; - len = get_object_hard_regs_subnodes_num (obj_data->hard_regs_node); - obj_data->hard_regs_subnodes_start = start; - obj_data->hard_regs_subnodes_num = len; - start += len; - } + allocno_data = ALLOCNO_COLOR_DATA (a); + if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs)) + continue; + len = get_allocno_hard_regs_subnodes_num (allocno_data->hard_regs_node); + allocno_data->hard_regs_subnodes_start = start; + allocno_data->hard_regs_subnodes_num = len; + start += len; } - object_hard_regs_subnodes - = ((object_hard_regs_subnode_t) - ira_allocate (sizeof (struct object_hard_regs_subnode) * start)); - VEC_free (object_hard_regs_node_t, heap, hard_regs_node_vec); + allocno_hard_regs_subnodes + = ((allocno_hard_regs_subnode_t) + ira_allocate (sizeof (struct allocno_hard_regs_subnode) * start)); + VEC_free (allocno_hard_regs_node_t, heap, hard_regs_node_vec); } -/* Free tree of object hard registers nodes given by its ROOT. */ +/* Free tree of allocno hard registers nodes given by its ROOT. */ static void -finish_object_hard_regs_nodes_tree (object_hard_regs_node_t root) +finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root) { - object_hard_regs_node_t child, next; + allocno_hard_regs_node_t child, next; for (child = root->first; child != NULL; child = next) { next = child->next; - finish_object_hard_regs_nodes_tree (child); + finish_allocno_hard_regs_nodes_tree (child); } ira_free (root); } -/* Finish work with the forest of object hard registers nodes. */ +/* Finish work with the forest of allocno hard registers nodes. */ static void -finish_object_hard_regs_nodes_forest (void) +finish_allocno_hard_regs_nodes_forest (void) { - object_hard_regs_node_t node, next; + allocno_hard_regs_node_t node, next; - ira_free (object_hard_regs_subnodes); + ira_free (allocno_hard_regs_subnodes); for (node = hard_regs_roots; node != NULL; node = next) { next = node->next; - finish_object_hard_regs_nodes_tree (node); + finish_allocno_hard_regs_nodes_tree (node); } - ira_free (object_hard_regs_nodes); - ira_free (object_hard_regs_subnode_index); - finish_object_hard_regs (); + ira_free (allocno_hard_regs_nodes); + ira_free (allocno_hard_regs_subnode_index); + finish_allocno_hard_regs (); } /* Set up left conflict sizes and left conflict subnodes sizes of hard @@ -825,46 +804,47 @@ finish_object_hard_regs_nodes_forest (vo static bool setup_left_conflict_sizes_p (ira_allocno_t a) { - int k, nobj, conflict_size; + int i, k, nobj, start; + int conflict_size, left_conflict_subnodes_size, node_preorder_num; allocno_color_data_t data; + HARD_REG_SET profitable_hard_regs; + allocno_hard_regs_subnode_t subnodes; + allocno_hard_regs_node_t node; + HARD_REG_SET node_set; nobj = ALLOCNO_NUM_OBJECTS (a); conflict_size = 0; data = ALLOCNO_COLOR_DATA (a); + subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start; + COPY_HARD_REG_SET (profitable_hard_regs, data->profitable_hard_regs); + node = data->hard_regs_node; + node_preorder_num = node->preorder_num; + COPY_HARD_REG_SET (node_set, node->hard_regs->set); + node_check_tick++; + curr_allocno_process++; for (k = 0; k < nobj; k++) { - int i, node_preorder_num, start, left_conflict_subnodes_size; - HARD_REG_SET profitable_hard_regs; - object_hard_regs_subnode_t subnodes; - object_hard_regs_node_t node; - HARD_REG_SET node_set; ira_object_t obj = ALLOCNO_OBJECT (a, k); ira_object_t conflict_obj; ira_object_conflict_iterator oci; - object_color_data_t obj_data; - node_check_tick++; - obj_data = OBJECT_COLOR_DATA (obj); - subnodes = object_hard_regs_subnodes + obj_data->hard_regs_subnodes_start; - COPY_HARD_REG_SET (profitable_hard_regs, obj_data->profitable_hard_regs); - node = obj_data->hard_regs_node; - node_preorder_num = node->preorder_num; - COPY_HARD_REG_SET (node_set, node->hard_regs->set); FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci) { int size; ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj); - object_hard_regs_node_t conflict_node, temp_node; + allocno_hard_regs_node_t conflict_node, temp_node; HARD_REG_SET conflict_node_set; - object_color_data_t conflict_obj_data; + allocno_color_data_t conflict_data; - conflict_obj_data = OBJECT_COLOR_DATA (conflict_obj); + conflict_data = ALLOCNO_COLOR_DATA (conflict_a); if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p + || conflict_data->last_process == curr_allocno_process || ! hard_reg_set_intersect_p (profitable_hard_regs, - conflict_obj_data + conflict_data ->profitable_hard_regs)) continue; - conflict_node = conflict_obj_data->hard_regs_node; + conflict_data->last_process = curr_allocno_process; + conflict_node = conflict_data->hard_regs_node; COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set); if (hard_reg_set_subset_p (node_set, conflict_node_set)) temp_node = node; @@ -885,164 +865,139 @@ setup_left_conflict_sizes_p (ira_allocno size = 1; temp_node->conflict_size += size; } - for (i = 0; i < obj_data->hard_regs_subnodes_num; i++) + } + for (i = 0; i < data->hard_regs_subnodes_num; i++) + { + allocno_hard_regs_node_t temp_node; + + temp_node = allocno_hard_regs_nodes[i + node_preorder_num]; + ira_assert (temp_node->preorder_num == i + node_preorder_num); + subnodes[i].left_conflict_size = (temp_node->check != node_check_tick + ? 0 : temp_node->conflict_size); + if (hard_reg_set_subset_p (temp_node->hard_regs->set, + profitable_hard_regs)) + subnodes[i].max_node_impact = temp_node->hard_regs_num; + else { - object_hard_regs_node_t temp_node; - - temp_node = object_hard_regs_nodes[i + node_preorder_num]; - ira_assert (temp_node->preorder_num == i + node_preorder_num); - subnodes[i].left_conflict_size = (temp_node->check != node_check_tick - ? 0 : temp_node->conflict_size); - if (hard_reg_set_subset_p (temp_node->hard_regs->set, - profitable_hard_regs)) - subnodes[i].max_node_impact = temp_node->hard_regs_num; - else + HARD_REG_SET temp_set; + int j, n, hard_regno; + enum reg_class aclass; + + COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set); + AND_HARD_REG_SET (temp_set, profitable_hard_regs); + aclass = ALLOCNO_CLASS (a); + for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--) { - HARD_REG_SET temp_set; - int j, n; - enum reg_class aclass; - - COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set); - AND_HARD_REG_SET (temp_set, profitable_hard_regs); - aclass = ALLOCNO_CLASS (a); - for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--) - if (TEST_HARD_REG_BIT (temp_set, ira_class_hard_regs[aclass][j])) - n++; - subnodes[i].max_node_impact = n; + hard_regno = ira_class_hard_regs[aclass][j]; + if (TEST_HARD_REG_BIT (temp_set, hard_regno)) + n++; } - subnodes[i].left_conflict_subnodes_size = 0; + subnodes[i].max_node_impact = n; } - start = node_preorder_num * object_hard_regs_nodes_num; - for (i = obj_data->hard_regs_subnodes_num - 1; i >= 0; i--) - { - int size, parent_i; - object_hard_regs_node_t parent; - - size = (subnodes[i].left_conflict_subnodes_size - + MIN (subnodes[i].max_node_impact - - subnodes[i].left_conflict_subnodes_size, - subnodes[i].left_conflict_size)); - parent = object_hard_regs_nodes[i + node_preorder_num]->parent; - if (parent == NULL) - continue; - parent_i - = object_hard_regs_subnode_index[start + parent->preorder_num]; - if (parent_i < 0) - continue; - subnodes[parent_i].left_conflict_subnodes_size += size; - } - left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size; - conflict_size - += (left_conflict_subnodes_size - + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size, - subnodes[0].left_conflict_size)); + subnodes[i].left_conflict_subnodes_size = 0; } + start = node_preorder_num * allocno_hard_regs_nodes_num; + for (i = data->hard_regs_subnodes_num - 1; i >= 0; i--) + { + int size, parent_i; + allocno_hard_regs_node_t parent; + + size = (subnodes[i].left_conflict_subnodes_size + + MIN (subnodes[i].max_node_impact + - subnodes[i].left_conflict_subnodes_size, + subnodes[i].left_conflict_size)); + parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent; + if (parent == NULL) + continue; + parent_i + = allocno_hard_regs_subnode_index[start + parent->preorder_num]; + if (parent_i < 0) + continue; + subnodes[parent_i].left_conflict_subnodes_size += size; + } + left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size; + conflict_size + += (left_conflict_subnodes_size + + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size, + subnodes[0].left_conflict_size)); conflict_size += ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]; data->colorable_p = conflict_size <= data->available_regs_num; return data->colorable_p; } /* Update left conflict sizes of hard registers subnodes of allocno A - after removing allocno containing object REMOVED_OBJ with SIZE from - the conflict graph. Return TRUE if A is trivially colorable. */ + after removing allocno REMOVED_A with SIZE from the conflict graph. + Return TRUE if A is trivially colorable. */ static bool update_left_conflict_sizes_p (ira_allocno_t a, - ira_object_t removed_obj, int size) + ira_allocno_t removed_a, int size) { - int i, k, conflict_size, before_conflict_size, diff, start; + int i, conflict_size, before_conflict_size, diff, start; int node_preorder_num, parent_i; - object_hard_regs_node_t node, removed_node, parent; - object_hard_regs_subnode_t subnodes; + allocno_hard_regs_node_t node, removed_node, parent; + allocno_hard_regs_subnode_t subnodes; allocno_color_data_t data = ALLOCNO_COLOR_DATA (a); - bool colorable_p = true; ira_assert (! data->colorable_p); - for (k = 0; k < ALLOCNO_NUM_OBJECTS (a); k++) + node = data->hard_regs_node; + node_preorder_num = node->preorder_num; + removed_node = ALLOCNO_COLOR_DATA (removed_a)->hard_regs_node; + ira_assert (hard_reg_set_subset_p (removed_node->hard_regs->set, + node->hard_regs->set) + || hard_reg_set_subset_p (node->hard_regs->set, + removed_node->hard_regs->set)); + start = node_preorder_num * allocno_hard_regs_nodes_num; + i = allocno_hard_regs_subnode_index[start + removed_node->preorder_num]; + if (i < 0) + i = 0; + subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start; + before_conflict_size + = (subnodes[i].left_conflict_subnodes_size + + MIN (subnodes[i].max_node_impact + - subnodes[i].left_conflict_subnodes_size, + subnodes[i].left_conflict_size)); + subnodes[i].left_conflict_size -= size; + for (;;) { - ira_object_t obj = ALLOCNO_OBJECT (a, k); - object_color_data_t obj_data = OBJECT_COLOR_DATA (obj); - - node = obj_data->hard_regs_node; - node_preorder_num = node->preorder_num; - removed_node = OBJECT_COLOR_DATA (removed_obj)->hard_regs_node; - if (! hard_reg_set_subset_p (removed_node->hard_regs->set, - node->hard_regs->set) - && ! hard_reg_set_subset_p (node->hard_regs->set, - removed_node->hard_regs->set)) - /* It is a rare case which can happen for conflicting - multi-object allocnos where only one pair of objects might - conflict. */ - continue; - start = node_preorder_num * object_hard_regs_nodes_num; - i = object_hard_regs_subnode_index[start + removed_node->preorder_num]; - if (i < 0) - i = 0; - subnodes = object_hard_regs_subnodes + obj_data->hard_regs_subnodes_start; + conflict_size + = (subnodes[i].left_conflict_subnodes_size + + MIN (subnodes[i].max_node_impact + - subnodes[i].left_conflict_subnodes_size, + subnodes[i].left_conflict_size)); + if ((diff = before_conflict_size - conflict_size) == 0) + break; + ira_assert (conflict_size < before_conflict_size); + parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent; + if (parent == NULL) + break; + parent_i + = allocno_hard_regs_subnode_index[start + parent->preorder_num]; + if (parent_i < 0) + break; + i = parent_i; before_conflict_size = (subnodes[i].left_conflict_subnodes_size + MIN (subnodes[i].max_node_impact - subnodes[i].left_conflict_subnodes_size, subnodes[i].left_conflict_size)); - subnodes[i].left_conflict_size -= size; - for (;;) - { - conflict_size - = (subnodes[i].left_conflict_subnodes_size - + MIN (subnodes[i].max_node_impact - - subnodes[i].left_conflict_subnodes_size, - subnodes[i].left_conflict_size)); - if ((diff = before_conflict_size - conflict_size) == 0) - break; - ira_assert (conflict_size < before_conflict_size); - parent = object_hard_regs_nodes[i + node_preorder_num]->parent; - if (parent == NULL) - break; - parent_i - = object_hard_regs_subnode_index[start + parent->preorder_num]; - if (parent_i < 0) - break; - i = parent_i; - before_conflict_size - = (subnodes[i].left_conflict_subnodes_size - + MIN (subnodes[i].max_node_impact - - subnodes[i].left_conflict_subnodes_size, - subnodes[i].left_conflict_size)); - subnodes[i].left_conflict_subnodes_size -= diff; - } - if (i != 0 - || (conflict_size - + ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)] - > data->available_regs_num)) - { - colorable_p = false; - break; - } - } - if (colorable_p) - { - data->colorable_p = true; - return true; + subnodes[i].left_conflict_subnodes_size -= diff; } - return false; + if (i != 0 + || (conflict_size + + ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)] + > data->available_regs_num)) + return false; + data->colorable_p = true; + return true; } -/* Return true if allocno A has an object with empty profitable hard - regs. */ +/* Return true if allocno A has empty profitable hard regs. */ static bool empty_profitable_hard_regs (ira_allocno_t a) { - int k, nobj; - - nobj = ALLOCNO_NUM_OBJECTS (a); - for (k = 0; k < nobj; k++) - { - ira_object_t obj = ALLOCNO_OBJECT (a, k); - object_color_data_t obj_data = OBJECT_COLOR_DATA (obj); + allocno_color_data_t data = ALLOCNO_COLOR_DATA (a); - if (hard_reg_set_empty_p (obj_data->profitable_hard_regs)) - return true; - } - return false; + return hard_reg_set_empty_p (data->profitable_hard_regs); } /* Set up profitable hard registers for each allocno being @@ -1056,6 +1011,7 @@ setup_profitable_hard_regs (void) bitmap_iterator bi; enum reg_class aclass; enum machine_mode mode; + allocno_color_data_t data; /* Initial set up from allocno classes and explicitly conflicting hard regs. */ @@ -1064,23 +1020,22 @@ setup_profitable_hard_regs (void) a = ira_allocnos[i]; if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS) continue; - mode = ALLOCNO_MODE (a); - nobj = ALLOCNO_NUM_OBJECTS (a); - for (k = 0; k < nobj; k++) + data = ALLOCNO_COLOR_DATA (a); + if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL + && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a)) + CLEAR_HARD_REG_SET (data->profitable_hard_regs); + else { - ira_object_t obj = ALLOCNO_OBJECT (a, k); - object_color_data_t obj_data = OBJECT_COLOR_DATA (obj); - - if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL - && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a)) - CLEAR_HARD_REG_SET (obj_data->profitable_hard_regs); - else + COPY_HARD_REG_SET (data->profitable_hard_regs, + reg_class_contents[aclass]); + AND_COMPL_HARD_REG_SET (data->profitable_hard_regs, + ira_no_alloc_regs); + nobj = ALLOCNO_NUM_OBJECTS (a); + for (k = 0; k < nobj; k++) { - COPY_HARD_REG_SET (obj_data->profitable_hard_regs, - reg_class_contents[aclass]); - AND_COMPL_HARD_REG_SET (obj_data->profitable_hard_regs, - ira_no_alloc_regs); - AND_COMPL_HARD_REG_SET (obj_data->profitable_hard_regs, + ira_object_t obj = ALLOCNO_OBJECT (a, k); + + AND_COMPL_HARD_REG_SET (data->profitable_hard_regs, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); } } @@ -1104,22 +1059,26 @@ setup_profitable_hard_regs (void) FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci) { + ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj); + + /* We can process the conflict allocno repeatedly with + the same result. */ if (nregs == nobj && nregs > 1) { int num = OBJECT_SUBWORD (conflict_obj); if (WORDS_BIG_ENDIAN) CLEAR_HARD_REG_BIT - (OBJECT_COLOR_DATA (conflict_obj)->profitable_hard_regs, + (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs, hard_regno + nobj - num - 1); else CLEAR_HARD_REG_BIT - (OBJECT_COLOR_DATA (conflict_obj)->profitable_hard_regs, + (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs, hard_regno + num); } else AND_COMPL_HARD_REG_SET - (OBJECT_COLOR_DATA (conflict_obj)->profitable_hard_regs, + (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs, ira_reg_mode_hard_regset[hard_regno][mode]); } } @@ -1134,44 +1093,28 @@ setup_profitable_hard_regs (void) if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS || empty_profitable_hard_regs (a)) continue; + data = ALLOCNO_COLOR_DATA (a); mode = ALLOCNO_MODE (a); - nobj = ALLOCNO_NUM_OBJECTS (a); - for (k = 0; k < nobj; k++) + if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL + || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL) { - ira_object_t obj = ALLOCNO_OBJECT (a, k); - object_color_data_t obj_data = OBJECT_COLOR_DATA (obj); - - if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL - || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL) + class_size = ira_class_hard_regs_num[aclass]; + for (j = 0; j < class_size; j++) { - class_size = ira_class_hard_regs_num[aclass]; - for (j = 0; j < class_size; j++) - { - hard_regno = ira_class_hard_regs[aclass][j]; - nregs = hard_regno_nregs[hard_regno][mode]; - if (nregs == nobj && nregs > 1) - { - int num = OBJECT_SUBWORD (obj); - - if (WORDS_BIG_ENDIAN) - hard_regno += nobj - num - 1; - else - hard_regno += num; - } - if (! TEST_HARD_REG_BIT (obj_data->profitable_hard_regs, - hard_regno)) - continue; - if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j]) - CLEAR_HARD_REG_BIT (obj_data->profitable_hard_regs, - hard_regno); - else if (min_cost > costs[j]) - min_cost = costs[j]; - } + hard_regno = ira_class_hard_regs[aclass][j]; + if (! TEST_HARD_REG_BIT (data->profitable_hard_regs, + hard_regno)) + continue; + if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j]) + CLEAR_HARD_REG_BIT (data->profitable_hard_regs, + hard_regno); + else if (min_cost > costs[j]) + min_cost = costs[j]; } - else if (ALLOCNO_UPDATED_MEMORY_COST (a) - < ALLOCNO_UPDATED_CLASS_COST (a)) - CLEAR_HARD_REG_SET (obj_data->profitable_hard_regs); } + else if (ALLOCNO_UPDATED_MEMORY_COST (a) + < ALLOCNO_UPDATED_CLASS_COST (a)) + CLEAR_HARD_REG_SET (data->profitable_hard_regs); if (ALLOCNO_UPDATED_CLASS_COST (a) > min_cost) ALLOCNO_UPDATED_CLASS_COST (a) = min_cost; } @@ -1447,14 +1390,16 @@ update_conflict_hard_regno_costs (int *c } } -/* Set up conflicting and profitable regs (through CONFLICT_REGS and - PROFITABLE_REGS) for each object of allocno A. Remember that the - profitable regs exclude hard regs which can not hold value of mode - of allocno A. */ +/* Set up conflicting (through CONFLICT_REGS) for each object of + allocno A and the start allocno profitable regs (through + START_PROFITABLE_REGS). Remember that the start profitable regs + exclude hard regs which can not hold value of mode of allocno A. + This covers mostly cases when multi-register value should be + aligned. */ static inline void -get_conflict_profitable_regs (ira_allocno_t a, bool retry_p, - HARD_REG_SET *conflict_regs, - HARD_REG_SET *profitable_regs) +get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p, + HARD_REG_SET *conflict_regs, + HARD_REG_SET *start_profitable_regs) { int i, nwords; ira_object_t obj; @@ -1465,25 +1410,25 @@ get_conflict_profitable_regs (ira_allocn obj = ALLOCNO_OBJECT (a, i); COPY_HARD_REG_SET (conflict_regs[i], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); - if (retry_p) - { - COPY_HARD_REG_SET (profitable_regs[i], - reg_class_contents[ALLOCNO_CLASS (a)]); - AND_COMPL_HARD_REG_SET (profitable_regs[i], - ira_prohibited_class_mode_regs - [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]); - } - else - COPY_HARD_REG_SET (profitable_regs[i], - OBJECT_COLOR_DATA (obj)->profitable_hard_regs); } + if (retry_p) + { + COPY_HARD_REG_SET (*start_profitable_regs, + reg_class_contents[ALLOCNO_CLASS (a)]); + AND_COMPL_HARD_REG_SET (*start_profitable_regs, + ira_prohibited_class_mode_regs + [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]); + } + else + COPY_HARD_REG_SET (*start_profitable_regs, + ALLOCNO_COLOR_DATA (a)->profitable_hard_regs); } -/* Return true if HARD_REGNO is ok for assigning to allocno A whose - objects have corresponding CONFLICT_REGS and PROFITABLE_REGS. */ +/* Return true if HARD_REGNO is ok for assigning to allocno A with + PROFITABLE_REGS and whose objects have CONFLICT_REGS. */ static inline bool check_hard_reg_p (ira_allocno_t a, int hard_regno, - HARD_REG_SET *conflict_regs, HARD_REG_SET *profitable_regs) + HARD_REG_SET *conflict_regs, HARD_REG_SET profitable_regs) { int j, nwords, nregs; enum reg_class aclass; @@ -1494,6 +1439,9 @@ check_hard_reg_p (ira_allocno_t a, int h if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)) return false; + /* Checking only profitable hard regs. */ + if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno)) + return false; nregs = hard_regno_nregs[hard_regno][mode]; nwords = ALLOCNO_NUM_OBJECTS (a); for (j = 0; j < nregs; j++) @@ -1510,9 +1458,7 @@ check_hard_reg_p (ira_allocno_t a, int h set_to_test_end = set_to_test_start + 1; } for (k = set_to_test_start; k < set_to_test_end; k++) - /* Checking only profitable hard regs. */ - if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j) - || ! TEST_HARD_REG_BIT (profitable_regs[k], hard_regno + j)) + if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j)) break; if (k != set_to_test_end) break; @@ -1566,7 +1512,7 @@ calculate_saved_nregs (int hard_regno, e static bool assign_hard_reg (ira_allocno_t a, bool retry_p) { - HARD_REG_SET conflicting_regs[2], profitable_hard_regs[2]; + HARD_REG_SET conflicting_regs[2], profitable_hard_regs; int i, j, hard_regno, best_hard_regno, class_size; int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word; int *a_costs; @@ -1583,8 +1529,9 @@ assign_hard_reg (ira_allocno_t a, bool r #endif ira_assert (! ALLOCNO_ASSIGNED_P (a)); - get_conflict_profitable_regs (a, retry_p, - conflicting_regs, profitable_hard_regs); + get_conflict_and_start_profitable_regs (a, retry_p, + conflicting_regs, + &profitable_hard_regs); aclass = ALLOCNO_CLASS (a); class_size = ira_class_hard_regs_num[aclass]; best_hard_regno = -1; @@ -1618,6 +1565,7 @@ assign_hard_reg (ira_allocno_t a, bool r full_costs[i] += cost; } nwords = ALLOCNO_NUM_OBJECTS (a); + curr_allocno_process++; for (word = 0; word < nwords; word++) { ira_object_t conflict_obj; @@ -1638,9 +1586,9 @@ assign_hard_reg (ira_allocno_t a, bool r || ((!ALLOCNO_ASSIGNED_P (conflict_a) || ALLOCNO_HARD_REGNO (conflict_a) < 0) && !(hard_reg_set_intersect_p - (profitable_hard_regs[word], - OBJECT_COLOR_DATA - (conflict_obj)->profitable_hard_regs))))) + (profitable_hard_regs, + ALLOCNO_COLOR_DATA + (conflict_a)->profitable_hard_regs))))) continue; conflict_aclass = ALLOCNO_CLASS (conflict_a); ira_assert (ira_reg_classes_intersect_p @@ -1673,16 +1621,21 @@ assign_hard_reg (ira_allocno_t a, bool r IOR_HARD_REG_SET (conflicting_regs[word], ira_reg_mode_hard_regset[hard_regno][mode]); - if (hard_reg_set_subset_p (profitable_hard_regs[word], + if (hard_reg_set_subset_p (profitable_hard_regs, conflicting_regs[word])) goto fail; } } else if (! retry_p - && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p) + && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p + /* Don't process the conflict allocno twice. */ + && (ALLOCNO_COLOR_DATA (conflict_a)->last_process + != curr_allocno_process)) { int k, *conflict_costs; + ALLOCNO_COLOR_DATA (conflict_a)->last_process + = curr_allocno_process; ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a), conflict_aclass, @@ -1983,15 +1936,15 @@ push_allocno_to_stack (ira_allocno_t a) || ! conflict_data->in_graph_p || ALLOCNO_ASSIGNED_P (conflict_a) || !(hard_reg_set_intersect_p - (OBJECT_COLOR_DATA (obj)->profitable_hard_regs, - OBJECT_COLOR_DATA (conflict_obj)->profitable_hard_regs))) + (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs, + conflict_data->profitable_hard_regs))) continue; ira_assert (bitmap_bit_p (coloring_allocno_bitmap, ALLOCNO_NUM (conflict_a))); - if (update_left_conflict_sizes_p (conflict_a, obj, size)) + if (update_left_conflict_sizes_p (conflict_a, a, size)) { delete_allocno_from_bucket - (conflict_a, &uncolorable_allocno_bucket); + (conflict_a, &uncolorable_allocno_bucket); add_allocno_to_ordered_bucket (conflict_a, &colorable_allocno_bucket); if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL) @@ -2228,9 +2181,8 @@ pop_allocnos_from_stack (void) static void setup_allocno_available_regs_num (ira_allocno_t a) { - int i, j, n, hard_regno, hard_regs_num, nwords, nregs; + int i, n, hard_regno, hard_regs_num, nwords; enum reg_class aclass; - enum machine_mode mode; allocno_color_data_t data; aclass = ALLOCNO_CLASS (a); @@ -2239,42 +2191,12 @@ setup_allocno_available_regs_num (ira_al if (aclass == NO_REGS) return; hard_regs_num = ira_class_hard_regs_num[aclass]; - mode = ALLOCNO_MODE (a); nwords = ALLOCNO_NUM_OBJECTS (a); for (n = 0, i = hard_regs_num - 1; i >= 0; i--) { hard_regno = ira_class_hard_regs[aclass][i]; - nregs = hard_regno_nregs[hard_regno][mode]; - for (j = 0; j < nregs; j++) - { - int k; - int set_to_test_start = 0, set_to_test_end = nwords; - - if (nregs == nwords) - { - if (WORDS_BIG_ENDIAN) - set_to_test_start = nwords - j - 1; - else - set_to_test_start = j; - set_to_test_end = set_to_test_start + 1; - } - for (k = set_to_test_start; k < set_to_test_end; k++) - { - ira_object_t obj = ALLOCNO_OBJECT (a, k); - object_color_data_t obj_data = OBJECT_COLOR_DATA (obj); - - /* Checking only profitable hard regs which exclude - object's conflict hard regs. */ - if (TEST_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), - hard_regno + j) - || ! TEST_HARD_REG_BIT (obj_data->profitable_hard_regs, - hard_regno + j)) - break; - } - if (k != set_to_test_end) - break; - } - if (j == nregs) + /* Checking only profitable hard regs. */ + if (TEST_HARD_REG_BIT (data->profitable_hard_regs, hard_regno)) n++; } data->available_regs_num = n; @@ -2282,13 +2204,19 @@ setup_allocno_available_regs_num (ira_al return; fprintf (ira_dump_file, - " Allocno a%dr%d of %s(%d) has %d avail. regs", + " Allocno a%dr%d of %s(%d) has %d avail. regs ", ALLOCNO_NUM (a), ALLOCNO_REGNO (a), reg_class_names[aclass], ira_class_hard_regs_num[aclass], n); + print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false); + fprintf (ira_dump_file, ", %snode: ", + hard_reg_set_equal_p (data->profitable_hard_regs, + data->hard_regs_node->hard_regs->set) + ? "" : "^"); + print_hard_reg_set (ira_dump_file, + data->hard_regs_node->hard_regs->set, false); for (i = 0; i < nwords; i++) { ira_object_t obj = ALLOCNO_OBJECT (a, i); - object_color_data_t obj_data = OBJECT_COLOR_DATA (obj); if (nwords != 1) { @@ -2296,17 +2224,10 @@ setup_allocno_available_regs_num (ira_al fprintf (ira_dump_file, ", "); fprintf (ira_dump_file, " obj %d", i); } - print_hard_reg_set (ira_dump_file, obj_data->profitable_hard_regs, false); fprintf (ira_dump_file, " (confl regs = "); print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), false); - fprintf (ira_dump_file, " ) %snode: ", - hard_reg_set_equal_p (obj_data->profitable_hard_regs, - obj_data->hard_regs_node->hard_regs->set) - ? "" : "^"); - print_hard_reg_set (ira_dump_file, - obj_data->hard_regs_node->hard_regs->set, false); - + fprintf (ira_dump_file, ")"); } fprintf (ira_dump_file, "\n"); } @@ -2402,7 +2323,7 @@ improve_allocation (void) enum machine_mode mode; int *allocno_costs; int costs[FIRST_PSEUDO_REGISTER]; - HARD_REG_SET conflicting_regs[2], profitable_hard_regs[2]; + HARD_REG_SET conflicting_regs[2], profitable_hard_regs; ira_allocno_t a; bitmap_iterator bi; @@ -2434,8 +2355,9 @@ improve_allocation (void) else base_cost = allocno_costs[ira_class_hard_reg_index[aclass][hregno]]; try_p = false; - get_conflict_profitable_regs (a, false, - conflicting_regs, profitable_hard_regs); + get_conflict_and_start_profitable_regs (a, false, + conflicting_regs, + &profitable_hard_regs); class_size = ira_class_hard_regs_num[aclass]; /* Set up cost improvement for usage of each profitable hard register for allocno A. */ @@ -2684,7 +2606,7 @@ color_allocnos (void) } else { - form_object_hard_regs_nodes_forest (); + form_allocno_hard_regs_nodes_forest (); if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) print_hard_regs_forest (ira_dump_file); EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi) @@ -2717,7 +2639,7 @@ color_allocnos (void) } push_allocnos_to_stack (); pop_allocnos_from_stack (); - finish_object_hard_regs_nodes_forest (); + finish_allocno_hard_regs_nodes_forest (); } improve_allocation (); } @@ -2785,7 +2707,7 @@ print_loop_title (ira_loop_tree_node_t l static void color_pass (ira_loop_tree_node_t loop_tree_node) { - int i, regno, hard_regno, index = -1, n, nobj; + int regno, hard_regno, index = -1, n; int cost, exit_freq, enter_freq; unsigned int j; bitmap_iterator bi; @@ -2800,12 +2722,11 @@ color_pass (ira_loop_tree_node_t loop_tr bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos); bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap); - n = nobj = 0; + n = 0; EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi) { a = ira_allocnos[j]; n++; - nobj += ALLOCNO_NUM_OBJECTS (a); if (! ALLOCNO_ASSIGNED_P (a)) continue; bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a)); @@ -2814,21 +2735,13 @@ color_pass (ira_loop_tree_node_t loop_tr = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data) * n); memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n); - object_color_data - = (object_color_data_t) ira_allocate (sizeof (struct object_color_data) - * nobj); - memset (object_color_data, 0, sizeof (struct object_color_data) * nobj); - n = nobj = 0; + curr_allocno_process = 0; + n = 0; EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi) { a = ira_allocnos[j]; ALLOCNO_ADD_DATA (a) = allocno_color_data + n; n++; - for (i = 0; i < ALLOCNO_NUM_OBJECTS (a); i++) - { - OBJECT_ADD_DATA (ALLOCNO_OBJECT (a, i)) = object_color_data + nobj; - nobj++; - } } /* Color all mentioned allocnos including transparent ones. */ color_allocnos (); @@ -2960,14 +2873,11 @@ color_pass (ira_loop_tree_node_t loop_tr } } } - ira_free (object_color_data); ira_free (allocno_color_data); EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi) { a = ira_allocnos[j]; ALLOCNO_ADD_DATA (a) = NULL; - for (i = 0; i < ALLOCNO_NUM_OBJECTS (a); i++) - OBJECT_ADD_DATA (a) = NULL; } } Index: ira-build.c =================================================================== --- ira-build.c (revision 181892) +++ ira-build.c (working copy) @@ -442,7 +442,6 @@ ira_create_object (ira_allocno_t a, int OBJECT_MIN (obj) = INT_MAX; OBJECT_MAX (obj) = -1; OBJECT_LIVE_RANGES (obj) = NULL; - OBJECT_ADD_DATA (obj) = NULL; VEC_safe_push (ira_object_t, heap, ira_object_id_map_vec, obj); ira_object_id_map