From patchwork Tue Apr 16 22:15:28 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Bosscher X-Patchwork-Id: 237117 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 5A94E2C0130 for ; Wed, 17 Apr 2013 08:16:19 +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 :mime-version:from:date:message-id:subject:to:cc:content-type; q=dns; s=default; b=r4N8r83IFSjBFGSbk/a0sIYIKoBguC2fug0s7VFatl+ g79GWlR8kNrFQg3BWVGeBA5C819gWLDOMa3SXQT3Ugel9M9t+I2Prvvyfw5kp0Yu ikKenMbePWvztWZRnDaf/kjYv0RWzsTdvTKjrt7oe/nxpX79nkvgg1Nebf+kmMoQ = 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 :mime-version:from:date:message-id:subject:to:cc:content-type; s=default; bh=wyVBdhsDbsy1cNFwYFMWbNRo3SA=; b=iqGOJ1CFmgI44p7MZ kwploutmNahf0xiELuQuEmZuTABHBUk8OtSmahxoVbcq79YLseJJIjtvcakw/3D/ e4cKOd96Q0c72b5A/Y1feK4wfw1v+45I0SnEAgufg2nXbqRWhyuwHf523ZPddqN3 +2KAhhwcoXOyKI5P02MBQD+cW8= Received: (qmail 32071 invoked by alias); 16 Apr 2013 22:16:12 -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 32060 invoked by uid 89); 16 Apr 2013 22:16:12 -0000 X-Spam-SWARE-Status: No, score=-4.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, TW_EQ autolearn=ham version=3.3.1 Received: from mail-ve0-f179.google.com (HELO mail-ve0-f179.google.com) (209.85.128.179) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Tue, 16 Apr 2013 22:16:11 +0000 Received: by mail-ve0-f179.google.com with SMTP id oz10so924250veb.10 for ; Tue, 16 Apr 2013 15:16:10 -0700 (PDT) X-Received: by 10.220.168.202 with SMTP id v10mr2952153vcy.71.1366150569952; Tue, 16 Apr 2013 15:16:09 -0700 (PDT) MIME-Version: 1.0 Received: by 10.58.240.13 with HTTP; Tue, 16 Apr 2013 15:15:28 -0700 (PDT) From: Steven Bosscher Date: Wed, 17 Apr 2013 00:15:28 +0200 Message-ID: Subject: [patch] simplify emit_delay_sequence To: GCC Patches Cc: Eric Botcazou X-Virus-Found: No Hello, With the recent add_insn_* cleanups, we can now simplify reorg.c:emit_delay_sequence. Without this patch, emit_delay_sequence hacks the insns chain "manually", setting PREV_INSN and NEXT_INSN to chain everything together properly. But emit-rtl provides an abstraction of sorts for that, and emit_delay_sequence should use it. This wasn't possible before, because inserting a SEQUENCE wasn't allowed. But with a 5-line change in emit-rtl.c, inserting a SEQUENCE via add_insn, add_insn_before, and add_insn_after now works just fine.: This patch is also necessary for my new delay-slot scheduler to keep basic block boundaries correctly up-to-date. The emit-rtl API does that already. Cross-tested powerpc64 x mips. Currently running bootstrap&test on sparc64-unknown-linux-gnu. OK if it passes? Ciao! Steven * emit-rtl.c (link_insn_into_chain): Handle chaining of SEQUENCEs. * reorg.c (emit_delay_sequence): Simplify with emit-rtl API. Index: emit-rtl.c =================================================================== --- emit-rtl.c (revision 198008) +++ emit-rtl.c (working copy) @@ -3806,6 +3806,13 @@ link_insn_into_chain (rtx insn, rtx prev, rtx next if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE) PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = insn; } + + if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE) + { + rtx sequence = PATTERN (insn); + PREV_INSN (XVECEXP (sequence, 0, 0)) = prev; + NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = next; + } } /* Add INSN to the end of the doubly-linked list. Index: reorg.c =================================================================== --- reorg.c (revision 198008) +++ reorg.c (working copy) @@ -458,69 +458,32 @@ find_end_label (rtx kind) /* Put INSN and LIST together in a SEQUENCE rtx of LENGTH, and replace the pattern of INSN with the SEQUENCE. - Chain the insns so that NEXT_INSN of each insn in the sequence points to - the next and NEXT_INSN of the last insn in the sequence points to - the first insn after the sequence. Similarly for PREV_INSN. This makes - it easier to scan all insns. - Returns the SEQUENCE that replaces INSN. */ static rtx emit_delay_sequence (rtx insn, rtx list, int length) { - int i = 1; - rtx li; - int had_barrier = 0; - /* Allocate the rtvec to hold the insns and the SEQUENCE. */ rtvec seqv = rtvec_alloc (length + 1); rtx seq = gen_rtx_SEQUENCE (VOIDmode, seqv); rtx seq_insn = make_insn_raw (seq); - rtx first = get_insns (); - rtx last = get_last_insn (); - /* Make a copy of the insn having delay slots. */ - rtx delay_insn = copy_rtx (insn); + /* If DELAY_INSN has a location, use it for SEQ_INSN. If DELAY_INSN does + not have a location, but one of the delayed insns does, we pick up a + location from there later. */ + INSN_LOCATION (seq_insn) = INSN_LOCATION (insn); - /* If INSN is followed by a BARRIER, delete the BARRIER since it will only - confuse further processing. Update LAST in case it was the last insn. - We will put the BARRIER back in later. */ - if (NEXT_INSN (insn) && BARRIER_P (NEXT_INSN (insn))) - { - delete_related_insns (NEXT_INSN (insn)); - last = get_last_insn (); - had_barrier = 1; - } + /* Unlink INSN from the insn chain, so that we can put it into + the SEQUENCE. Remember where we want to emit SEQUENCE in AFTER. */ + rtx after = PREV_INSN (insn); + remove_insn (insn); + NEXT_INSN (insn) = PREV_INSN (insn) = NULL; - /* Splice our SEQUENCE into the insn stream where INSN used to be. */ - NEXT_INSN (seq_insn) = NEXT_INSN (insn); - PREV_INSN (seq_insn) = PREV_INSN (insn); - - if (insn != last) - PREV_INSN (NEXT_INSN (seq_insn)) = seq_insn; - - if (insn != first) - NEXT_INSN (PREV_INSN (seq_insn)) = seq_insn; - - /* Note the calls to set_new_first_and_last_insn must occur after - SEQ_INSN has been completely spliced into the insn stream. - - Otherwise CUR_INSN_UID will get set to an incorrect value because - set_new_first_and_last_insn will not find SEQ_INSN in the chain. */ - if (insn == last) - set_new_first_and_last_insn (first, seq_insn); - - if (insn == first) - set_new_first_and_last_insn (seq_insn, last); - /* Build our SEQUENCE and rebuild the insn chain. */ - XVECEXP (seq, 0, 0) = delay_insn; - INSN_DELETED_P (delay_insn) = 0; - PREV_INSN (delay_insn) = PREV_INSN (seq_insn); - - INSN_LOCATION (seq_insn) = INSN_LOCATION (delay_insn); - - for (li = list; li; li = XEXP (li, 1), i++) + int i = 1; + start_sequence (); + XVECEXP (seq, 0, 0) = emit_insn (insn); + for (rtx li = list; li; li = XEXP (li, 1), i++) { rtx tem = XEXP (li, 0); rtx note, next; @@ -528,9 +491,10 @@ emit_delay_sequence (rtx insn, rtx list, int lengt /* Show that this copy of the insn isn't deleted. */ INSN_DELETED_P (tem) = 0; - XVECEXP (seq, 0, i) = tem; - PREV_INSN (tem) = XVECEXP (seq, 0, i - 1); - NEXT_INSN (XVECEXP (seq, 0, i - 1)) = tem; + /* Unlink insn from its original place, and re-emit it into + the sequence. */ + NEXT_INSN (tem) = PREV_INSN (tem) = NULL; + XVECEXP (seq, 0, i) = emit_insn (tem); /* SPARC assembler, for instance, emit warning when debug info is output into the delay slot. */ @@ -538,6 +502,8 @@ emit_delay_sequence (rtx insn, rtx list, int lengt INSN_LOCATION (seq_insn) = INSN_LOCATION (tem); INSN_LOCATION (tem) = 0; + /* Remove any REG_DEAD notes because we can't rely on them now + that the insn has been moved. */ for (note = REG_NOTES (tem); note; note = next) { next = XEXP (note, 1); @@ -561,29 +527,12 @@ emit_delay_sequence (rtx insn, rtx list, int lengt } } } - - NEXT_INSN (XVECEXP (seq, 0, length)) = NEXT_INSN (seq_insn); - - /* If the previous insn is a SEQUENCE, update the NEXT_INSN pointer on the - last insn in that SEQUENCE to point to us. Similarly for the first - insn in the following insn if it is a SEQUENCE. */ - - if (PREV_INSN (seq_insn) && NONJUMP_INSN_P (PREV_INSN (seq_insn)) - && GET_CODE (PATTERN (PREV_INSN (seq_insn))) == SEQUENCE) - NEXT_INSN (XVECEXP (PATTERN (PREV_INSN (seq_insn)), 0, - XVECLEN (PATTERN (PREV_INSN (seq_insn)), 0) - 1)) - = seq_insn; - - if (NEXT_INSN (seq_insn) && NONJUMP_INSN_P (NEXT_INSN (seq_insn)) - && GET_CODE (PATTERN (NEXT_INSN (seq_insn))) == SEQUENCE) - PREV_INSN (XVECEXP (PATTERN (NEXT_INSN (seq_insn)), 0, 0)) = seq_insn; - - /* If there used to be a BARRIER, put it back. */ - if (had_barrier) - emit_barrier_after (seq_insn); - + end_sequence (); gcc_assert (i == length + 1); + /* Splice our SEQUENCE into the insn stream where INSN used to be. */ + add_insn_after (seq_insn, after, NULL); + return seq_insn; }