From patchwork Tue May 17 09:22:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Greenhalgh X-Patchwork-Id: 67934 Delivered-To: patch@linaro.org Received: by 10.140.92.199 with SMTP id b65csp1966609qge; Tue, 17 May 2016 02:23:58 -0700 (PDT) X-Received: by 10.98.101.199 with SMTP id z190mr325195pfb.1.1463477038000; Tue, 17 May 2016 02:23:58 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id i189si3361811pfc.206.2016.05.17.02.23.57 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 17 May 2016 02:23:57 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-427444-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-427444-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-427444-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:from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; q=dns; s=default; b=NsKBkNeUx04KLVZu zxEVvGlhWHcubOdxh+eNkA8wv67zGGYNRjTeNXmRnguraWlfypd1lhhMchQQglMT xReknf/uKjf7X80M+izEBAF9pDZq/3K3W7hgstNYHZEjDE1pKdoqgX25jg6sVScM uGHebxZU1Zkumxvb1VxizkZTz/4= 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:in-reply-to:references :mime-version:content-type; s=default; bh=QR0z9yu9GFBzCi9r3ZOdAw Q/Ups=; b=Na+RmJD6WP/f46dlxe6x4NG0CSFwwYyrOiKi9bumItfKnCf9UkaW3g ZE77NgLHXoeat+CDEtp0iKQwK8DPeuHHYJm6SS2r+rnVnT0bXae8pYLNK8e9W+dX D7doXNuv/b9b+ESIeioB1OF0mpOEzuYjg3ustMQ8ejO0mxIJpEHho= Received: (qmail 62183 invoked by alias); 17 May 2016 09:23:17 -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 61181 invoked by uid 89); 17 May 2016 09:23:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL, BAYES_00, SPF_PASS autolearn=ham version=3.3.2 spammy=pulled, BASE, opportunity, HX-Exchange-Antispam-Report-CFA-Test:102415293 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (146.101.78.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 17 May 2016 09:23:07 +0000 Received: from emea01-db3-obe.outbound.protection.outlook.com (mail-db3lrp0080.outbound.protection.outlook.com [213.199.154.80]) (Using TLS) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-45-9sfkIpV8RcyngXxIOSbo-g-1; Tue, 17 May 2016 10:22:59 +0100 Received: from DB5PR08CA0022.eurprd08.prod.outlook.com (10.163.102.160) by DB3PR08MB0234.eurprd08.prod.outlook.com (10.161.61.14) with Microsoft SMTP Server (TLS) id 15.1.492.11; Tue, 17 May 2016 09:22:59 +0000 Received: from AM1FFO11FD031.protection.gbl (2a01:111:f400:7e00::108) by DB5PR08CA0022.outlook.office365.com (2a01:111:e400:52c3::32) with Microsoft SMTP Server (TLS) id 15.1.497.12 via Frontend Transport; Tue, 17 May 2016 09:22:58 +0000 Received: from nebula.arm.com (217.140.96.140) by AM1FFO11FD031.mail.protection.outlook.com (10.174.64.220) with Microsoft SMTP Server (TLS) id 15.1.497.8 via Frontend Transport; Tue, 17 May 2016 09:22:58 +0000 Received: from e107456-lin.cambridge.arm.com (10.1.2.79) by mail.arm.com (10.1.105.66) with Microsoft SMTP Server id 14.3.279.2; Tue, 17 May 2016 10:22:40 +0100 From: James Greenhalgh To: CC: , , , Subject: [AArch64 1/2] Refactor aarch64_operands_ok_for_ldpstp, aarch64_operands_adjust_ok_for_ldpstp Date: Tue, 17 May 2016 10:22:30 +0100 Message-ID: <1463476951-1567-2-git-send-email-james.greenhalgh@arm.com> In-Reply-To: <1463476951-1567-1-git-send-email-james.greenhalgh@arm.com> References: <1463476951-1567-1-git-send-email-james.greenhalgh@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:217.140.96.140; IPV:CAL; SCL:-1; CTRY:GB; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(2980300002)(438002)(199003)(189002)(377424004)(4610100001)(50226002)(86362001)(189998001)(5000100001)(5890100001)(19580405001)(84326002)(5008740100001)(104016004)(19580395003)(8676002)(6806005)(568964002)(11100500001)(450100001)(4326007)(586003)(33646002)(2950100001)(50986999)(76176999)(92566002)(36756003)(87936001)(77096005)(1220700001)(2906002)(2476003)(8936002)(2351001)(5003600100002)(229853001)(106466001)(110136002)(512874002)(15760500001); DIR:OUT; SFP:1101; SCL:1; SRVR:DB3PR08MB0234; H:nebula.arm.com; FPR:; SPF:Pass; MLV:sfv; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; AM1FFO11FD031; 1:Mnxqg1qLp3LC9sWjEmx5ovTi4fKTYakL/TS/S9cdCwK464xcE9qXBLQQk2lZFmbXg6tBVj0F+NfXgGexlo997ApgKitBc3LztLbS8Sk0yB4DVSxGhkFtvEaxdZyd1mrAO0D4LEjlqG2OILY33+dSY2QpygTUBShecTVSsq6TvJuIED8MWSnBjVJx0dsHtJSgXkSJ7EHO3PgMhsd1sZBd81TwPvGgMZ9AODXpN2IQAxpHtxblY0tMcOFawQEiCoIEsisFmNV9c+dlAoYmTF2q7mGDYxcAAAixiHq/FX2SKJ/0XiJfOqcjbdUkQz97nlgRf4xSDfgqUpbQXIzbnGaphNmm65QY1Oo6hncbDIaTWQcEdwxY8Wo9DlIvlJVLOXwXPj65yCAH1QZhC/qexIUMFVizTBdppeoJsayYXKDQ1NRXI4OXR1XHPs4C9kFedSGfoRRWIUVm8ILUYMHqJ9Y1IMJl7Dmw0L8AledFxs4kL0oJ3qI/1gTSuqYNdP2eTW17 X-MS-Office365-Filtering-Correlation-Id: 0f193579-7bb3-4229-5e44-08d37e34d62f X-Microsoft-Exchange-Diagnostics: 1; DB3PR08MB0234; 2:lZtzhbaiojzKDccDff+bsXkqTUHTWo0chKKlwaS8WBgdU3YeYEWcWrU4K5GN4Mo5UsXh2fWV/+4IlwVfXjIrm0Rv1kgITriZ7YEkvS/Op6YU2zIsYkXzz2goVe6MrF6nRNS2Z/xWpEBbuIj7/F5DlB0fPrZ7TwMXnvPLHsccpDeGhCiRO2RyH1cLtpgaUYO9; 3:9icUMb5HdEzBwDldlvPaRSyf8El+TU/qYqbeh0/bio3Dr2g/cF+qgDiv5CRBd6m/2HzHVDYZ4GdjTLvtuqJofCPgvqFXaEeJVkmtQO8za8JgSrrj6lnnXuvQvZgWtaB/UtJn0rWYpW4Zmo/V8GJMG9+762r0aJm9aKm2syxmucr0JxN9CjXi+pxplDw4aAWs0lLvSl2O6OwZ8arHlCBXx5qACkezkIV7PK/npQr2BB2KUIWx2AOjD5Ux1m24eThRAxI23kfU6J5hnkupR7ZjHQ== X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(8251501002); SRVR:DB3PR08MB0234; X-Microsoft-Exchange-Diagnostics: 1; DB3PR08MB0234; 25:OzaTd3jiWq+BtgQcFMWuuXA5TBSj8VC3wZ0hwRddGgi/GvK0zImjVV1JUzY6zQGXoOnwSctHdOBcw1WCfNUwYH9PByt8pmLEqdBqJlaNiCS9wOJeji0UG/z2bGomcjDpfXZ1clQXA3EoO0fPiHhkBLz2zWWSWVe8fPGdUCTfUL3/d8nzbfVwBUyeoVcu+jRdGw0G2R7LTHu6Wf91DkY7aq75ZDREQ2BIn+fVse9JM6WWfboi2Oe6Z2ZJxIkrlAUKWKCt4RlF78UhlK4ntBH1Z4UV+UHKd/2Z4xfL/2vDB0Zc/AHcipaeVhSlLfgnHr4RtJY/Rzw5KljJ8YRCWqM9ks/J6S3R2sP4sEll4YGcwIi8CrwBBDKsJTLfMLpn78HH+IkzpKSfdEPKsSXJjLRvMizMK55lfac9ie4QDJuGqS41noM23vDEjliaVzA+u7WR0AfIfO4o1CmbDEhyfY9xmfwL3xNU0v+b0DpbHnPhtOxoOJIYlaDxDwi7aheYaFoe/B6J8O1OwLpVeFzLSRh4+iDm2bTkdwyYTrYVpmdtlXwLKth0zx1gSHeNh1vD3cpbp4bkRZqad+UE2O5WfH3y39PXKcrUnQQagY/ULfnhm+1hXM8P3lQE+m2gAGmPLtxyXAbrGMqkqrg4J0u0zXNu3DHsbTQnv9vpDqlYf2Mf5PIxtNswd8Un+0tS8B5NAkgBreINaMpvR/Sq8PaJBIuPDjpOMvojkRhJwB23DfCMM01Y9KXfPlDftljHzhnbbkrA3Scxu3YJI1k2krNZXtDr9punJ+vfP2CPOjsgib0APQaI6HP4NulxafT8uGljjf5OvOlMssKEh5aw3borvX61+CI/LdyUXxXFOaQgyyNkt1PHdLzh9s/o1sbirYQM8PgHZUEeLFmLZs2sfkVwLq5Ff9gY8sNphpX5gFfX/eW+VHk= NoDisclaimer: True X-Microsoft-Exchange-Diagnostics: 1; DB3PR08MB0234; 20:8Mtrx9i9a89tO8sv6puAbGhdXwwePvuQXMQykKeSCrYgsvRU1ygs3VqwGcR0z8MTwr0Id56RCDc9qtml5AzAgbCy1HBjsOfSfd5UPHuvN7VsfCmNUfpNU8EkrPWivTEooazir5S7vB5jGZh9WMU/XYrn5a/VonXnLBx87F+16QFOyMxZBfvRmyPiDLWMiDzklsd95pPrsK2uT9yHMSPQg62MsnMHtwN2shdHoXTtOGIIPYMMVV2vflEwQ0azEDF/; 4:MvlLXa1Jrv1I4ln9Kbd90j9b+P8nfwHS1bRhX0vHO5PAGrFOP7NVNQIv/tj0ECVeqT8NZN+nE4u1/nz6N530+Wq2GuB5/LSS48mPsBUJBOCHWx1cNrRGcBbaugeRnrrHzV+3i7dl6JOZYYU7AoCl80jMAlJIpn0panv1A/TAzBrPeEzLEAIwaNfXX7O2iRyUTzQ/2Ct9AqS3nxxGZHEo8j6SiwHv3xkgoUnTYMEGxXsUSB9iW5xGk5TN+qF18oB1l7wRzYVVsIc5SDGtqwbOFCCcS8c8hFTj9SzI9iHs5Jcan8XbbipA6o/C+81lzHwoFlPNmeNrbymWPgln4ouR01SqordiF66GoBYYiI+qsrclWWjy/CG3aGSvynzf1g4rmQiLZRTnFRKWCTvwSxFHjnwmyDQaCeTgobWqHTjgpl1bp91viUCYoyv3ptbmvGITuxbNAIJB+qTBOFuvKcxNjss7Z9dwRNyGul/qSCrKvgw0iRUDVkzF274Kxp2JfEWL X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(102415293)(102615271)(601004)(2401047)(13013025)(13020025)(13024025)(13023025)(8121501046)(5005006)(10201501046)(3002001)(6055026); SRVR:DB3PR08MB0234; BCL:0; PCL:0; RULEID:; SRVR:DB3PR08MB0234; X-Forefront-PRVS: 0945B0CC72 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DB3PR08MB0234; 23:RRTX+rW2N9bB/vUpys7t4IvPsPhpaYj4fpDKUlWx5?= =?us-ascii?Q?0SJkp8UfKxKppWuuq2MUKjJ4SaHLwK5h7Wa83QWuCw6DZO/ceAXFtadPQYiq?= =?us-ascii?Q?wbj8zPcRrway9o6YwVEbzWsFG4KDaxxkj1H0mH5CpgSMF3C7SLyVcAUvZoUg?= =?us-ascii?Q?Bc3zRQ4vxt1wOv4wm2J7VsXdjJZ0ZZVAAGSSd3fA1mcyFtZMl1cCy5Yix+NR?= =?us-ascii?Q?JDFpzyPgZefhY9vMwmit6LzEs6jC+blGxMvlL/6KhR8I/jjSlT0j9fYlOtE3?= =?us-ascii?Q?Iac2o+eGjbxS/w1iq0cGGrFQiVwX2xMVK0lTrg3ZwBtAOZxT7Ucr25kOdTnE?= =?us-ascii?Q?dZUoXWChgfIoUbNPxMQ028kGgXPD6wVbQjtK7mm4F6OOgpKzTnBTkcvaq6ZE?= =?us-ascii?Q?nkBBvmfhWTV3lxqP072DvCbhpAiWRzsTj27wqZJOwwVxVKAQceUvdhVcj7Kf?= =?us-ascii?Q?sgPmfS/jB7w+DgDHM1zmK6iKfr7Nb2hXEKasKE5xs8OvYg0reJmIIojM1kQH?= =?us-ascii?Q?k4e09lNc/WMjXo+s0A+xYeXgfDAfFgwwAdY2BbpD3wVAVEtZjbOw9SvkN0O+?= =?us-ascii?Q?UbtXoMxLNY9ZMV2D+hgsb2qdHmoRUBpxGJADqoSWs4m4esI4cdMelAwn7+vg?= =?us-ascii?Q?ZqitEbrD60YDkYKYI4iiI+/N0ou0lSBYH6r8BKSH4LylUeRIm6l9Rzxa2IE0?= =?us-ascii?Q?nCy7JwU9GZF39eynVfn4NjyB2PcgfazkiQOkRQg6Z7jyk7yspCM3Swiu7rKR?= =?us-ascii?Q?S3L9w6J8Eh+B1TU+FfrRYlDs4gvyC+ZAypAeHqw+TwN/8vA0ZQcF7XfhB3rW?= =?us-ascii?Q?w7lnCw5BVvaEMmmTaTzt8Nq52kk8/pUXPAUJYNjVML/Vw+iB0o+Qxua3Lcyz?= =?us-ascii?Q?EjkqgNlnFumpkTEg0PfiV+Xq3RZYqWa2cvBcO6W/iznT91JfWiGrCuAn9hY2?= =?us-ascii?Q?gd7ce0mhZ8a+lilKkpXMRGiR4uGTC7yTfhPk/iKCJbzZqkXmrFd43xSqPRH9?= =?us-ascii?Q?VsOrdyV6HKf//at4+UcH0p1UmIq8/XYsNj8eyHACNPyMrA97N/A7VjqJb3Gx?= =?us-ascii?Q?PFv6cviqu1H1ugXJl3ZrzO70py1w4WuyUmiVqJpJkHuCkoJBQZ18avQtFgW8?= =?us-ascii?Q?W/jC8ylhEcMZME804fl7xg26C+5LglF?= X-Microsoft-Exchange-Diagnostics: 1; DB3PR08MB0234; 5:P+XW1EJFccsx55Fc+u15e/WBhbHFlDMkwOAdtEHKWd78FCktZz+duzGGlg1lJ33APLS4vPZGSL/bNvG9xJcOlcGG48LCEMXZLpwqfc8MEYcy76sUc4X0WS9bkqobtLCy4veGaDRCQac/XkfzzNBxWA==; 24:I/KpL8qlfEeSjPfradUsFuiJpTT2m2bn1D7bIePS6KAq0xwn1RpRh5yBm64HN+3wEyjLoC477kV2zI4vYbJKESvr3MNS2Y1JXaUMV5p54q4=; 7:HrxIpNkRE1gnmD2vl+5aW8AVBKSKHspvhcVzn0eRkFX1yrZRyqTGLkDK1vVpOHTj3+jToxlH6Ylv1Fyrt0adAloH1H/e6W85k/anhlCkf5rWU9BIokxNOBh6e2Bc75P8WmgJg8ZSdJM1V8W42VH/+v3F7/emdPbMur2UuaRaFBn7ir/qsQ80tHp7Ca9AQOfl; 20:lRNx+O2zsiDHAjC/OqgkptNJGv9iSAlAkzRHtGxtJ3a5IwNTgyLa7WAtXXV/fm4ssxQDx24dgspctvp40q3oWCMWviQiZHPs5Q51O729lidp1dr0kNh9UuTRqfrq8jEIduje1dUq5c2+NxA1OpEONHyoA89lc1pwGOCQbRDRKoI= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 May 2016 09:22:58.3859 (UTC) X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[217.140.96.140]; Helo=[nebula.arm.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB3PR08MB0234 X-MC-Unique: 9sfkIpV8RcyngXxIOSbo-g-1 X-IsSubscribed: yes Hi, These two functions are very similar and suffer from code duplication. With a little bit of work we can reduce the strain on the reader by refactoring the functions. Essentially, we're going to remove the explicit references to reg_1, reg_2, reg_3, reg_4 and keep these things in arrays instead, at which point it becomes clear that these functions are very similar and can be pulled together. OK? Bootstrapped and tested for aarch64-none-linux-gnu with no issues. OK? Thanks, James --- 2016-05-17 James Greenhalgh * config/aarch64/aarch64.c (aarch64_extract_ldpstp_operands): New. (aarch64_ldpstp_ops_same_reg_class_p): Likewise. (aarch64_ldpstp_load_regs_clobber_base_p): Likewise. (aarch64_ldpstp_offsets_consecutive_p): Likewise. (aarch64_operands_ok_for_ldpstp_1): Likewise. (aarch64_operands_ok_for_ldpstp): Refactor to aarch64_operands_ok_for_ldpstp_1. (aarch64_operands_adjust_ok_for_ldpstp): Likewise. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 986262b..434c154 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -13346,85 +13346,167 @@ aarch64_sched_fusion_priority (rtx_insn *insn, int max_pri, return; } -/* Given OPERANDS of consecutive load/store, check if we can merge - them into ldp/stp. LOAD is true if they are load instructions. - MODE is the mode of memory operands. */ +/* Extract in to REG and MEM operands to an LDP/STP operation from + OPERANDS. The count of operands to extract is OPS, and whether + we are looking at a load or a store is given by LOAD. */ -bool -aarch64_operands_ok_for_ldpstp (rtx *operands, bool load, - enum machine_mode mode) +static void +aarch64_extract_ldpstp_operands (unsigned int ops, bool load, + rtx *operands, rtx *reg, rtx *mem) { - HOST_WIDE_INT offval_1, offval_2, msize; - enum reg_class rclass_1, rclass_2; - rtx mem_1, mem_2, reg_1, reg_2, base_1, base_2, offset_1, offset_2; + for (unsigned int i = 0; i < ops; i++) + { + unsigned int twoi = i * 2; + reg[i] = operands[load ? twoi : (twoi + 1)]; + mem[i] = operands[load ? (twoi + 1) : twoi]; + /* Sanity check. */ + gcc_assert (MEM_P (mem[i])); - if (load) + if (load) + gcc_assert (REG_P (reg[i])); + } +} + +/* Return TRUE if each RTX in REG (which has size COUNT) is of the + same register class. For the purpose of this function anything which + would not fit REG_P (i.e. a const_int 0 or a const_double 0.0) is + consider to be in GENERAL_REGS. */ + +static bool +aarch64_ldpstp_ops_same_reg_class_p (unsigned int count, rtx *reg) +{ + /* Check if the registers are of same class. */ + reg_class rclass = (REG_P (reg[0]) && FP_REGNUM_P (REGNO (reg[0]))) + ? FP_REGS + : GENERAL_REGS; + + for (unsigned int i = 1; i < count; i++) { - mem_1 = operands[1]; - mem_2 = operands[3]; - reg_1 = operands[0]; - reg_2 = operands[2]; - gcc_assert (REG_P (reg_1) && REG_P (reg_2)); - if (REGNO (reg_1) == REGNO (reg_2)) + reg_class rc = (REG_P (reg[i]) && FP_REGNUM_P (REGNO (reg[i]))) + ? FP_REGS + : GENERAL_REGS; + if (rclass != rc) return false; } - else + + return true; +} + +/* REG contains the set of registers, sized by COUNT, which are written by + a sequence of (base + offset) loads which are based from BASE and have + offsets OFFSETS. Return TRUE if any of the registers in REG clobber + BASE. */ + +static bool +aarch64_ldpstp_load_regs_clobber_base_p (unsigned int count, + rtx *reg, rtx base, + HOST_WIDE_INT *offsets) +{ + for (unsigned int i = 0; i < count - 1; i++) + if (reg_mentioned_p (reg[i], base)) + return true; + + /* In increasing order, the last load can clobber the address. */ + return (offsets[0] > offsets[1] + && reg_mentioned_p (reg[count - 1], base)); +} + +/* Return true if OFFSETS, which has size COUNT, is an ascending or + descending sequence, separated by MSIZE. */ + +static bool +aarch64_ldpstp_offsets_consecutive_p (unsigned int count, + HOST_WIDE_INT *offsets, + HOST_WIDE_INT msize) +{ + bool ascending = true, descending = true; + for (unsigned int i = 0; i < count; i++) { - mem_1 = operands[0]; - mem_2 = operands[2]; - reg_1 = operands[1]; - reg_2 = operands[3]; + ascending &= (offsets[0] == offsets[i] - (msize * i)); + descending &= (offsets[0] == offsets[i] + msize * i); } - /* The mems cannot be volatile. */ - if (MEM_VOLATILE_P (mem_1) || MEM_VOLATILE_P (mem_2)) - return false; + return ascending || descending; +} - /* Check if the addresses are in the form of [base+offset]. */ - extract_base_offset_in_addr (mem_1, &base_1, &offset_1); - if (base_1 == NULL_RTX || offset_1 == NULL_RTX) - return false; - extract_base_offset_in_addr (mem_2, &base_2, &offset_2); - if (base_2 == NULL_RTX || offset_2 == NULL_RTX) - return false; - /* Check if the bases are same. */ - if (!rtx_equal_p (base_1, base_2)) - return false; +/* Helper function for aarch64_operands_ok_for_ldpstp and + aarch64_operands_adjust_ok_for_ldpstp. OPERANDS are the + consecutive load/store operands which we hope to merge. LOAD + is true if these are LOAD instructions. MODE is the mode of the + memory operations. ADJUST is true if we are in the 4-operand + adjust case. */ - offval_1 = INTVAL (offset_1); - offval_2 = INTVAL (offset_2); - msize = GET_MODE_SIZE (mode); - /* Check if the offsets are consecutive. */ - if (offval_1 != (offval_2 + msize) && offval_2 != (offval_1 + msize)) - return false; +bool +aarch64_operands_ok_for_ldpstp_1 (rtx *operands, bool load, + enum machine_mode mode, bool adjust) +{ + const unsigned int count = adjust ? 4 : 2; + /* Avoid alloca calls and just size as large as they need to be + for the largest case we can handle. */ + const unsigned int max_ops = 4; + rtx mem[max_ops], reg[max_ops], base[max_ops], offset[max_ops]; + HOST_WIDE_INT offval[max_ops]; + unsigned int i = 0; + HOST_WIDE_INT msize = GET_MODE_SIZE (mode); + + aarch64_extract_ldpstp_operands (count, load, operands, reg, mem); - /* Check if the addresses are clobbered by load. */ if (load) { - if (reg_mentioned_p (reg_1, mem_1)) - return false; + for (i = 0; i < count; i += 2) + if (REGNO (reg[i]) == REGNO (reg[i + 1])) + return false; + } + + /* For the adjust case, skip if memory operand is by itself valid + for ldp/stp. */ + if (adjust + && (!MEM_P (mem[0]) || aarch64_mem_pair_operand (mem[0], mode))) + return false; - /* In increasing order, the last load can clobber the address. */ - if (offval_1 > offval_2 && reg_mentioned_p (reg_2, mem_2)) + /* The mems cannot be volatile. */ + for (i = 0; i < count; i++) + if (MEM_VOLATILE_P (mem[i])) return false; + + /* Check if the addresses are in the form of [base+offset]. */ + for (i = 0; i < count; i++) + { + extract_base_offset_in_addr (mem[i], &base[i], &offset[i]); + if (base[i] == NULL_RTX || offset[i] == NULL_RTX) + return false; } - if (REG_P (reg_1) && FP_REGNUM_P (REGNO (reg_1))) - rclass_1 = FP_REGS; - else - rclass_1 = GENERAL_REGS; + /* Check if the bases are same. */ + for (i = 1; i < count; i++) + if (!rtx_equal_p (base[0], base[i])) + return false; - if (REG_P (reg_2) && FP_REGNUM_P (REGNO (reg_2))) - rclass_2 = FP_REGS; - else - rclass_2 = GENERAL_REGS; + for (unsigned int i = 0; i < count; i++) + offval[i] = INTVAL (offset[i]); - /* Check if the registers are of same class. */ - if (rclass_1 != rclass_2) + if (!aarch64_ldpstp_offsets_consecutive_p (count, offval, msize)) return false; - return true; + /* Check if the addresses are clobbered by load. */ + if (load && aarch64_ldpstp_load_regs_clobber_base_p (count, reg, + base[0], offval)) + return false; + + return aarch64_ldpstp_ops_same_reg_class_p (count, reg); +} + + +/* Given OPERANDS of consecutive load/store, check if we can merge + them into ldp/stp. LOAD is true if they are load instructions. + MODE is the mode of memory operands. */ + +bool +aarch64_operands_ok_for_ldpstp (rtx *operands, bool load, + enum machine_mode mode) +{ + return aarch64_operands_ok_for_ldpstp_1 (operands, load, mode, false); } /* Given OPERANDS of consecutive load/store, check if we can merge @@ -13446,124 +13528,13 @@ aarch64_operands_ok_for_ldpstp (rtx *operands, bool load, stp w1, w1, [scratch, 0x8] The peephole patterns detecting this opportunity should guarantee - the scratch register is avaliable. */ + the scratch register is available. */ bool aarch64_operands_adjust_ok_for_ldpstp (rtx *operands, bool load, enum machine_mode mode) { - enum reg_class rclass_1, rclass_2, rclass_3, rclass_4; - HOST_WIDE_INT offval_1, offval_2, offval_3, offval_4, msize; - rtx mem_1, mem_2, mem_3, mem_4, reg_1, reg_2, reg_3, reg_4; - rtx base_1, base_2, base_3, base_4, offset_1, offset_2, offset_3, offset_4; - - if (load) - { - reg_1 = operands[0]; - mem_1 = operands[1]; - reg_2 = operands[2]; - mem_2 = operands[3]; - reg_3 = operands[4]; - mem_3 = operands[5]; - reg_4 = operands[6]; - mem_4 = operands[7]; - gcc_assert (REG_P (reg_1) && REG_P (reg_2) - && REG_P (reg_3) && REG_P (reg_4)); - if (REGNO (reg_1) == REGNO (reg_2) || REGNO (reg_3) == REGNO (reg_4)) - return false; - } - else - { - mem_1 = operands[0]; - reg_1 = operands[1]; - mem_2 = operands[2]; - reg_2 = operands[3]; - mem_3 = operands[4]; - reg_3 = operands[5]; - mem_4 = operands[6]; - reg_4 = operands[7]; - } - /* Skip if memory operand is by itslef valid for ldp/stp. */ - if (!MEM_P (mem_1) || aarch64_mem_pair_operand (mem_1, mode)) - return false; - - /* The mems cannot be volatile. */ - if (MEM_VOLATILE_P (mem_1) || MEM_VOLATILE_P (mem_2) - || MEM_VOLATILE_P (mem_3) ||MEM_VOLATILE_P (mem_4)) - return false; - - /* Check if the addresses are in the form of [base+offset]. */ - extract_base_offset_in_addr (mem_1, &base_1, &offset_1); - if (base_1 == NULL_RTX || offset_1 == NULL_RTX) - return false; - extract_base_offset_in_addr (mem_2, &base_2, &offset_2); - if (base_2 == NULL_RTX || offset_2 == NULL_RTX) - return false; - extract_base_offset_in_addr (mem_3, &base_3, &offset_3); - if (base_3 == NULL_RTX || offset_3 == NULL_RTX) - return false; - extract_base_offset_in_addr (mem_4, &base_4, &offset_4); - if (base_4 == NULL_RTX || offset_4 == NULL_RTX) - return false; - - /* Check if the bases are same. */ - if (!rtx_equal_p (base_1, base_2) - || !rtx_equal_p (base_2, base_3) - || !rtx_equal_p (base_3, base_4)) - return false; - - offval_1 = INTVAL (offset_1); - offval_2 = INTVAL (offset_2); - offval_3 = INTVAL (offset_3); - offval_4 = INTVAL (offset_4); - msize = GET_MODE_SIZE (mode); - /* Check if the offsets are consecutive. */ - if ((offval_1 != (offval_2 + msize) - || offval_1 != (offval_3 + msize * 2) - || offval_1 != (offval_4 + msize * 3)) - && (offval_4 != (offval_3 + msize) - || offval_4 != (offval_2 + msize * 2) - || offval_4 != (offval_1 + msize * 3))) - return false; - - /* Check if the addresses are clobbered by load. */ - if (load) - { - if (reg_mentioned_p (reg_1, mem_1) - || reg_mentioned_p (reg_2, mem_2) - || reg_mentioned_p (reg_3, mem_3)) - return false; - - /* In increasing order, the last load can clobber the address. */ - if (offval_1 > offval_2 && reg_mentioned_p (reg_4, mem_4)) - return false; - } - - if (REG_P (reg_1) && FP_REGNUM_P (REGNO (reg_1))) - rclass_1 = FP_REGS; - else - rclass_1 = GENERAL_REGS; - - if (REG_P (reg_2) && FP_REGNUM_P (REGNO (reg_2))) - rclass_2 = FP_REGS; - else - rclass_2 = GENERAL_REGS; - - if (REG_P (reg_3) && FP_REGNUM_P (REGNO (reg_3))) - rclass_3 = FP_REGS; - else - rclass_3 = GENERAL_REGS; - - if (REG_P (reg_4) && FP_REGNUM_P (REGNO (reg_4))) - rclass_4 = FP_REGS; - else - rclass_4 = GENERAL_REGS; - - /* Check if the registers are of same class. */ - if (rclass_1 != rclass_2 || rclass_2 != rclass_3 || rclass_3 != rclass_4) - return false; - - return true; + return aarch64_operands_ok_for_ldpstp_1 (operands, load, mode, true); } /* Given OPERANDS of consecutive load/store, this function pairs them