From patchwork Fri Nov 21 21:32:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Makarov X-Patchwork-Id: 413189 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id BEE3214014D for ; Sat, 22 Nov 2014 08:32:46 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=iw8K3Ku4zVEKAdPRLf210Zf8ub/HKaC3P5Mk7cflcZlG7j N075kenYcfmPh6copmnWL7c1eYM+Q7WHPYLOI9uXMcT1ot2CoCPKKOtGYyuCU8ST UW2Rcn6nCefo5V3OnkfmLVk5mQqOe1ciaku73Hw3Ibd9zVZuJKSVRVG3KJBQU= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=wa6RSVaTtICj+02a5IYT9IXcJjw=; b=XDOl4EKOPZURGbbopUaq 5rhze4pVtXzDJuK308k4JXb/xKN4ezVX8GzaQVbQ7qoiG37pxUWLCS5KwS4FDaaU 0lofxuFQibnKznHyLSRUf/6TIitzi/1vR6EUGzpBLwQX1OKc5ymINNvZAMCghRRc vOJZiGuY1vDn24Ej4bRUb5A= Received: (qmail 26313 invoked by alias); 21 Nov 2014 21:32:39 -0000 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 Received: (qmail 26301 invoked by uid 89); 21 Nov 2014 21:32:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.7 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 21 Nov 2014 21:32:36 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id sALLWYI2018751 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Fri, 21 Nov 2014 16:32:34 -0500 Received: from VMBP.local (vpn-62-99.rdu2.redhat.com [10.10.62.99]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id sALLWUjx010665 for ; Fri, 21 Nov 2014 16:32:32 -0500 Message-ID: <546FAF6E.4020001@redhat.com> Date: Fri, 21 Nov 2014 16:32:30 -0500 From: Vladimir Makarov User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: GCC Patches Subject: patch to fix PR63897 X-IsSubscribed: yes The following patch fixes PR63897. The details can be found on https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63897 The patch was successfully bootstrapped and tested on x86 and x86-64. Committed as rev. 217947. 2014-11-21 Vladimir Makarov PR target/63897 * lra-lives.c (mark_regno_live, mark_regno_dead): Remove last argument. (process_bb_lives): Rename dead_insn_p on remove_p and global_live_info_p on dead_insn_p. Calculate local live info unconditionally. Remove last argument in calls mark_regno_live and mark_regno_dead. Reorganize body of EXECUTE_IF_SET_IN_BITMAP. (lra_create_live_ranges): Rename to lra_create_live_ranges_1. Return bool. Rename global_live_info_p on dead_insn_p. Return flag of live info change. (lra_create_live_ranges): New. Index: lra-lives.c =================================================================== --- lra-lives.c (revision 217865) +++ lra-lives.c (working copy) @@ -321,11 +321,11 @@ mark_pseudo_dead (int regno, int point) static bitmap bb_killed_pseudos, bb_gen_pseudos; /* Mark register REGNO (pseudo or hard register) in MODE as live at - program point POINT. Update BB_GEN_PSEUDOS if LOCAL_SETS_P. + program point POINT. Update BB_GEN_PSEUDOS. Return TRUE if the liveness tracking sets were modified, or FALSE if nothing changed. */ static bool -mark_regno_live (int regno, machine_mode mode, int point, bool local_sets_p) +mark_regno_live (int regno, machine_mode mode, int point) { int last; bool changed = false; @@ -344,19 +344,17 @@ mark_regno_live (int regno, machine_mode mark_pseudo_live (regno, point); changed = true; } - if (local_sets_p) - bitmap_set_bit (bb_gen_pseudos, regno); + bitmap_set_bit (bb_gen_pseudos, regno); } return changed; } /* Mark register REGNO in MODE as dead at program point POINT. Update - BB_GEN_PSEUDOS and BB_KILLED_PSEUDOS if LOCAL_SETS_P. Return TRUE - if the liveness tracking sets were modified, or FALSE if nothing - changed. */ + BB_GEN_PSEUDOS and BB_KILLED_PSEUDOS. Return TRUE if the liveness + tracking sets were modified, or FALSE if nothing changed. */ static bool -mark_regno_dead (int regno, machine_mode mode, int point, bool local_sets_p) +mark_regno_dead (int regno, machine_mode mode, int point) { int last; bool changed = false; @@ -375,11 +373,8 @@ mark_regno_dead (int regno, machine_mode mark_pseudo_dead (regno, point); changed = true; } - if (local_sets_p) - { - bitmap_clear_bit (bb_gen_pseudos, regno); - bitmap_set_bit (bb_killed_pseudos, regno); - } + bitmap_clear_bit (bb_gen_pseudos, regno); + bitmap_set_bit (bb_killed_pseudos, regno); } return changed; } @@ -639,10 +634,10 @@ check_pseudos_live_through_calls (int re BB ends. The function updates this counter and returns in CURR_POINT the program point where BB starts. The function also does local live info updates and can delete the dead insns if - GLOBAL_LIVE_INFO_P. It returns true if pseudo live info was + DEAD_INSN_P. It returns true if pseudo live info was changed at the BB start. */ static bool -process_bb_lives (basic_block bb, int &curr_point, bool global_live_info_p) +process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) { int i, regno, freq; unsigned int j; @@ -662,13 +657,10 @@ process_bb_lives (basic_block bb, int &c EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi) mark_pseudo_live (j, curr_point); - if (global_live_info_p) - { - bb_gen_pseudos = &get_bb_data (bb)->gen_pseudos; - bb_killed_pseudos = &get_bb_data (bb)->killed_pseudos; - bitmap_clear (bb_gen_pseudos); - bitmap_clear (bb_killed_pseudos); - } + bb_gen_pseudos = &get_bb_data (bb)->gen_pseudos; + bb_killed_pseudos = &get_bb_data (bb)->killed_pseudos; + bitmap_clear (bb_gen_pseudos); + bitmap_clear (bb_killed_pseudos); freq = REG_FREQ_FROM_BB (bb); if (lra_dump_file != NULL) @@ -701,7 +693,7 @@ process_bb_lives (basic_block bb, int &c set = single_set (curr_insn); - if (global_live_info_p && set != NULL_RTX + if (dead_insn_p && set != NULL_RTX && REG_P (SET_DEST (set)) && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER && find_reg_note (curr_insn, REG_EH_REGION, NULL_RTX) == NULL_RTX && ! may_trap_p (PATTERN (curr_insn)) @@ -710,21 +702,21 @@ process_bb_lives (basic_block bb, int &c && (pic_offset_table_rtx == NULL_RTX || pic_offset_table_rtx != SET_DEST (set))) { - bool dead_insn_p = true; + bool remove_p = true; for (reg = curr_id->regs; reg != NULL; reg = reg->next) if (reg->type != OP_IN && sparseset_bit_p (pseudos_live, reg->regno)) { - dead_insn_p = false; + remove_p = false; break; } for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type != OP_IN) { - dead_insn_p = false; + remove_p = false; break; } - if (dead_insn_p && ! volatile_refs_p (PATTERN (curr_insn))) + if (remove_p && ! volatile_refs_p (PATTERN (curr_insn))) { dst_regno = REGNO (SET_DEST (set)); if (lra_dump_file != NULL) @@ -818,7 +810,7 @@ process_bb_lives (basic_block bb, int &c { need_curr_point_incr |= mark_regno_live (reg->regno, reg->biggest_mode, - curr_point, global_live_info_p); + curr_point); check_pseudos_live_through_calls (reg->regno); } @@ -835,7 +827,7 @@ process_bb_lives (basic_block bb, int &c if (reg->type == OP_OUT && ! reg->early_clobber && ! reg->subreg_p) need_curr_point_incr |= mark_regno_dead (reg->regno, reg->biggest_mode, - curr_point, global_live_info_p); + curr_point); for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type == OP_OUT && ! reg->early_clobber && ! reg->subreg_p) @@ -877,7 +869,7 @@ process_bb_lives (basic_block bb, int &c { need_curr_point_incr |= mark_regno_live (reg->regno, reg->biggest_mode, - curr_point, global_live_info_p); + curr_point); check_pseudos_live_through_calls (reg->regno); } @@ -897,7 +889,7 @@ process_bb_lives (basic_block bb, int &c if (reg->type == OP_OUT && reg->early_clobber && ! reg->subreg_p) need_curr_point_incr |= mark_regno_dead (reg->regno, reg->biggest_mode, - curr_point, global_live_info_p); + curr_point); for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type == OP_OUT && reg->early_clobber && ! reg->subreg_p) @@ -971,25 +963,22 @@ process_bb_lives (basic_block bb, int &c } bool live_change_p = false; - if (global_live_info_p) + /* Check if bb border live info was changed. */ + unsigned int live_pseudos_num = 0; + EXECUTE_IF_SET_IN_BITMAP (df_get_live_in (bb), + FIRST_PSEUDO_REGISTER, j, bi) { - /* Check if bb border live info was changed. */ - unsigned int live_pseudos_num = 0; - EXECUTE_IF_SET_IN_BITMAP (df_get_live_in (bb), - FIRST_PSEUDO_REGISTER, j, bi) + live_pseudos_num++; + if (! sparseset_bit_p (pseudos_live, j)) { - live_pseudos_num++; - if (! sparseset_bit_p (pseudos_live, j)) - { - live_change_p = TRUE; - break; - } + live_change_p = TRUE; + break; } - live_change_p - = (live_change_p - || sparseset_cardinality (pseudos_live) != live_pseudos_num); } - + live_change_p + = (live_change_p + || sparseset_cardinality (pseudos_live) != live_pseudos_num); + /* See if we'll need an increment at the end of this basic block. An increment is needed if the PSEUDOS_LIVE set is not empty, to make sure the finish points are set up correctly. */ @@ -1180,13 +1169,14 @@ compress_live_ranges (void) /* The number of the current live range pass. */ int lra_live_range_iter; -/* The main entry function creates live ranges only for memory pseudos - (or for all ones if ALL_P), set up CONFLICT_HARD_REGS for the - pseudos. It also does dead insn elimination and global live - analysis only for pseudos and only if GLOBAL_LIVE_INFO_P and the - pseudo live info was changed on a BB border. */ -void -lra_create_live_ranges (bool all_p, bool global_live_info_p) +/* The function creates live ranges only for memory pseudos (or for + all ones if ALL_P), set up CONFLICT_HARD_REGS for the pseudos. It + also does dead insn elimination if DEAD_INSN_P and global live + analysis only for pseudos and only if the pseudo live info was + changed on a BB border. Return TRUE if the live info was + changed. */ +static bool +lra_create_live_ranges_1 (bool all_p, bool dead_insn_p) { basic_block bb; int i, hard_regno, max_regno = max_reg_num (); @@ -1239,7 +1229,7 @@ lra_create_live_ranges (bool all_p, bool if (! have_referenced_pseudos) { timevar_pop (TV_LRA_CREATE_LIVE_RANGES); - return; + return false; } pseudos_live = sparseset_alloc (max_regno); @@ -1262,7 +1252,7 @@ lra_create_live_ranges (bool all_p, bool if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun) || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)) continue; - if (process_bb_lives (bb, curr_point, global_live_info_p)) + if (process_bb_lives (bb, curr_point, dead_insn_p)) bb_live_change_p = true; } if (bb_live_change_p) @@ -1317,6 +1307,27 @@ lra_create_live_ranges (bool all_p, bool sparseset_free (pseudos_live); compress_live_ranges (); timevar_pop (TV_LRA_CREATE_LIVE_RANGES); + return bb_live_change_p; +} + +/* The main entry function creates live-ranges and other live info + necessary for the assignment sub-pass. It uses + lra_creates_live_ranges_1 -- so read comments for the + function. */ +void +lra_create_live_ranges (bool all_p, bool dead_insn_p) +{ + if (! lra_create_live_ranges_1 (all_p, dead_insn_p)) + return; + if (lra_dump_file != NULL) + fprintf (lra_dump_file, "Live info was changed -- recalculate it\n"); + /* Live info was changed on a bb border. It means that some info, + e.g. about conflict regs, calls crossed may be wrong, live + ranges. We need this info for allocation. So recalcualate it + again. */ + lra_clear_live_ranges (); + bool res = lra_create_live_ranges_1 (all_p, dead_insn_p); + lra_assert (! res); } /* Finish all live ranges. */