From patchwork Thu Oct 20 15:28:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiong Wang X-Patchwork-Id: 78529 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp842845qge; Thu, 20 Oct 2016 08:29:09 -0700 (PDT) X-Received: by 10.98.139.193 with SMTP id e62mr2348264pfl.84.1476977349929; Thu, 20 Oct 2016 08:29:09 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id l184si11812490pge.112.2016.10.20.08.29.09 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 20 Oct 2016 08:29:09 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-439144-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-439144-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-439144-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=TtKbgfvMJ1BjEmaGSW3F43EmEv015+Ro3t4kKm3EjuxLA6HHRI CObYUx7Na0OSd6eoDrO49+aDJLDmiFYZ6v+wTyt+igCar74eEe5AsCLcfJ8jg/uD 2QlqqAXM7w2XUzUO2Z9fnbe9CMyA/j8lScBdZaMOyzXL1093xK2XeZpZ8= 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:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=H/lbRHzD/Q1St9idh7CzvbKL9F4=; b=Tv6wEzIUDqol8tuzVQDA d/ACM5OHB5UoQhWs2d04xD1vFXLMhAJQGFJimaCgGGsx61dvRxuRzGW+Plz57TEP 5Vejt4WcEOUH7X1z51dRe/gGKs5qcK4INImgK+1rV2awx7lik7KmFRj3EMS/bnFh cIpfduWlYaz04ErdTxAMiw4= Received: (qmail 35996 invoked by alias); 20 Oct 2016 15:28:51 -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 35972 invoked by uid 89); 20 Oct 2016 15:28:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.7 required=5.0 tests=BAYES_20, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy=1399, 61707, 57637, INSN X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 20 Oct 2016 15:28:40 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0F86416; Thu, 20 Oct 2016 08:28:39 -0700 (PDT) Received: from [10.2.206.198] (e104437-lin.cambridge.arm.com [10.2.206.198]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9368D3F32C; Thu, 20 Oct 2016 08:28:38 -0700 (PDT) To: gcc-patches Cc: Eric Botcazou From: Jiong Wang Subject: [Patch, rtl] PR middle-end/78016, keep REG_NOTE order during insn copy Message-ID: <1f9dd2ba-6a92-3afc-a6fb-d4be914ab239@foss.arm.com> Date: Thu, 20 Oct 2016 16:28:36 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 X-IsSubscribed: yes As discussed on PR middle-end/78016, here is the patch. This patch makes EXPR_LIST/INST_LIST/INT_LIST insertion bi-directional, the new node can be inserted to either the start or the end of the given list. The existed alloc_EXPR_LIST, alloc_INSN_LIST becomes wrapper of new bi-directional function, there is no functional change on them, callers of them are *not affected*. This patch then factor out those REG_NOTES copy code in emit-rtl.c and sel-sched-ir.c into a function append_insn_reg_notes in rtlanal.c, it use those new bi-directional interfaces to make sure the order of REG_NOTES are not changed during insn copy. Redundant code in emit-rtl.c and sel-sched-ir.c are deleted also. x86_64/aarch64 bootstrap OK. c/c++ regression OK. OK for trunk? gcc/ 2016-10-20 Jiong Wang PR middle-end/78016 * lists.c (alloc_INSN_LIST_bidirection): New function. The function body is cloned from alloc_INSN_LIST with minor changes to make it support bi-directional insertion. (alloc_EXPR_LIST_bidirection): Likewise. (alloc_INT_LIST_bidirection): New function. Alloc INT_LIST node, and support bi-directional insertion into given list. (alloc_INSN_LIST): Call alloc_INSN_LIST_bidirection. (alloc_EXPR_LIST): Call alloc_EXPR_LIST_bidirection. * rtl.h (append_insn_reg_notes): New declaration. (alloc_INSN_LIST_bidirection): New declaration. (alloc_EXPR_LIST_bidirection): New declaration. (alloc_INT_LIST_bidirection): New declaration. * rtlanal.c (alloc_reg_note_bidirection): New static function. Function body is cloned from alloc_reg_note with minor changes to make it support bi-directional insertion. (alloc_reg_note): Call alloc_reg_note_bidirection. (append_insn_reg_notes): New function. * emit-rtl.c (emit_copy_of_insn_after): Use append_insn_reg_notes. * sel-sched-ir.c (create_copy_of_insn_rtx): Likewise. diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 2d6d1eb..87eb1e3 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -6125,7 +6125,6 @@ rtx_insn * emit_copy_of_insn_after (rtx_insn *insn, rtx_insn *after) { rtx_insn *new_rtx; - rtx link; switch (GET_CODE (insn)) { @@ -6171,15 +6170,7 @@ emit_copy_of_insn_after (rtx_insn *insn, rtx_insn *after) /* Copy all REG_NOTES except REG_LABEL_OPERAND since mark_jump_label will make them. REG_LABEL_TARGETs are created there too, but are supposed to be sticky, so we copy them. */ - for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) - if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND) - { - if (GET_CODE (link) == EXPR_LIST) - add_reg_note (new_rtx, REG_NOTE_KIND (link), - copy_insn_1 (XEXP (link, 0))); - else - add_shallow_copy_of_reg_note (new_rtx, link); - } + append_insn_reg_notes (new_rtx, insn, true, false); INSN_CODE (new_rtx) = INSN_CODE (insn); return new_rtx; diff --git a/gcc/lists.c b/gcc/lists.c index 96b4bc7..cd30b7c 100644 --- a/gcc/lists.c +++ b/gcc/lists.c @@ -98,11 +98,14 @@ remove_list_elem (rtx elem, rtx *listp) /* This call is used in place of a gen_rtx_INSN_LIST. If there is a cached node available, we'll use it, otherwise a call to gen_rtx_INSN_LIST - is made. */ + is made. The new node will be appended at the end of LIST if APPEND_P is + TRUE, otherwise list is appended to the new node. */ + rtx_insn_list * -alloc_INSN_LIST (rtx val, rtx next) +alloc_INSN_LIST_bidirection (rtx val, rtx list, bool append_p) { rtx_insn_list *r; + rtx next = append_p ? NULL_RTX : list; if (unused_insn_list) { @@ -117,16 +120,33 @@ alloc_INSN_LIST (rtx val, rtx next) else r = gen_rtx_INSN_LIST (VOIDmode, val, next); + if (append_p) + { + gcc_assert (list != NULL_RTX); + XEXP (list, 1) = r; + } + return r; } +/* Allocate new INSN_LIST node for VAL, append NEXT to it. */ + +rtx_insn_list * +alloc_INSN_LIST (rtx val, rtx next) +{ + return alloc_INSN_LIST_bidirection (val, next, false); +} + /* This call is used in place of a gen_rtx_EXPR_LIST. If there is a cached node available, we'll use it, otherwise a call to gen_rtx_EXPR_LIST - is made. */ + is made. The new node will be appended at the end of LIST if APPEND_P is + TRUE, otherwise list is appended to the new node. */ + rtx_expr_list * -alloc_EXPR_LIST (int kind, rtx val, rtx next) +alloc_EXPR_LIST_bidirection (int kind, rtx val, rtx list, bool append_p) { rtx_expr_list *r; + rtx next = append_p ? NULL_RTX : list; if (unused_expr_list) { @@ -139,9 +159,23 @@ alloc_EXPR_LIST (int kind, rtx val, rtx next) else r = gen_rtx_EXPR_LIST ((machine_mode) kind, val, next); + if (append_p) + { + gcc_assert (list != NULL_RTX); + XEXP (list, 1) = r; + } + return r; } +/* Allocate new EXPR_LIST node for KIND and VAL, append NEXT to it. */ + +rtx_expr_list * +alloc_EXPR_LIST (int kind, rtx val, rtx next) +{ + return alloc_EXPR_LIST_bidirection (kind, val, next, false); +} + /* This function will free up an entire list of EXPR_LIST nodes. */ void free_EXPR_LIST_list (rtx_expr_list **listp) @@ -242,4 +276,22 @@ remove_free_EXPR_LIST_node (rtx_expr_list **listp) return elem; } +/* Allocate new INT_LIST node for KIND and VAL, append it to LIST if APPEND_P is + TRUE, otherwise append LIST to it. */ + +rtx +alloc_INT_LIST_bidirection (int kind, int val, rtx list, bool append_p) +{ + rtx r = gen_rtx_INT_LIST ((machine_mode) kind, val, + append_p ? NULL_RTX : list); + + if (append_p) + { + gcc_assert (list != NULL_RTX); + XEXP (list, 1) = r; + } + + return r; +} + #include "gt-lists.h" diff --git a/gcc/rtl.h b/gcc/rtl.h index ce1131b..5ce0c27 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -2996,6 +2996,7 @@ extern rtx alloc_reg_note (enum reg_note, rtx, rtx); extern void add_reg_note (rtx, enum reg_note, rtx); extern void add_int_reg_note (rtx, enum reg_note, int); extern void add_shallow_copy_of_reg_note (rtx_insn *, rtx); +extern void append_insn_reg_notes (rtx_insn *, rtx_insn *, bool, bool); extern void remove_note (rtx, const_rtx); extern void remove_reg_equal_equiv_notes (rtx_insn *); extern void remove_reg_equal_equiv_notes_for_regno (unsigned int); @@ -3095,13 +3096,16 @@ extern void free_INSN_LIST_list (rtx_insn_list **); extern void free_EXPR_LIST_node (rtx); extern void free_INSN_LIST_node (rtx); extern rtx_insn_list *alloc_INSN_LIST (rtx, rtx); +extern rtx_insn_list *alloc_INSN_LIST_bidirection (rtx, rtx, bool); extern rtx_insn_list *copy_INSN_LIST (rtx_insn_list *); extern rtx_insn_list *concat_INSN_LIST (rtx_insn_list *, rtx_insn_list *); extern rtx_expr_list *alloc_EXPR_LIST (int, rtx, rtx); +extern rtx_expr_list *alloc_EXPR_LIST_bidirection (int, rtx, rtx, bool); extern void remove_free_INSN_LIST_elem (rtx_insn *, rtx_insn_list **); extern rtx remove_list_elem (rtx, rtx *); extern rtx_insn *remove_free_INSN_LIST_node (rtx_insn_list **); extern rtx remove_free_EXPR_LIST_node (rtx_expr_list **); +extern rtx alloc_INT_LIST_bidirection (int, int, rtx, bool); /* reginfo.c */ diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 2a0a1d2..7effdd8 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -2244,10 +2244,12 @@ int_reg_note_p (enum reg_note kind) } /* Allocate a register note with kind KIND and datum DATUM. LIST is - stored as the pointer to the next register note. */ + stored as the pointer to the existed register note. Append new note to LIST + if APPEND_P is TRUE, otherwise append LIST to new note. */ -rtx -alloc_reg_note (enum reg_note kind, rtx datum, rtx list) +static rtx +alloc_reg_note_bidirection (enum reg_note kind, rtx datum, rtx list, + bool append_p) { rtx note; @@ -2262,18 +2264,27 @@ alloc_reg_note (enum reg_note kind, rtx datum, rtx list) /* These types of register notes use an INSN_LIST rather than an EXPR_LIST, so that copying is done right and dumps look better. */ - note = alloc_INSN_LIST (datum, list); + note = alloc_INSN_LIST_bidirection (datum, list, append_p); PUT_REG_NOTE_KIND (note, kind); break; default: - note = alloc_EXPR_LIST (kind, datum, list); + note = alloc_EXPR_LIST_bidirection (kind, datum, list, append_p); break; } return note; } +/* Allocate a register note with kind KIND and datum DATUM. Append LIST to the + new note. */ + +rtx +alloc_reg_note (enum reg_note kind, rtx datum, rtx list) +{ + return alloc_reg_note_bidirection (kind, datum, list, false); +} + /* Add register note with kind KIND and datum DATUM to INSN. */ void @@ -2334,6 +2345,66 @@ remove_note (rtx insn, const_rtx note) } } +/* Append all REG_NOTES in order from FROM_INSN to end of existed REG_NOTES of + TO_INSN. Skip REG_LABEL_OPERAND if skip_reg_label_p is TRUE, skip REG_EQUAL + and REG_EQUIV if skip_reg_equ_p is TRUE. */ + +void +append_insn_reg_notes (rtx_insn *to_insn, rtx_insn *from_insn, + bool skip_reg_label_p, bool skip_reg_equ_p) +{ + /* Locate to the end of existed REG_NOTES of TO_INSN. */ + rtx tail = REG_NOTES (to_insn); + + if (tail != NULL_RTX) + { + rtx tail_old; + + do { + tail_old = tail; + tail = XEXP (tail, 1); + } while (tail != NULL_RTX); + + tail = tail_old; + } + + /* Do the insertion. */ + rtx link; + enum reg_note kind; + for (link = REG_NOTES (from_insn); link; link = XEXP (link, 1)) + { + kind = REG_NOTE_KIND (link); + + if ((skip_reg_label_p && kind == REG_LABEL_OPERAND) + || (skip_reg_equ_p && (kind == REG_EQUAL || kind == REG_EQUIV))) + continue; + + if (tail == NULL_RTX) + { + /* Initialize the head of REG_NOTES for TO_RTX if necessary. */ + if (GET_CODE (link) == INT_LIST) + add_shallow_copy_of_reg_note (to_insn, link); + else + add_reg_note (to_insn, kind, (GET_CODE (link) == EXPR_LIST + ? copy_insn_1 (XEXP (link, 0)) + : XEXP (link ,0))); + tail = REG_NOTES (to_insn); + } + else + { + /* Append to the end of existed REG_NOTES of TO_RTX. */ + if (GET_CODE (link) == INT_LIST) + tail = alloc_INT_LIST_bidirection (kind, XINT (link, 0), tail, + true); + else + tail = alloc_reg_note_bidirection (kind, + (GET_CODE (link) == EXPR_LIST + ? copy_insn_1 (XEXP (link, 0)) + : XEXP (link, 0)), tail, true); + } + } +} + /* Remove REG_EQUAL and/or REG_EQUIV notes if INSN has such notes. */ void diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index 210b1e4..bd28f15 100644 --- a/gcc/sel-sched-ir.c +++ b/gcc/sel-sched-ir.c @@ -5750,7 +5750,6 @@ rtx_insn * create_copy_of_insn_rtx (rtx insn_rtx) { rtx_insn *res; - rtx link; if (DEBUG_INSN_P (insn_rtx)) return create_insn_rtx_from_pattern (copy_rtx (PATTERN (insn_rtx)), @@ -5764,17 +5763,7 @@ create_copy_of_insn_rtx (rtx insn_rtx) /* Copy all REG_NOTES except REG_EQUAL/REG_EQUIV and REG_LABEL_OPERAND since mark_jump_label will make them. REG_LABEL_TARGETs are created there too, but are supposed to be sticky, so we copy them. */ - for (link = REG_NOTES (insn_rtx); link; link = XEXP (link, 1)) - if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND - && REG_NOTE_KIND (link) != REG_EQUAL - && REG_NOTE_KIND (link) != REG_EQUIV) - { - if (GET_CODE (link) == EXPR_LIST) - add_reg_note (res, REG_NOTE_KIND (link), - copy_insn_1 (XEXP (link, 0))); - else - add_reg_note (res, REG_NOTE_KIND (link), XEXP (link, 0)); - } + append_insn_reg_notes (res, safe_as_a (insn_rtx), true, true); return res; }