From patchwork Thu Nov 16 12:35:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Hayward X-Patchwork-Id: 838537 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-466988-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="DzN3GY02"; dkim-atps=neutral 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 3yd11j0bBBz9ryT for ; Thu, 16 Nov 2017 23:35:52 +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:from :to:cc:subject:date:message-id:content-type:content-id :content-transfer-encoding:mime-version; q=dns; s=default; b=QkC cixtKYVjdqqndPsvLxNDZKueSBsGcc4iimqolGWadAocejutOMIFjbGYqEaiTI+K Q6dd1Cde6UHRzoIpy5er8ouOruo1oP60MRx/yckXlkEIgcYRorohGMgXu57JOG7S HTTyUSldFecKiAFu9T8sDY1i2R+g+JZa2IDfdq5Q= 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:cc:subject:date:message-id:content-type:content-id :content-transfer-encoding:mime-version; s=default; bh=od9oRvS3D W3eniOExcsZJ++jWmw=; b=DzN3GY023fKO9wdAbJcqXq6h5hLxUNoAFJuq1LOY3 Xo/+iZVZqvmxX8v5YlcPSpRMef+tuT55WPlthF85uE06O7/4K//+uHU2auT2vY0A gieANEs2Lywh4vVFmYJiavZH+zwzHsroQFCNn00VAyh+qfj0CZg42XD1qr9Oti9W +k= Received: (qmail 13467 invoked by alias); 16 Nov 2017 12:35:34 -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 13341 invoked by uid 89); 16 Nov 2017 12:35:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LOTSOFHASH, KB_WAM_FROM_NAME_SINGLEWORD, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: EUR02-AM5-obe.outbound.protection.outlook.com Received: from mail-eopbgr00066.outbound.protection.outlook.com (HELO EUR02-AM5-obe.outbound.protection.outlook.com) (40.107.0.66) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 16 Nov 2017 12:35:30 +0000 Received: from AM3PR08MB0101.eurprd08.prod.outlook.com (10.160.211.19) by AM3PR08MB0103.eurprd08.prod.outlook.com (10.160.211.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.239.5; Thu, 16 Nov 2017 12:35:25 +0000 Received: from AM3PR08MB0101.eurprd08.prod.outlook.com ([fe80::2891:52f2:59:8e54]) by AM3PR08MB0101.eurprd08.prod.outlook.com ([fe80::2891:52f2:59:8e54%16]) with mapi id 15.20.0218.015; Thu, 16 Nov 2017 12:35:25 +0000 From: Alan Hayward To: "gcc-patches@gcc.gnu.org" CC: nd Subject: [PATCH 5/7]: cse support for clobber_high Date: Thu, 16 Nov 2017 12:35:25 +0000 Message-ID: <953AA06E-16AD-4135-9216-CADCB8E08417@arm.com> authentication-results: spf=none (sender IP is ) smtp.mailfrom=Alan.Hayward@arm.com; x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM3PR08MB0103; 6:g+lOKInzt04KWv1eo8KsZFwDnyThZamu51CIIfTbJ+86m6nZBSoEdk4InwTgMCsT+Z7fOubLwWTYFT5bXZu2MHvdWH3Cmj9YKlWJtzu4/8j02OQ51aBTr9c/qNrMvCHsxuGxacomahBka4F8TLFdGMn/vytwlyGF64SYiZKKZBrY2iQpR9mrTJu4LWuSWlcpE2URC6JEhxqUUFP6RWNL0ftn9GXjftj7oHt+Nl2ZvUg5iQwlWI4Rv4wagpMkznxI73xMl2S1N9iEU9NMs+yYaJVL2cx67lQjQ3nyuhZnlUECDnYlJ4Ag9LIswd17SLFREqKBrFExZaM1d7d+mhWdluBRaue9NcF7ruwUtyjRH6s=; 5:+ontmSIGfbeaG9mW5Vge0RsbzKGhf/8HzLDd5oDZ5L2vPyvQkb5KG/95AKOT/GnUYNKTuJaFydwhzGsWM7wSshGp2uTvddToh0SfG2GEEKm6bmKuIV4NCz9Wbvs5VVGeO1Utt73lFAeblEP+XnzHdlt9dvXmv9j4Asu2j1VfaFw=; 24:p5MN9EIJePu3RhiI4urjag96DrArlYIxeVQpS9BDAET9+f0TyJtgzQwDELpyO3r0YJLW+kxXI5cCsOhhMafMT+U4s+aJU0NLCDh4/eJyh0g=; 7:e0NPgzyHcM1D85xKLUBXf7TowgOG9GNT0SMtWrhxkwIdO4ISxmPNZiBfLivIROgpX3WorupKmf/ouYrgOXHqM3CZlNVQ/rRhIYVlSCDA7pIXwGZAvuv0WcxDCJIOeAgUOOFVQUG73HDBtMKE7z3aQlhD/Lp686QqIbUVxiCZIYqdyiWb0itA1Q5FGIQJax0YsJv0r1zQIViF0EfkvBtcOopyrwPl1GMufxRnZUZJmBkgZXBrKqngU6tXi0n69HnA x-ms-exchange-antispam-srfa-diagnostics: SSOS; x-ms-office365-filtering-correlation-id: 993aa1c2-87b2-45a0-031a-08d52cee8309 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(48565401081)(4534020)(4602075)(4627115)(201703031133081)(201702281549075)(2017052603199); SRVR:AM3PR08MB0103; x-ms-traffictypediagnostic: AM3PR08MB0103: nodisclaimer: True x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(180628864354917); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(8121501046)(5005006)(100000703101)(100105400095)(93006095)(93001095)(10201501046)(3002001)(3231022)(6055026)(6041248)(20161123564025)(20161123560025)(20161123558100)(20161123562025)(20161123555025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:AM3PR08MB0103; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:AM3PR08MB0103; x-forefront-prvs: 0493852DA9 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(6009001)(39860400002)(376002)(346002)(377424004)(199003)(189002)(6512007)(6116002)(5250100002)(5660300001)(25786009)(86362001)(106356001)(575784001)(14454004)(36756003)(2906002)(82746002)(6916009)(83716003)(97736004)(3846002)(102836003)(105586002)(99286004)(3280700002)(3660700001)(101416001)(478600001)(189998001)(68736007)(72206003)(7736002)(305945005)(53936002)(6506006)(33656002)(6436002)(5640700003)(2351001)(6486002)(4001150100001)(50986999)(2501003)(54356999)(66066001)(4326008)(316002)(8936002)(81166006)(81156014)(2900100001)(8676002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM3PR08MB0103; H:AM3PR08MB0101.eurprd08.prod.outlook.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-ID: <8739D4B29C1F4F4C9C6B89A93B1C37B0@eurprd08.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-Network-Message-Id: 993aa1c2-87b2-45a0-031a-08d52cee8309 X-MS-Exchange-CrossTenant-originalarrivaltime: 16 Nov 2017 12:35:25.3944 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM3PR08MB0103 This patch simply adds the cse specific changes for clobber_high. Alan. 2017-11-16 Alan Hayward * cse.c (invalidate_reg): New function extracted from... (invalidate): ...here. (canonicalize_insn): Check for clobber high. (invalidate_from_clobbers): invalidate clobber highs. (invalidate_from_sets_and_clobbers): Likewise. (count_reg_usage): Check for clobber high. (insn_live_p): Likewise. * cselib.c (cselib_expand_value_rtx_1):Likewise. (cselib_invalidate_regno): Check for clobber in setter. (cselib_invalidate_rtx): Pass through setter. (cselib_invalidate_rtx_note_stores): (cselib_process_insn): Check for clobber high. * cselib.h (cselib_invalidate_rtx): Add operand. diff --git a/gcc/cse.c b/gcc/cse.c index e3c0710215df0acca924ce74ffa54582125d0136..f15ae8693fbb243323dd049e21648a49546a4608 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -559,6 +559,7 @@ static struct table_elt *insert_with_costs (rtx, struct table_elt *, unsigned, static struct table_elt *insert (rtx, struct table_elt *, unsigned, machine_mode); static void merge_equiv_classes (struct table_elt *, struct table_elt *); +static void invalidate_reg (rtx, bool); static void invalidate (rtx, machine_mode); static void remove_invalid_refs (unsigned int); static void remove_invalid_subreg_refs (unsigned int, poly_uint64, @@ -1818,7 +1819,85 @@ check_dependence (const_rtx x, rtx exp, machine_mode mode, rtx addr) } return false; } - + +/* Remove from the hash table, or mark as invalid, all expressions whose + values could be altered by storing in register X. + + CLOBBER_HIGH is set if X was part of a CLOBBER_HIGH expression. */ + +static void +invalidate_reg (rtx x, bool clobber_high) +{ + gcc_assert (GET_CODE (x) == REG); + + /* If X is a register, dependencies on its contents are recorded + through the qty number mechanism. Just change the qty number of + the register, mark it as invalid for expressions that refer to it, + and remove it itself. */ + unsigned int regno = REGNO (x); + unsigned int hash = HASH (x, GET_MODE (x)); + + /* Remove REGNO from any quantity list it might be on and indicate + that its value might have changed. If it is a pseudo, remove its + entry from the hash table. + + For a hard register, we do the first two actions above for any + additional hard registers corresponding to X. Then, if any of these + registers are in the table, we must remove any REG entries that + overlap these registers. */ + + delete_reg_equiv (regno); + REG_TICK (regno)++; + SUBREG_TICKED (regno) = -1; + + if (regno >= FIRST_PSEUDO_REGISTER) + { + gcc_assert (!clobber_high); + remove_pseudo_from_table (x, hash); + } + else + { + HOST_WIDE_INT in_table = TEST_HARD_REG_BIT (hard_regs_in_table, regno); + unsigned int endregno = END_REGNO (x); + unsigned int rn; + struct table_elt *p, *next; + + CLEAR_HARD_REG_BIT (hard_regs_in_table, regno); + + for (rn = regno + 1; rn < endregno; rn++) + { + in_table |= TEST_HARD_REG_BIT (hard_regs_in_table, rn); + CLEAR_HARD_REG_BIT (hard_regs_in_table, rn); + delete_reg_equiv (rn); + REG_TICK (rn)++; + SUBREG_TICKED (rn) = -1; + } + + if (in_table) + for (hash = 0; hash < HASH_SIZE; hash++) + for (p = table[hash]; p; p = next) + { + next = p->next_same_hash; + + if (!REG_P (p->exp) || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER) + continue; + + if (clobber_high) + { + if (reg_is_clobbered_by_clobber_high (p->exp, x)) + remove_from_table (p, hash); + } + else + { + unsigned int tregno = REGNO (p->exp); + unsigned int tendregno = END_REGNO (p->exp); + if (tendregno > regno && tregno < endregno) + remove_from_table (p, hash); + } + } + } +} + /* Remove from the hash table, or mark as invalid, all expressions whose values could be altered by storing in X. X is a register, a subreg, or a memory reference with nonvarying address (because, when a memory @@ -1841,65 +1920,7 @@ invalidate (rtx x, machine_mode full_mode) switch (GET_CODE (x)) { case REG: - { - /* If X is a register, dependencies on its contents are recorded - through the qty number mechanism. Just change the qty number of - the register, mark it as invalid for expressions that refer to it, - and remove it itself. */ - unsigned int regno = REGNO (x); - unsigned int hash = HASH (x, GET_MODE (x)); - - /* Remove REGNO from any quantity list it might be on and indicate - that its value might have changed. If it is a pseudo, remove its - entry from the hash table. - - For a hard register, we do the first two actions above for any - additional hard registers corresponding to X. Then, if any of these - registers are in the table, we must remove any REG entries that - overlap these registers. */ - - delete_reg_equiv (regno); - REG_TICK (regno)++; - SUBREG_TICKED (regno) = -1; - - if (regno >= FIRST_PSEUDO_REGISTER) - remove_pseudo_from_table (x, hash); - else - { - HOST_WIDE_INT in_table - = TEST_HARD_REG_BIT (hard_regs_in_table, regno); - unsigned int endregno = END_REGNO (x); - unsigned int tregno, tendregno, rn; - struct table_elt *p, *next; - - CLEAR_HARD_REG_BIT (hard_regs_in_table, regno); - - for (rn = regno + 1; rn < endregno; rn++) - { - in_table |= TEST_HARD_REG_BIT (hard_regs_in_table, rn); - CLEAR_HARD_REG_BIT (hard_regs_in_table, rn); - delete_reg_equiv (rn); - REG_TICK (rn)++; - SUBREG_TICKED (rn) = -1; - } - - if (in_table) - for (hash = 0; hash < HASH_SIZE; hash++) - for (p = table[hash]; p; p = next) - { - next = p->next_same_hash; - - if (!REG_P (p->exp) - || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER) - continue; - - tregno = REGNO (p->exp); - tendregno = END_REGNO (p->exp); - if (tendregno > regno && tregno < endregno) - remove_from_table (p, hash); - } - } - } + invalidate_reg (x, false); return; case SUBREG: @@ -4391,6 +4412,8 @@ canonicalize_insn (rtx_insn *insn, struct set **psets, int n_sets) if (MEM_P (XEXP (x, 0))) canon_reg (XEXP (x, 0), insn); } + else if (GET_CODE (x) == CLOBBER_HIGH) + gcc_assert (REG_P (XEXP (x, 0))); else if (GET_CODE (x) == USE && ! (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)) @@ -4422,6 +4445,8 @@ canonicalize_insn (rtx_insn *insn, struct set **psets, int n_sets) if (MEM_P (XEXP (y, 0))) canon_reg (XEXP (y, 0), insn); } + else if (GET_CODE (y) == CLOBBER_HIGH) + gcc_assert (REG_P (XEXP (y, 0))); else if (GET_CODE (y) == USE && ! (REG_P (XEXP (y, 0)) && REGNO (XEXP (y, 0)) < FIRST_PSEUDO_REGISTER)) @@ -6122,6 +6147,12 @@ invalidate_from_clobbers (rtx_insn *insn) invalidate (XEXP (ref, 0), GET_MODE (ref)); } } + if (GET_CODE (x) == CLOBBER_HIGH) + { + rtx ref = XEXP (x, 0); + gcc_assert (REG_P (ref)); + invalidate_reg (ref, true); + } else if (GET_CODE (x) == PARALLEL) { int i; @@ -6138,6 +6169,12 @@ invalidate_from_clobbers (rtx_insn *insn) || GET_CODE (ref) == ZERO_EXTRACT) invalidate (XEXP (ref, 0), GET_MODE (ref)); } + else if (GET_CODE (y) == CLOBBER_HIGH) + { + rtx ref = XEXP (y, 0); + gcc_assert (REG_P (ref)); + invalidate_reg (ref, true); + } } } } @@ -6155,8 +6192,17 @@ invalidate_from_sets_and_clobbers (rtx_insn *insn) if (CALL_P (insn)) { for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1)) - if (GET_CODE (XEXP (tem, 0)) == CLOBBER) - invalidate (SET_DEST (XEXP (tem, 0)), VOIDmode); + { + rtx temx = XEXP (tem, 0); + if (GET_CODE (temx) == CLOBBER) + invalidate (SET_DEST (temx), VOIDmode); + else if (GET_CODE (temx) == CLOBBER_HIGH) + { + rtx temref = XEXP (temx, 0); + gcc_assert (REG_P (temref)); + invalidate_reg (temref, true); + } + } } /* Ensure we invalidate the destination register of a CALL insn. @@ -6183,6 +6229,12 @@ invalidate_from_sets_and_clobbers (rtx_insn *insn) || GET_CODE (clobbered) == ZERO_EXTRACT) invalidate (XEXP (clobbered, 0), GET_MODE (clobbered)); } + else if (GET_CODE (y) == CLOBBER_HIGH) + { + rtx ref = XEXP (y, 0); + gcc_assert (REG_P (ref)); + invalidate_reg (ref, true); + } else if (GET_CODE (y) == SET && GET_CODE (SET_SRC (y)) == CALL) invalidate (SET_DEST (y), VOIDmode); } @@ -6842,6 +6894,10 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr) count_reg_usage (XEXP (XEXP (x, 0), 0), counts, NULL_RTX, incr); return; + case CLOBBER_HIGH: + gcc_assert (REG_P ((XEXP (x, 0)))); + return; + case SET: /* Unless we are setting a REG, count everything in SET_DEST. */ if (!REG_P (SET_DEST (x))) @@ -6894,7 +6950,8 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr) || (REG_NOTE_KIND (x) != REG_NONNEG && GET_CODE (XEXP (x,0)) == USE) /* FUNCTION_USAGE expression lists may include (CLOBBER (mem /u)), involving registers in the address. */ - || GET_CODE (XEXP (x, 0)) == CLOBBER) + || GET_CODE (XEXP (x, 0)) == CLOBBER + || GET_CODE (XEXP (x, 0)) == CLOBBER_HIGH) count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr); count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr); @@ -6978,7 +7035,9 @@ insn_live_p (rtx_insn *insn, int *counts) if (set_live_p (elt, insn, counts)) return true; } - else if (GET_CODE (elt) != CLOBBER && GET_CODE (elt) != USE) + else if (GET_CODE (elt) != CLOBBER + && GET_CODE (elt) != CLOBBER_HIGH + && GET_CODE (elt) != USE) return true; } return false; diff --git a/gcc/cselib.h b/gcc/cselib.h index dd949196b7d4a46f2b157ae3874241ee116d022d..ad4cce4ebbda1556124259be4d84edf410fb14cd 100644 --- a/gcc/cselib.h +++ b/gcc/cselib.h @@ -92,7 +92,7 @@ extern bool cselib_dummy_expand_value_rtx_cb (rtx, bitmap, int, cselib_expand_callback, void *); extern rtx cselib_subst_to_values (rtx, machine_mode); extern rtx cselib_subst_to_values_from_insn (rtx, machine_mode, rtx_insn *); -extern void cselib_invalidate_rtx (rtx); +extern void cselib_invalidate_rtx (rtx, const_rtx = NULL); extern void cselib_reset_table (unsigned int); extern unsigned int cselib_get_next_uid (void); diff --git a/gcc/cselib.c b/gcc/cselib.c index 9c8f206c909925c58f0ab1a14853caf738bbfc4f..92f91a463f2519b09545d0b050de5521427d4929 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -54,7 +54,8 @@ static unsigned int cselib_hash_rtx (rtx, int, machine_mode); static cselib_val *new_cselib_val (unsigned int, machine_mode, rtx); static void add_mem_for_addr (cselib_val *, cselib_val *, rtx); static cselib_val *cselib_lookup_mem (rtx, int); -static void cselib_invalidate_regno (unsigned int, machine_mode); +static void cselib_invalidate_regno (unsigned int, machine_mode, + const_rtx = NULL); static void cselib_invalidate_mem (rtx); static void cselib_record_set (rtx, cselib_val *, cselib_val *); static void cselib_record_sets (rtx_insn *); @@ -1661,6 +1662,7 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd, /* SCRATCH must be shared because they represent distinct values. */ return orig; case CLOBBER: + case CLOBBER_HIGH: if (REG_P (XEXP (orig, 0)) && HARD_REGISTER_NUM_P (REGNO (XEXP (orig, 0)))) return orig; break; @@ -2163,7 +2165,8 @@ cselib_lookup (rtx x, machine_mode mode, invalidating call clobbered registers across a call. */ static void -cselib_invalidate_regno (unsigned int regno, machine_mode mode) +cselib_invalidate_regno (unsigned int regno, machine_mode mode, + const_rtx setter) { unsigned int endregno; unsigned int i; @@ -2186,6 +2189,9 @@ cselib_invalidate_regno (unsigned int regno, machine_mode mode) i = regno - max_value_regs; endregno = end_hard_regno (mode, regno); + + if (setter && GET_CODE (setter) == CLOBBER_HIGH) + gcc_assert (endregno == regno + 1); } else { @@ -2218,6 +2224,19 @@ cselib_invalidate_regno (unsigned int regno, machine_mode mode) continue; } + /* Ignore if clobber high and the register isn't clobbered. */ + if (setter && GET_CODE (setter) == CLOBBER_HIGH) + { + gcc_assert (endregno == regno + 1); + const_rtx x = XEXP (setter, 0); + if (!reg_is_clobbered_by_clobber_high (i, GET_MODE (v->val_rtx), + x)) + { + l = &(*l)->next; + continue; + } + } + /* We have an overlap. */ if (*l == REG_VALUES (i)) { @@ -2352,10 +2371,10 @@ cselib_invalidate_mem (rtx mem_rtx) *vp = &dummy_val; } -/* Invalidate DEST, which is being assigned to or clobbered. */ +/* Invalidate DEST, which is being assigned to or clobbered by SETTER. */ void -cselib_invalidate_rtx (rtx dest) +cselib_invalidate_rtx (rtx dest, const_rtx setter) { while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == ZERO_EXTRACT @@ -2363,7 +2382,7 @@ cselib_invalidate_rtx (rtx dest) dest = XEXP (dest, 0); if (REG_P (dest)) - cselib_invalidate_regno (REGNO (dest), GET_MODE (dest)); + cselib_invalidate_regno (REGNO (dest), GET_MODE (dest), setter); else if (MEM_P (dest)) cselib_invalidate_mem (dest); } @@ -2371,10 +2390,10 @@ cselib_invalidate_rtx (rtx dest) /* A wrapper for cselib_invalidate_rtx to be called via note_stores. */ static void -cselib_invalidate_rtx_note_stores (rtx dest, const_rtx ignore ATTRIBUTE_UNUSED, +cselib_invalidate_rtx_note_stores (rtx dest, const_rtx setter, void *data ATTRIBUTE_UNUSED) { - cselib_invalidate_rtx (dest); + cselib_invalidate_rtx (dest, setter); } /* Record the result of a SET instruction. DEST is being set; the source @@ -2710,9 +2729,12 @@ cselib_process_insn (rtx_insn *insn) if (CALL_P (insn)) { for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1)) - if (GET_CODE (XEXP (x, 0)) == CLOBBER) - cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0)); - /* Flush evertything on setjmp. */ + { + gcc_assert (GET_CODE (XEXP (x, 0)) != CLOBBER_HIGH); + if (GET_CODE (XEXP (x, 0)) == CLOBBER) + cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0)); + } + /* Flush everything on setjmp. */ if (cselib_preserve_constants && find_reg_note (insn, REG_SETJMP, NULL)) {