From patchwork Thu Jun 17 20:41:24 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Makarov X-Patchwork-Id: 56089 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 D7EC7B7D16 for ; Fri, 18 Jun 2010 06:40:08 +1000 (EST) Received: (qmail 29159 invoked by alias); 17 Jun 2010 20:40:06 -0000 Received: (qmail 29149 invoked by uid 22791); 17 Jun 2010 20:40:03 -0000 X-SWARE-Spam-Status: No, hits=-5.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD 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; Thu, 17 Jun 2010 20:39:57 +0000 Received: from int-mx05.intmail.prod.int.phx2.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.18]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o5HKdtvS001659 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 17 Jun 2010 16:39:55 -0400 Received: from toll.yyz.redhat.com (toll.yyz.redhat.com [10.15.16.165]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o5HKdswa030039 for ; Thu, 17 Jun 2010 16:39:54 -0400 Message-ID: <4C1A8874.7090203@redhat.com> Date: Thu, 17 Jun 2010 16:41:24 -0400 From: Vladimir Makarov User-Agent: Thunderbird 2.0.0.23 (X11/20090825) MIME-Version: 1.0 To: gcc-patches Subject: [ira-improv] patch to fix some branch problems 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 the branch compiler crashes on bootstrap (in debug mode) and on SPEC2006 gamess. The problem was in wrong integer overflow check code and assertion became wrong after making cost calculation classes are specific for each pseudo. Committed as revision 160946. 2010-06-16 Vladimir Makarov * ira.c (ira_class_hard_regs_num): Fix the comment. * ira-costs.c (struct cost_classes): New member hard_regno_index. (setup_cost_classes): New. (setup_regno_cost_classes_by_aclass): Call setup_cost_classes. (setup_regno_cost_classes_by_mode): Ditto. (record_address_regs): Fix overflow code. (scan_one_insn): Ditto. (find_costs_and_classes): Ditto. Move setting cost classes to the loop start. (setup_allocno_class_and_costs): Use member hard_regno_index. (ira_tune_allocno_costs): Fix overflow code. Index: ira.c =================================================================== --- ira.c (revision 160634) +++ ira.c (working copy) @@ -461,7 +461,7 @@ short ira_class_hard_regs[N_REG_CLASSES] 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 +/* The number of elements of the two above arrays for given register class. */ int ira_class_hard_regs_num[N_REG_CLASSES]; Index: ira-costs.c =================================================================== --- ira-costs.c (revision 160634) +++ ira-costs.c (working copy) @@ -125,6 +125,9 @@ struct cost_classes /* Map reg class -> index of the reg class in the previous array. -1 if it is not a cost classe. */ int index[N_REG_CLASSES]; + /* Map hard regno index of first class in array CLASSES containing + the hard regno, -1 otherwise. */ + int hard_regno_index[FIRST_PSEUDO_REGISTER]; }; /* Types of pointers to the structure above. */ @@ -187,6 +190,35 @@ initiate_regno_cost_classes (void) = htab_create (200, cost_classes_hash, cost_classes_eq, cost_classes_del); } +/* Create new classes from FROM and set up memebrs index and + hard_regno_index. Return the new classes. */ +static cost_classes_t +setup_cost_classes (cost_classes_t from) +{ + cost_classes_t classes_ptr; + enum reg_class cl; + int i, j, hard_regno; + + classes_ptr = (cost_classes_t) ira_allocate (sizeof (struct cost_classes)); + classes_ptr->num = from->num; + for (i = 0; i < N_REG_CLASSES; i++) + classes_ptr->index[i] = -1; + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + classes_ptr->hard_regno_index[i] = -1; + for (i = 0; i < from->num; i++) + { + cl = classes_ptr->classes[i] = from->classes[i]; + classes_ptr->index[cl] = i; + for (j = ira_class_hard_regs_num[cl] - 1; j >= 0; j--) + { + hard_regno = ira_class_hard_regs[cl][j]; + if (classes_ptr->hard_regno_index[hard_regno] < 0) + classes_ptr->hard_regno_index[hard_regno] = i; + } + } + return classes_ptr; +} + /* Setup cost classes for REGNO whose allocno class ACLASS. */ static void setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass) @@ -216,16 +248,7 @@ setup_regno_cost_classes_by_aclass (int slot = htab_find_slot (cost_classes_htab, &classes, INSERT); if (*slot == NULL) { - classes_ptr - = (cost_classes_t) ira_allocate (sizeof (struct cost_classes)); - classes_ptr->num = classes.num; - for (i = 0; i < N_REG_CLASSES; i++) - classes_ptr->index[i] = -1; - for (i = 0; i < classes.num; i++) - { - cl = classes_ptr->classes[i] = classes.classes[i]; - classes_ptr->index[cl] = i; - } + classes_ptr = setup_cost_classes (&classes); *slot = classes_ptr; } cost_classes_aclass_cache[aclass] = (cost_classes_t) *slot; @@ -259,16 +282,7 @@ setup_regno_cost_classes_by_mode (int re slot = htab_find_slot (cost_classes_htab, &classes, INSERT); if (*slot == NULL) { - classes_ptr - = (cost_classes_t) ira_allocate (sizeof (struct cost_classes)); - classes_ptr->num = classes.num; - for (i = 0; i < N_REG_CLASSES; i++) - classes_ptr->index[i] = -1; - for (i = 0; i < classes.num; i++) - { - cl = classes_ptr->classes[i] = classes.classes[i]; - classes_ptr->index[cl] = i; - } + classes_ptr = setup_cost_classes (&classes); *slot = classes_ptr; } cost_classes_mode_cache[mode] = (cost_classes_t) *slot; @@ -1114,8 +1128,7 @@ record_address_regs (enum machine_mode m struct costs *pp; int *pp_costs; enum reg_class i; - int k, regno; - bool plus_p; + int k, regno, add_cost; cost_classes_t cost_classes_ptr; enum reg_class *cost_classes; move_table *move_in_cost; @@ -1126,10 +1139,11 @@ record_address_regs (enum machine_mode m if (allocno_p) ALLOCNO_BAD_SPILL_P (ira_curr_regno_allocno_map[regno]) = true; pp = COSTS (costs, COST_INDEX (regno)); - plus_p = pp->mem_cost > 0; - pp->mem_cost += (ira_memory_move_cost[Pmode][rclass][1] * scale) / 2; - if (pp->mem_cost < 0 && plus_p) + add_cost = (ira_memory_move_cost[Pmode][rclass][1] * scale) / 2; + if (INT_MAX - add_cost < pp->mem_cost) pp->mem_cost = INT_MAX; + else + pp->mem_cost += add_cost; cost_classes_ptr = regno_cost_classes[regno]; cost_classes = cost_classes_ptr->classes; pp_costs = pp->cost; @@ -1138,10 +1152,11 @@ record_address_regs (enum machine_mode m for (k = cost_classes_ptr->num - 1; k >= 0; k--) { i = cost_classes[k]; - plus_p = pp_costs[k] > 0; - pp_costs[k] += (move_in_cost[i][rclass] * scale) / 2; - if (pp_costs[k] < 0 && plus_p) + add_cost = (move_in_cost[i][rclass] * scale) / 2; + if (INT_MAX - add_cost < pp_costs[k]) pp_costs[k] = INT_MAX; + else + pp_costs[k] += add_cost; } } break; @@ -1274,18 +1289,20 @@ scan_one_insn (rtx insn) struct costs *q = op_costs[i]; int *p_costs = p->cost, *q_costs = q->cost; cost_classes_t cost_classes_ptr = regno_cost_classes[regno]; - bool plus_p; + int add_cost; - plus_p = p->mem_cost > 0 && q->mem_cost > 0; - p->mem_cost += q->mem_cost; - if (p->mem_cost < 0 && plus_p) + add_cost = q->mem_cost; + if (add_cost > 0 && INT_MAX - add_cost < p->mem_cost) p->mem_cost = INT_MAX; + else + p->mem_cost += add_cost; for (k = cost_classes_ptr->num - 1; k >= 0; k--) { - plus_p = p_costs[k] > 0 && q_costs[k] > 0; - p_costs[k] += q_costs[k]; - if (p_costs[k] < 0 && plus_p) + add_cost = q_costs[k]; + if (add_cost > 0 && INT_MAX - add_cost < p_costs[k]) p_costs[k] = INT_MAX; + else + p_costs[k] += add_cost; } } @@ -1419,13 +1436,17 @@ find_costs_and_classes (FILE *dump_file) int i, k, start, max_cost_classes_num; int pass; basic_block bb; - enum reg_class pref_cl; + enum reg_class *regno_best_class; init_recog (); #ifdef FORBIDDEN_INC_DEC_CLASSES in_inc_dec = ira_allocate (sizeof (bool) * cost_elements_num); #endif /* FORBIDDEN_INC_DEC_CLASSES */ - + regno_best_class + = (enum reg_class *) ira_allocate (max_reg_num () + * sizeof (enum reg_class)); + for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--) + regno_best_class[i] = NO_REGS; if (!resize_reg_info () && allocno_p && pseudo_classes_defined_p && flag_expensive_optimizations) { @@ -1468,6 +1489,18 @@ find_costs_and_classes (FILE *dump_file) if ((!allocno_p || internal_flag_ira_verbose > 0) && dump_file) fprintf (dump_file, "\nPass %i for finding pseudo/allocno costs\n\n", pass); + + if (pass != start) + { + max_cost_classes_num = 1; + for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--) + { + setup_regno_cost_classes_by_aclass (i, regno_best_class[i]); + max_cost_classes_num + = MAX (max_cost_classes_num, regno_cost_classes[i]->num); + } + } + struct_costs_size = sizeof (struct costs) + sizeof (int) * (max_cost_classes_num - 1); /* Zero out our accumulation of the cost of each class for each @@ -1477,7 +1510,6 @@ find_costs_and_classes (FILE *dump_file) memset (in_inc_dec, 0, cost_elements_num * sizeof (bool)); #endif - max_cost_classes_num = 1; if (allocno_p) { /* Scan the instructions and record each time it would save code @@ -1504,14 +1536,13 @@ find_costs_and_classes (FILE *dump_file) for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--) { ira_allocno_t a, parent_a; - int rclass, a_num, parent_a_num; + int rclass, a_num, parent_a_num, add_cost; ira_loop_tree_node_t parent; int best_cost, allocno_cost; enum reg_class best, alt_class; #ifdef FORBIDDEN_INC_DEC_CLASSES int inc_dec_p = false; #endif - bool plus_p; cost_classes_t cost_classes_ptr = regno_cost_classes[i]; enum reg_class *cost_classes = cost_classes_ptr->classes; int *i_costs = temp_costs->cost; @@ -1557,34 +1588,38 @@ find_costs_and_classes (FILE *dump_file) p_costs = COSTS (total_allocno_costs, parent_a_num)->cost; for (k = cost_classes_ptr->num - 1; k >= 0; k--) { - plus_p = p_costs[k] > 0 && a_costs[k] > 0; - p_costs[k] += a_costs[k]; - if (p_costs[k] < 0 && plus_p) + add_cost = a_costs[k]; + if (add_cost > 0 && INT_MAX - add_cost < p_costs[k]) p_costs[k] = INT_MAX; + else + p_costs[k] += add_cost; } - plus_p = (COSTS (total_allocno_costs, - parent_a_num)->mem_cost > 0 - && COSTS (total_allocno_costs, - a_num)->mem_cost > 0); - COSTS (total_allocno_costs, parent_a_num)->mem_cost - += COSTS (total_allocno_costs, a_num)->mem_cost; - if (COSTS (total_allocno_costs, parent_a_num)->mem_cost < 0 - && plus_p) + add_cost = COSTS (total_allocno_costs, a_num)->mem_cost; + if (add_cost > 0 + && (INT_MAX - add_cost + < COSTS (total_allocno_costs, + parent_a_num)->mem_cost)) COSTS (total_allocno_costs, parent_a_num)->mem_cost = INT_MAX; + else + COSTS (total_allocno_costs, parent_a_num)->mem_cost + += add_cost; + } a_costs = COSTS (costs, a_num)->cost; for (k = cost_classes_ptr->num - 1; k >= 0; k--) { - plus_p = i_costs[k] > 0 && a_costs[k] > 0; - i_costs[k] += a_costs[k]; - if (i_costs[k] < 0 && plus_p) + add_cost = a_costs[k]; + if (add_cost > 0 && INT_MAX - add_cost < i_costs[k]) i_costs[k] = INT_MAX; + else + i_costs[k] += add_cost; } - plus_p = i_mem_cost > 0 && COSTS (costs, a_num)->mem_cost > 0; - i_mem_cost += COSTS (costs, a_num)->mem_cost; - if (i_mem_cost < 0 && plus_p) + add_cost = COSTS (costs, a_num)->mem_cost; + if (add_cost && INT_MAX - add_cost < i_mem_cost) i_mem_cost = INT_MAX; + else + i_mem_cost += add_cost; #ifdef FORBIDDEN_INC_DEC_CLASSES if (in_inc_dec[a_num]) inc_dec_p = true; @@ -1650,16 +1685,10 @@ find_costs_and_classes (FILE *dump_file) i, reg_class_names[best], reg_class_names[alt_class], reg_class_names[regno_aclass[i]]); } - pref_cl = best; + regno_best_class[i] = best; if (! allocno_p) { pref[i] = best_cost > i_mem_cost ? NO_REGS : best; - if (pass < flag_expensive_optimizations) - { - setup_regno_cost_classes_by_aclass (i, pref_cl); - max_cost_classes_num - = MAX (max_cost_classes_num, regno_cost_classes[i]->num); - } continue; } for (a = ira_regno_allocno_map[i]; @@ -1673,7 +1702,7 @@ find_costs_and_classes (FILE *dump_file) { int *total_a_costs = COSTS (total_allocno_costs, a_num)->cost; int *a_costs = COSTS (costs, a_num)->cost; - + /* Finding best class which is subset of the common class. */ best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1; @@ -1726,11 +1755,8 @@ find_costs_and_classes (FILE *dump_file) } pref[a_num] = best; } - setup_regno_cost_classes_by_aclass (i, pref_cl); - max_cost_classes_num - = MAX (max_cost_classes_num, regno_cost_classes[i]->num); } - + if (internal_flag_ira_verbose > 4 && dump_file) { if (allocno_p) @@ -1740,6 +1766,7 @@ find_costs_and_classes (FILE *dump_file) fprintf (dump_file,"\n"); } } + ira_free (regno_best_class); #ifdef FORBIDDEN_INC_DEC_CLASSES ira_free (in_inc_dec); #endif @@ -1862,12 +1889,8 @@ setup_allocno_class_and_costs (void) num = cost_classes_ptr->index[rclass]; if (num < 0) { - /* The hard register class is not an allocno - class or a class not fully inside in an - allocno class -- use the allocno class. */ - ira_assert (ira_hard_regno_allocno_class[hard_regno] - == aclass); - num = cost_classes_ptr->index[aclass]; + num = cost_classes_ptr->hard_regno_index[hard_regno]; + ira_assert (num >= 0); } reg_costs[j] = COSTS (costs, i)->cost[num]; } @@ -2022,7 +2045,6 @@ ira_tune_allocno_costs (void) enum machine_mode mode; ira_allocno_t a; ira_allocno_iterator ai; - bool plus_p; FOR_EACH_ALLOCNO (a, ai) { @@ -2057,10 +2079,10 @@ ira_tune_allocno_costs (void) * ALLOCNO_FREQ (a) * IRA_HARD_REGNO_ADD_COST_MULTIPLIER (regno) / 2); #endif - plus_p = reg_costs[j] > 0 && cost > 0; - reg_costs[j] += cost; - if (reg_costs[j] < 0 && plus_p) + if (INT_MAX - cost < reg_costs[j]) reg_costs[j] = INT_MAX; + else + reg_costs[j] += cost; if (min_cost > reg_costs[j]) min_cost = reg_costs[j]; }