From patchwork Sun Aug 3 14:25:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 376048 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 BAD9A1400A3 for ; Mon, 4 Aug 2014 00:25:52 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=default; b=pE4NKmwtNLoP9EzwMEB5WNjj6sXHB gW8ggGx9D7ESu+RwJU5b9vrpKKeXgFYJKppEPf4/FT2ig/n9J8PrWC8Ujah6bT3g PZ2imjw7Qcz+1OmXdn6Fn0FFaR5ABfiGYXMBXMZ3I/PaVqBFhNniN/ouxCu8jlhB VXltHl7z4RipG4= 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:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type; s=default; bh=0S65kOLN2jVh5pexAYXTO/fJX7U=; b=Lsk RpW5iMlmcEe1Qa2SgZdbw6Aevb+NbPZYVHfGGcs1DqKHa5yzNA+WpD1qW8iatIwq fpqUKpLlC33bWofejn6W8J75zJq9hvqZqvLD8LbBWI9Sext32J5t6qvdvvOx6ttH d6VkVIhsy8dR/Bw/zvZkt0lTTrm8vn22Hr3MM4EE= Received: (qmail 7783 invoked by alias); 3 Aug 2014 14:25:46 -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 7774 invoked by uid 89); 3 Aug 2014 14:25:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-wi0-f177.google.com Received: from mail-wi0-f177.google.com (HELO mail-wi0-f177.google.com) (209.85.212.177) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Sun, 03 Aug 2014 14:25:43 +0000 Received: by mail-wi0-f177.google.com with SMTP id ho1so3679735wib.4 for ; Sun, 03 Aug 2014 07:25:40 -0700 (PDT) X-Received: by 10.194.23.135 with SMTP id m7mr24045690wjf.2.1407075940659; Sun, 03 Aug 2014 07:25:40 -0700 (PDT) Received: from localhost ([95.145.138.172]) by mx.google.com with ESMTPSA id fs3sm30383899wic.20.2014.08.03.07.25.39 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Aug 2014 07:25:40 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, rdsandiford@googlemail.com Subject: [PATCH 38/50] rtlanal.c:replace_label References: <87y4v5d77q.fsf@googlemail.com> Date: Sun, 03 Aug 2014 15:25:39 +0100 In-Reply-To: <87y4v5d77q.fsf@googlemail.com> (Richard Sandiford's message of "Sun, 03 Aug 2014 14:38:01 +0100") Message-ID: <87egwx7iqk.fsf@googlemail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 The main change here is to handle ADDR_VEC and ADDR_DIFF_VECs specially, since they can have many elements and are a relatively important case for this function. This is for speed rather than correctness. gcc/ * rtl.h (replace_label_data): Delete. (replace_label): Take the old label, new label and update-nuses flag as direct arguments. Return void. * cfgcleanup.c (outgoing_edges_match): Update accordingly. * rtlanal.c (replace_label): Update interface as above. Handle JUMP_TABLE_DATA as a special case. Handle JUMPs outside the iterator. Use FOR_EACH_SUBRTX_PTR. Index: gcc/rtl.h =================================================================== --- gcc/rtl.h 2014-08-03 11:25:30.447157195 +0100 +++ gcc/rtl.h 2014-08-03 11:25:30.745160142 +0100 @@ -2211,14 +2211,6 @@ #define single_set(I) (INSN_P (I) \ : NULL_RTX) #define single_set_1(I) single_set_2 (I, PATTERN (I)) -/* Structure used for passing data to REPLACE_LABEL. */ -struct replace_label_data -{ - rtx r1; - rtx r2; - bool update_label_nuses; -}; - extern enum machine_mode get_address_mode (rtx mem); extern int rtx_addr_can_trap_p (const_rtx); extern bool nonzero_address_p (const_rtx); @@ -2287,7 +2279,7 @@ extern void copy_reg_eh_region_note_forw extern void copy_reg_eh_region_note_backward (rtx, rtx, rtx); extern int inequality_comparisons_p (const_rtx); extern rtx replace_rtx (rtx, rtx, rtx); -extern int replace_label (rtx *, void *); +extern void replace_label (rtx *, rtx, rtx, bool); extern bool rtx_referenced_p (const_rtx, const_rtx); extern bool tablejump_p (const_rtx, rtx *, rtx *); extern int computed_jump_p (const_rtx); Index: gcc/cfgcleanup.c =================================================================== --- gcc/cfgcleanup.c 2014-08-03 11:25:22.602079634 +0100 +++ gcc/cfgcleanup.c 2014-08-03 11:25:30.745160142 +0100 @@ -1716,15 +1716,11 @@ outgoing_edges_match (int mode, basic_bl if (identical) { - replace_label_data rr; bool match; /* Temporarily replace references to LABEL1 with LABEL2 in BB1->END so that we could compare the instructions. */ - rr.r1 = label1; - rr.r2 = label2; - rr.update_label_nuses = false; - for_each_rtx (&BB_END (bb1), replace_label, &rr); + replace_label (&BB_END (bb1), label1, label2, false); match = (old_insns_match_p (mode, BB_END (bb1), BB_END (bb2)) == dir_both); @@ -1736,9 +1732,7 @@ outgoing_edges_match (int mode, basic_bl /* Set the original label in BB1->END because when deleting a block whose end is a tablejump, the tablejump referenced from the instruction is deleted too. */ - rr.r1 = label2; - rr.r2 = label1; - for_each_rtx (&BB_END (bb1), replace_label, &rr); + replace_label (&BB_END (bb1), label2, label1, false); return match; } @@ -1985,20 +1979,16 @@ #define SWAP(T, X, Y) do { T tmp = (X); && tablejump_p (BB_END (osrc2), &label2, &table2) && label1 != label2) { - replace_label_data rr; rtx insn; /* Replace references to LABEL1 with LABEL2. */ - rr.r1 = label1; - rr.r2 = label2; - rr.update_label_nuses = true; for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) { /* Do not replace the label in SRC1->END because when deleting a block whose end is a tablejump, the tablejump referenced from the instruction is deleted too. */ if (insn != BB_END (osrc1)) - for_each_rtx (&insn, replace_label, &rr); + replace_label (&insn, label1, label2, true); } } } Index: gcc/rtlanal.c =================================================================== --- gcc/rtlanal.c 2014-08-03 11:25:30.448157205 +0100 +++ gcc/rtlanal.c 2014-08-03 11:25:30.746160151 +0100 @@ -2770,65 +2770,79 @@ replace_rtx (rtx x, rtx from, rtx to) return x; } -/* Replace occurrences of the old label in *X with the new one. - DATA is a REPLACE_LABEL_DATA containing the old and new labels. */ +/* Replace occurrences of the OLD_LABEL in *LOC with NEW_LABEL. Also track + the change in LABEL_NUSES if UPDATE_LABEL_NUSES. */ -int -replace_label (rtx *x, void *data) +void +replace_label (rtx *loc, rtx old_label, rtx new_label, bool update_label_nuses) { - rtx l = *x; - rtx old_label = ((replace_label_data *) data)->r1; - rtx new_label = ((replace_label_data *) data)->r2; - bool update_label_nuses = ((replace_label_data *) data)->update_label_nuses; - - if (l == NULL_RTX) - return 0; - - if (GET_CODE (l) == SYMBOL_REF - && CONSTANT_POOL_ADDRESS_P (l)) + /* Handle jump tables specially, since ADDR_{DIFF_,}VECs can be long. */ + rtx x = *loc; + if (JUMP_TABLE_DATA_P (x)) { - rtx c = get_pool_constant (l); - if (rtx_referenced_p (old_label, c)) + x = PATTERN (x); + rtvec vec = XVEC (x, GET_CODE (x) == ADDR_DIFF_VEC); + int len = GET_NUM_ELEM (vec); + for (int i = 0; i < len; ++i) { - rtx new_c, new_l; - replace_label_data *d = (replace_label_data *) data; - - /* Create a copy of constant C; replace the label inside - but do not update LABEL_NUSES because uses in constant pool - are not counted. */ - new_c = copy_rtx (c); - d->update_label_nuses = false; - for_each_rtx (&new_c, replace_label, data); - d->update_label_nuses = update_label_nuses; - - /* Add the new constant NEW_C to constant pool and replace - the old reference to constant by new reference. */ - new_l = XEXP (force_const_mem (get_pool_mode (l), new_c), 0); - *x = replace_rtx (l, l, new_l); + rtx ref = RTVEC_ELT (vec, i); + if (XEXP (ref, 0) == old_label) + { + XEXP (ref, 0) = new_label; + if (update_label_nuses) + { + ++LABEL_NUSES (new_label); + --LABEL_NUSES (old_label); + } + } } - return 0; + return; } /* If this is a JUMP_INSN, then we also need to fix the JUMP_LABEL - field. This is not handled by for_each_rtx because it doesn't + field. This is not handled by the iterator because it doesn't handle unprinted ('0') fields. */ - if (JUMP_P (l) && JUMP_LABEL (l) == old_label) - JUMP_LABEL (l) = new_label; + if (JUMP_P (x) && JUMP_LABEL (x) == old_label) + JUMP_LABEL (x) = new_label; - if ((GET_CODE (l) == LABEL_REF - || GET_CODE (l) == INSN_LIST) - && XEXP (l, 0) == old_label) + subrtx_ptr_iterator::array_type array; + FOR_EACH_SUBRTX_PTR (iter, array, loc, ALL) { - XEXP (l, 0) = new_label; - if (update_label_nuses) + rtx *loc = *iter; + if (rtx x = *loc) { - ++LABEL_NUSES (new_label); - --LABEL_NUSES (old_label); + if (GET_CODE (x) == SYMBOL_REF + && CONSTANT_POOL_ADDRESS_P (x)) + { + rtx c = get_pool_constant (x); + if (rtx_referenced_p (old_label, c)) + { + /* Create a copy of constant C; replace the label inside + but do not update LABEL_NUSES because uses in constant pool + are not counted. */ + rtx new_c = copy_rtx (c); + replace_label (&new_c, old_label, new_label, false); + + /* Add the new constant NEW_C to constant pool and replace + the old reference to constant by new reference. */ + rtx new_mem = force_const_mem (get_pool_mode (x), new_c); + *loc = replace_rtx (x, x, XEXP (new_mem, 0)); + } + } + + if ((GET_CODE (x) == LABEL_REF + || GET_CODE (x) == INSN_LIST) + && XEXP (x, 0) == old_label) + { + XEXP (x, 0) = new_label; + if (update_label_nuses) + { + ++LABEL_NUSES (new_label); + --LABEL_NUSES (old_label); + } + } } - return 0; } - - return 0; } /* Return true if X is referenced in BODY. */