From patchwork Wed Jul 20 09:51:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Greenhalgh X-Patchwork-Id: 72413 Delivered-To: patch@linaro.org Received: by 10.140.29.52 with SMTP id a49csp554118qga; Wed, 20 Jul 2016 02:53:43 -0700 (PDT) X-Received: by 10.66.177.7 with SMTP id cm7mr73995884pac.132.1469008423512; Wed, 20 Jul 2016 02:53:43 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id h21si2589176pfk.107.2016.07.20.02.53.43 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 20 Jul 2016 02:53:43 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-432038-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-432038-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-432038-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=lwQiT8z1UQE16PcM bpnvn4fGMjxnOOtoP2lgnsHMqz+5ok4abLYiaToC5sWkmkF40lsoiZqpPQZ4OIqd ZnU2relEy9CCsw7EoQxsmRij4LWWe7bjiMZNLvHIni9piD0kMo7NsHdWS6c1dtjf R/0//JAeROOxnyTWN2+dsD3HixI= 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=ddfRQIAXR0XUk0MLOqkEBT MH+Jk=; b=c2ONXwfsJbOhpN7cMi2fy5Macl5jEshpWIfBboMKVoSruBMpaPia83 YEC2v0YI1POJnXbgxzO0Yr82tCxdDdA7Mt76y+DFxzmLJdNH0T+qVjaJiE09pLQc sn9r1AQ1xAw4ExDmcAqbmD8CpDE83kHYxIk9/Zce4IBd34zf2YyBI= Received: (qmail 66467 invoked by alias); 20 Jul 2016 09:53: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 66442 invoked by uid 89); 20 Jul 2016 09:53:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL, BAYES_00, SPF_PASS autolearn=ham version=3.3.2 spammy=knew, trap, general_operand, Whether 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; Wed, 20 Jul 2016 09:53:13 +0000 Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-ve1eur03lp0146.outbound.protection.outlook.com [213.199.154.146]) (Using TLS) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-47-aeuLEK41MRSWA4tISTtXNQ-1; Wed, 20 Jul 2016 10:51:59 +0100 Received: from DB3PR08CA0016.eurprd08.prod.outlook.com (2a01:111:e400:503c::26) by AM3PR08MB0658.eurprd08.prod.outlook.com (2a01:111:e400:c409::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.544.10; Wed, 20 Jul 2016 09:51:56 +0000 Received: from DB3FFO11FD023.protection.gbl (2a01:111:f400:7e04::115) by DB3PR08CA0016.outlook.office365.com (2a01:111:e400:503c::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.544.10 via Frontend Transport; Wed, 20 Jul 2016 09:51:56 +0000 Received: from nebula.arm.com (217.140.96.140) by DB3FFO11FD023.mail.protection.outlook.com (10.47.217.54) with Microsoft SMTP Server (TLS) id 15.1.523.9 via Frontend Transport; Wed, 20 Jul 2016 09:51:56 +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.294.0; Wed, 20 Jul 2016 10:51:53 +0100 From: James Greenhalgh To: CC: , , , , , , , Subject: [Patch RFC 4/2 v3] Refactor noce_try_cmove_arith Date: Wed, 20 Jul 2016 10:51:35 +0100 Message-ID: <1469008295-28884-4-git-send-email-james.greenhalgh@arm.com> In-Reply-To: <1469008295-28884-1-git-send-email-james.greenhalgh@arm.com> References: <0f3c74c6-0c1b-f2df-77ce-a2ffc112583d@redhat.com> <1469008295-28884-1-git-send-email-james.greenhalgh@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:217.140.96.140; IPV:CAL; SCL:-1; CTRY:GB; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(7916002)(2980300002)(438002)(189002)(377424004)(199003)(36756003)(246002)(5000100001)(189998001)(110136002)(512874002)(4326007)(8676002)(229853001)(6806005)(305945005)(8936002)(5890100001)(26826002)(7846002)(86362001)(87936001)(4610100001)(50226002)(7696003)(356003)(11100500001)(5003600100003)(2476003)(2351001)(106466001)(84326002)(19580405001)(568964002)(19580395003)(92566002)(2950100001)(33646002)(76176999)(50986999)(2906002)(77096005)(104016004)(586003); DIR:OUT; SFP:1101; SCL:1; SRVR:AM3PR08MB0658; H:nebula.arm.com; FPR:; SPF:Pass; PTR:fw-tnat.cambridge.arm.com; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; DB3FFO11FD023; 1:NnGvHiZEngDWPXfSjgKBjOlNLFysHH7nNTQvCE9bQ4njfCAr/xlPlc2HiyYAhNzJx/MaQAfCm0PrsF4CkPgfcozIWdJiSu9KJXJ+2p1tI8FCKgZt2PVci4B6RB9uiB//SnmPGrETOHJwSx6TjS/3apObTZ8dKqWazWqfR9z2/X4iErpIS0EEAZrp4dU+9VDy9t7Ob8T8GjWn/IHGWBcjGhcFlrnpSTvrUOwtdC1Iao1IXKzU/5arh+HfM7fC6M28yOoTHbhLpZKb2Gr5nPhO+YZWWlSkWfUGkt3rjxzLU7+m7Z/6Fd3lQCWoYFGvAdXGrMtxvQ2+bKTu6Dn7wgC787D3o1iTOe7rU9hn9zM3YGT6U0IWWBBjK+yu14ZIaze7MQ9Z0iNqEccrmBo1dGfvBhb9GaSLJYOYP11eK77pFAoguV/SaJm6U+E4pw0m+WYPDc6lmz4ykHzm45+P/GWSWjK+CoYTQP+ChHWb9XrA+367LAbbAPvKnBdPLrNmu4DOHheCMpYEwt/VWa/WWngLMJp1I+6pEOaoT/GKC51xSqll+vB4tlsdb460rzaAqY0hwkNh3X0nhEriVnETHVHArQ== X-MS-Office365-Filtering-Correlation-Id: 45d5f5e6-5e92-40c3-acb3-08d3b0837ce0 X-Microsoft-Exchange-Diagnostics: 1; AM3PR08MB0658; 2:C91eeST7m4g5mVMAGVCGX3Ee0zo8K+h0rSFCqH5ySazmV1d5DqESC7/IyYcbHLVne+i4zDoxkdhiULkPAdoKxpS8mz/BTS/WjUAyRHaNaPqSL6TSvS24+3ldpovvO2ZtZniOA56tNShq0KCfRIyE3y8ks5tbPNE+GBTTNG+B/pjz48KxHUwYK/PjU9by5PHh; 3:KPEl+uXOoyfQeco4tyfIBTniftQ2Zg3BstX3qZYzLZ9g/Qtv6zvv9iG5RNVimxFDEHWShPNDROCZwK+l0S+RNyCJ9i1FeV+l5CaYCX1/rvlZcL+q2c2ZkME+wCeaDwPx6esruEId9peqbUNwjCvJyeqoMAdx+cHML/GNZNwglTnq5rDe389C2AqNr4bjV0SleqgQfLokS7JFm98PVAS3efq3TkpjpCLkqlH1isIg+jBIukOauaWGd4zpvM98Tf7S92fEH7cEIqTle51Fou4gXA== X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(8251501002); SRVR:AM3PR08MB0658; X-Microsoft-Exchange-Diagnostics: 1; AM3PR08MB0658; 25:FBVbRem2MlL+tHnLUIwL9Fo2yWS1DGhXEPkD6Ov7hqzGO1wBt6eCJH2cP+RsE8zwMolY6EKHBg9I5Lps5adSQc/325qKp8Bk6Q9CuheBUM28FuqkHJHmBZtxiCvA8pHMjY+ZGN24xaNZI2HnoJj/le4skV9xupvBTnH8twecrdXK2sSWyMgeGvat63JB/UI6JLD+sfLNO1Volmzj59zt8ybD4yGyWrAI/zxCkQrlfxuf2u3mIi+NrthXmWAiKH7tF41nqYLA0qvTDe78q+0kKHiz71YDs3/IUA0fZqKpEXHSPMXGuT1/eqZpBIB01zEzmII5RN1zO++4ivms+b0hh2CBsYH1C9G0LfqB0z7seIqwTjAuxBs7Vu4O0eFu++X27PsM3xf0Ll3C2ym0xWi1yK+1NYaDzs2p2JoyRmTGQmbVDrV+DLuOgOT9lN1gTmZNA1M7kaDCO/E7xmin55UE8fCEaBLdm3bCZEGD7oqLmKFdMqmIvmJTXYYOFEJdyp0KwtkmYuJC1xB4w4lWzgQesDD2ENHuBWm9nPQTqaympGAn+qMz1tkbWuItRIonAoOp0+o8y8WmGaLbMjejKc5iwk6r6kwR0U6bqwejNH7+NjZV5WYcNr+3YLQiW7/xXCbOdP9mEtXa2b0+DpY+AiZel8alHdkq72u92auzL+X4LzRfVw3nwYJ6vcL0BtEWa8vJQX26qav+mTmA8cLMGI5ZgwL6W2qOxPLYam/v1Zlp7EstFiWyi8KIVIUQdpsefP7ZdLrUcaOhHkTCxc4WmPb4StREYJ6Z0zNI+IDRRDO7Ysic4+wdD6RKn8in8vKFeqsSVGUyKVHDmDWntteGNdJ780vDMylrYSWQ/YEVqddCknDx3AD9Iat54x05ptHKSUSSr205rHJXISbnBdRXYW3CyM4bf1GpqAXrPk1NiXJl+4Y= X-Microsoft-Exchange-Diagnostics: 1; AM3PR08MB0658; 31:yQiQSAhBNgar7QrpX+llpIL/5KKGcpNu98HlwxmbatHd+YnnzJQ/T8MG24po9MQSALJaBS16u0Hqp9WYHkwNnQSnLH+02EUlhYp76UnhkE776nqYKVUcOhXJ+wBXdSdvmd/vPh+fYcepUFaGLRAb07D8K4jdDolByqGqxIzOCcsD4Ro1WP8eWYcmjpLGG8JAfs0rO0O8Pw2Gmk4+XZwlYQ==; 20:RcX1LGyRQcSu11FmgWjGypC2HHg32CD3yAH1KYekk+hVgNRi8dgerNnyFjDJhFxFeot5c4EuctNfDxlk01m4PYZDKpgr/4L4oKVyGapdautFpxjujzL4gjJlr1kg7hMUSLb4XPCvHSwNtCff7yAMnBsQfpknDPp24c+2CHCaJP30D9a5mG7rzGfPG5itsGVl7ZcsVjXe6WGguD6LEgnmX2kTbAS6uDJpFlWQgy66yS4y2qyP4s2kpaj3iAiuBBgA NoDisclaimer: True X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(180628864354917); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(102415321)(601004)(2401047)(13023025)(13024025)(13020025)(13013025)(5005006)(8121501046)(10201501046)(3002001)(6055026); SRVR:AM3PR08MB0658; BCL:0; PCL:0; RULEID:; SRVR:AM3PR08MB0658; X-Microsoft-Exchange-Diagnostics: 1; AM3PR08MB0658; 4:UNzua9CuevCU5hllPcYEJf2adP4NJN8vUS42bsysmodSq45GOSJ5KP6mmME3Eo/9GP/HGiVCgFnnV9/gdWBDouN2/+6y4tFXPv0ZthZ1w9B7JsGW21kQ76tZA2D1YhBAwICtzDxjFsulYMCMlDkmtDAEYtE5gVc5xXoNM/IVS8mXrcPR3nMoBOkNpzaKOJnvLcb5YUptPFwEGWpoIpk0Ls+/ajDTP62H8VBoxae+ZJxL/uURROEXsM9ntuamB+knVu/YgBd03OFsdNzkCJH3oJvYLty9FJ7rFOdgs/Ls8t5c0I2novALTVVThfWkAcFRribIpHgO1njcgazOGB3ACH/tde9K1HDFGcUYP1EVqYHiqhpjwmbiSvzKl3HMNjMbA9fVRmGpfK51IQ+tAPwHJ1yCtbVrFHdKYz/krjsZF8uol0d2GXG7RIN207hFIHzm19DvthBG/Px763Z9NjjbgwHlqXBI2JVWHPUeR6B6Gw5ShUTbGUhvKtWvwBCEZKDIKoU9q1JEwZ5oZayVeKhajA== X-Forefront-PRVS: 000947967F X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM3PR08MB0658; 23:OhjXx3j2AGDIYUwBRYnb1FmnZuVvWJ5dN1C26I7IL?= =?us-ascii?Q?IkEmR5WpjqVZKOlGRgexjrmSpKjj5GiXG+jXLY/MwqGddlMrwhrhjyApTNSx?= =?us-ascii?Q?HGnKeZzrg5CBEzhK/FIFzNi7Te64xGtUq9EZMTli1tLexqycud5J0YIXp7r2?= =?us-ascii?Q?/1po8culwAOxkHVWjRWFoqli2xEfpk5+fJ+1iXQxYKVWPEtil7AmEBj3HQhF?= =?us-ascii?Q?wp4OQok6zOGaUQ1FDKu1VkgS7m8Q2aA1UzRWnSj4bL3KnDS6IiRDNpWk9NDp?= =?us-ascii?Q?KBNOhs7D3VKbFFakxgUyJ/Zyk6UOSVBayaKmsU0tg4RhYgZ5fQfQkNjP5jjn?= =?us-ascii?Q?a54TKArJHyQTKGBRKQ9EUsDZWiQN7+zUUozRx7ru+U1eBiPPM+gMsU9sqlCA?= =?us-ascii?Q?9URZOF5qQkAgGwAEz0UDwEUVuF62wmHol8jnyKvjwntmmIjuZXD7PGukomUq?= =?us-ascii?Q?P5Uoc1iSNhsZtuOBq0AUYQ0DMVaiJ+tMy5BTsIGKf+a2Rc2bfKawl0KRRDLX?= =?us-ascii?Q?Wg09IEKSuo2wHN+fqhdhU62YR4EdTbvv1sFyizQFw/OlD6u8fboapIoN9HpO?= =?us-ascii?Q?6TL/AMbo81GtzwitmVnq24rcevr4sWkeLtpBzrJzRlefIuIW3CKtYrR27RVp?= =?us-ascii?Q?lQjCMBiT0m3Jb/3FEnmdUns71jshPdukxc1CtbuEvrHIt1UYdJrMSiTGvmXK?= =?us-ascii?Q?vLOeIBaL5N/8DoOxcPPGoQwK7dRtknTSGSFIz72ZFKsP1OUoXxIwZ/tSLcop?= =?us-ascii?Q?OgCPKE9rOkIH2tPufu1hz6r7ig7fAXxqfvbdBFGd9S1zxs+5Ht3Dl/zNovo3?= =?us-ascii?Q?fBYZIJH6lIeVTPR8hjR/nkJPAEB0irx0WCEaaijLtlXmD21t/bKnT1Nn7YoD?= =?us-ascii?Q?AWRPKmjpC69I8+GiX1Wm+FqHfRfLtvsgSyXZX/mHDqcN5/Oq8wnbS9WTqnxP?= =?us-ascii?Q?ultS6DfTrbLbXYYnMtdDMeW4usqDXgU9nS6qeK0s2AmPk+9BbBFguKTgEbT+?= =?us-ascii?Q?7ka/UkjFcUrAU5oGTZSnt6hDGDu7BziY+RVckvH9EaIYKKkWyQof0BUbm+4s?= =?us-ascii?Q?cPoFRmoZMYdSJFtRpBcCatJlGhs/MRYr5u4FdFKdbUL7twxdwftBIbaJwojT?= =?us-ascii?Q?6cb/8KVSxutP9RMc4VBbgRrFE7AEesZFSYj3tUVdHpSjGJa1qxjuA=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; AM3PR08MB0658; 6:SwiWB7XCWS0gsfI7cfwoPMB+9DJ/czT/Ru4qeycHHuyy7ZxRnFri0l/P4vCBYMBKcAnULtRXN4PieVrziNkuy0b0PlhQGpJh6/oXe3n4QAlhV5i+/M3hgN8Y4Hx7nnGF++TQIc/25xhSg478ICf1kBRRisJpD73eNxWM+ZamE/UE7HHzhMOisQee+K18D9FvOWDg2pqF0LaTrYy6A8odftwaBOeresJYsLino89RPJdSS4lrENk/E2o6rV+bWuRbz8u/fX2W/O9QbrRsvGL8UjPsJ9KJtlJwIpsI7gWPMUohDfMsLWqCU7ne6D8KlnFcZ/R7Kn7qiEIRrJ1owS8SBw==; 5:+YIH/4JKm3PXU9l8ODIJaLIO/Pzs7s5egJGMIc+FNbEtw6QyHS+D20X25Z6Evllf52gRwketUEZld8CoeougwlNzH97/ZfKC1w+E33ttKM5/89DBE3IegtlSFGThiJiu/LyiLqq83x2Z3LfTYa0BCw==; 24:LLUBOu4bDmW3DhaWpG/SaRYzK2My8cWTQEUCZ2AtFbjoSXuDWZywNDng/VO1mhATAK0Y92ZpirctF1GS7Bgha+5uk/YvvG0f0b8xi2J04Us=; 7:nLOhmGghxMwJDYcgwuxh7BPTL4dmzftBI7b2ODgrFyrC3IqgC4IzhNHRKqOtxHigafa3FCqpBhvOEgOwxQezCB6uX23bqxFeay7ga59TD1rBYRXmjd6P6pqfVbza6KQzYrWhMir5p9enYqBmI9Vfb7XQNbu73Ge3eAHKb+pfg3x1L1P8H9c7Vfwatiaw12GcfeziVN10Ob5KRQmi/hgkHipFDMDwQkYVPuvs4ZyHplKTGY+VtOuHVi9AgiMMZMw7 SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM3PR08MB0658; 20:+AnMPFUS6IML8biZdxEtWAIsxBMEvsnbtIcMj6eIL3Tu2olBI7D+Jlll9ew/6BB7eSF4KgTG2Knd1iA5QtcOP6k12ccoBBgNTAOmi3iphH01VepJVAFT9K6/+KapNOK5NQvKBayMYrc4dGGBk/pJOzDFTztlM3YjF8/H7rFuhBU= X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Jul 2016 09:51:56.9179 (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: AM3PR08MB0658 X-MC-Unique: aeuLEK41MRSWA4tISTtXNQ-1 X-IsSubscribed: yes Hi, This patch pulls some duplicate logic out from noce_try_cmove_arith. We do this in order to make reasoning about the code easier. Some of the natural simplification that comes from this process improves the generation of temporaries in the code, which is good as it reduces the size and speed costs of the generated sequence. We want to do this as the more useless register moves we can remove early, the more accurate our profitability analysis will be. Bootstrapped on x86_64 and aarch64 with no issues. OK? Thanks, James --- 2016-07-20 James Greenhalgh * ifcvt.c (noce_arith_helper): New. (noce_try_cmove_arith): Refactor. diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 4e3d8f3..f2e7ac6 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -2068,23 +2068,127 @@ noce_emit_bb (rtx last_insn, basic_block bb, bool simple) return true; } -/* Try more complex cases involving conditional_move. */ +/* Helper for noce_try_cmove_arith. This gets called twice, once for the + then branch, once for the else branch X_BB gives the basic block for the + branch we are currently interested in. X is the destination for this + branch. If X is complex, we need to move it in to a register first, by + possibly copying from INSN_X such that we preserve clobbers etc from the + original instruction. EMIT_X is the target register for this branch + result. ORIG_OTHER_DEST gives the original destination from the + opposite branch. OTHER_BB_EXISTS_P is true if there was an opposite + branch for us to consider. */ + +bool +noce_arith_helper (rtx *x, rtx *emit_x, rtx_insn *insn_x, + basic_block x_bb, rtx orig_other_dest, + bool other_bb_exists_p) +{ + rtx set_tmp = NULL_RTX; + + machine_mode x_mode = GET_MODE (*x); + + /* Two cases to catch here. Either X is not yet a general operand, in + which case we need to move it to an appropriate register. Or, the other + block is empty, in which case ORIG_OTHER_DEST came from the test block. + The non-empty complex block that we will emit might clobber the register + used by ORIG_OTHER_DEST, so move it to a pseudo first. */ + if (! general_operand (*x, x_mode) + || !other_bb_exists_p) + { + rtx reg = gen_reg_rtx (x_mode); + if (insn_x) + { + rtx_insn *copy_of_x = as_a (copy_rtx (insn_x)); + rtx set = single_set (copy_of_x); + SET_DEST (set) = reg; + set_tmp = PATTERN (copy_of_x); + } + else + { + set_tmp = gen_rtx_SET (reg, *x); + } + *x = reg; + } + + /* Check that our new insn isn't going to clobber ORIG_OTHER_DEST. */ + bool modified_in_x = (set_tmp != NULL_RTX) + && modified_in_p (orig_other_dest, set_tmp); + + /* If we have a X_BB to check, go through it and make sure the insns we'd + duplicate don't write ORIG_OTHER_DEST. */ + if (x_bb) + { + rtx_insn *tmp_insn = NULL; + FOR_BB_INSNS (x_bb, tmp_insn) + /* Don't check inside the destination insn, we will have changed + it to use a register that doesn't conflict. */ + if (!(insn_x && tmp_insn == insn_x) + && modified_in_p (orig_other_dest, tmp_insn)) + { + modified_in_x = true; + break; + } + } + + /* Store the SET back in EMIT_X. */ + *emit_x = set_tmp; + return modified_in_x; +} + +/* Try more complex cases involving conditional_move. + + We have: + + if (test) + x = a + b; + else + x = c - d; + + Make it: + + t1 = a + b; + t2 = c - d; + x = (test) ? t1 : t2; + + Alternatively, we have: + + if (test) + x = *y; + else + x = *z; + + Make it: + + p1 = (test) ? y : z; + x = *p1; +*/ static int noce_try_cmove_arith (struct noce_if_info *if_info) { + /* SET_SRC from the two branches. */ rtx a = if_info->a; rtx b = if_info->b; + /* SET_DEST of both branches. */ rtx x = if_info->x; - rtx orig_a, orig_b; - rtx_insn *insn_a, *insn_b; + /* Full insns from the two branches. */ + rtx_insn *insn_a = if_info->insn_a; + rtx_insn *insn_b = if_info->insn_b; + /* Whether the branches are single set. */ bool a_simple = if_info->then_simple; bool b_simple = if_info->else_simple; + /* Our two basic blocks. */ basic_block then_bb = if_info->then_bb; basic_block else_bb = if_info->else_bb; + /* Whether we're handling the transformation of a load. */ + bool is_mem = false; + /* Copies of A and B before we modified them. */ + rtx orig_a = a, orig_b = b; + /* A new target to be used by the conditional select. */ rtx target; - int is_mem = 0; - enum rtx_code code; + /* The RTX code for the condition in the test block. */ + enum rtx_code code = GET_CODE (if_info->cond); + /* Our generated sequence. */ rtx_insn *ifcvt_seq; /* A conditional move from two memory sources is equivalent to a @@ -2094,33 +2198,19 @@ noce_try_cmove_arith (struct noce_if_info *if_info) if (cse_not_expected && MEM_P (a) && MEM_P (b) && MEM_ADDR_SPACE (a) == MEM_ADDR_SPACE (b)) - { - machine_mode address_mode = get_address_mode (a); - - a = XEXP (a, 0); - b = XEXP (b, 0); - x = gen_reg_rtx (address_mode); - is_mem = 1; - } - + is_mem = true; /* ??? We could handle this if we knew that a load from A or B could not trap or fault. This is also true if we've already loaded from the address along the path from ENTRY. */ else if (may_trap_or_fault_p (a) || may_trap_or_fault_p (b)) return FALSE; - /* if (test) x = a + b; else x = c - d; - => y = a + b; - x = c - d; - if (test) - x = y; - */ code = GET_CODE (if_info->cond); insn_a = if_info->insn_a; insn_b = if_info->insn_b; - machine_mode x_mode = GET_MODE (x); + machine_mode x_mode = is_mem ? get_address_mode (a) : GET_MODE (x); if (!can_conditionally_move_p (x_mode)) return FALSE; @@ -2151,117 +2241,27 @@ noce_try_cmove_arith (struct noce_if_info *if_info) start_sequence (); - /* If one of the blocks is empty then the corresponding B or A value - came from the test block. The non-empty complex block that we will - emit might clobber the register used by B or A, so move it to a pseudo - first. */ - - rtx tmp_a = NULL_RTX; - rtx tmp_b = NULL_RTX; - - if (b_simple || !else_bb) - tmp_b = gen_reg_rtx (x_mode); - - if (a_simple || !then_bb) - tmp_a = gen_reg_rtx (x_mode); - orig_a = a; orig_b = b; - rtx emit_a = NULL_RTX; - rtx emit_b = NULL_RTX; - rtx_insn *tmp_insn = NULL; - bool modified_in_a = false; - bool modified_in_b = false; - /* If either operand is complex, load it into a register first. - The best way to do this is to copy the original insn. In this - way we preserve any clobbers etc that the insn may have had. - This is of course not possible in the IS_MEM case. */ - - if (! general_operand (a, GET_MODE (a)) || tmp_a) - { - - if (is_mem) - { - rtx reg = gen_reg_rtx (GET_MODE (a)); - emit_a = gen_rtx_SET (reg, a); - } - else - { - if (insn_a) - { - a = tmp_a ? tmp_a : gen_reg_rtx (GET_MODE (a)); - - rtx_insn *copy_of_a = as_a (copy_rtx (insn_a)); - rtx set = single_set (copy_of_a); - SET_DEST (set) = a; - - emit_a = PATTERN (copy_of_a); - } - else - { - rtx tmp_reg = tmp_a ? tmp_a : gen_reg_rtx (GET_MODE (a)); - emit_a = gen_rtx_SET (tmp_reg, a); - a = tmp_reg; - } - } - } - - if (! general_operand (b, GET_MODE (b)) || tmp_b) + /* Get the addresses if this is a MEM. */ + if (is_mem) { - if (is_mem) - { - rtx reg = gen_reg_rtx (GET_MODE (b)); - emit_b = gen_rtx_SET (reg, b); - } - else - { - if (insn_b) - { - b = tmp_b ? tmp_b : gen_reg_rtx (GET_MODE (b)); - rtx_insn *copy_of_b = as_a (copy_rtx (insn_b)); - rtx set = single_set (copy_of_b); - - SET_DEST (set) = b; - emit_b = PATTERN (copy_of_b); - } - else - { - rtx tmp_reg = tmp_b ? tmp_b : gen_reg_rtx (GET_MODE (b)); - emit_b = gen_rtx_SET (tmp_reg, b); - b = tmp_reg; - } - } + a = XEXP (a, 0); + b = XEXP (b, 0); } - modified_in_a = emit_a != NULL_RTX && modified_in_p (orig_b, emit_a); - if (tmp_b && then_bb) - { - FOR_BB_INSNS (then_bb, tmp_insn) - /* Don't check inside insn_a. We will have changed it to emit_a - with a destination that doesn't conflict. */ - if (!(insn_a && tmp_insn == insn_a) - && modified_in_p (orig_b, tmp_insn)) - { - modified_in_a = true; - break; - } - - } + rtx emit_a = NULL_RTX; + rtx emit_b = NULL_RTX; - modified_in_b = emit_b != NULL_RTX && modified_in_p (orig_a, emit_b); - if (tmp_a && else_bb) - { - FOR_BB_INSNS (else_bb, tmp_insn) - /* Don't check inside insn_b. We will have changed it to emit_b - with a destination that doesn't conflict. */ - if (!(insn_b && tmp_insn == insn_b) - && modified_in_p (orig_a, tmp_insn)) - { - modified_in_b = true; - break; - } - } + /* Sort out temporary registers and figure out whether either branch + would clobber the other. */ + bool modified_in_a + = noce_arith_helper (&a, &emit_a, insn_a, then_bb, + orig_b, (else_bb != NULL)); + bool modified_in_b + = noce_arith_helper (&b, &emit_b, insn_b, else_bb, + orig_a, (then_bb != NULL)); /* If insn to set up A clobbers any registers B depends on, try to swap insn that sets up A with the one that sets up B. If even @@ -2285,6 +2285,12 @@ noce_try_cmove_arith (struct noce_if_info *if_info) else goto end_seq_and_fail; + /* Emit the conditional move. If our operands were MEMs, we + need to generate a temporary to hold the result of conditionally + selecting between the two possible addresses. We'll fix this up + immediately afterwards. */ + if (is_mem) + x = gen_reg_rtx (x_mode); target = noce_emit_cmove (if_info, x, code, XEXP (if_info->cond, 0), XEXP (if_info->cond, 1), a, b);