From patchwork Fri May 13 17:11:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tamar Christina X-Patchwork-Id: 53966 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7AE263959C48 for ; Fri, 13 May 2022 17:12:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7AE263959C48 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1652461944; bh=MgUv//frcqQf/FtTB6yBzCmlveNyMnbpKJUNm9mG0AM=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=s40AXGqoXtueXRvuDe5ahseDENZrdCpXNp30FKd71Lpp4jOj3CSrrHN9sgikkJghv 8wUTL+MRxawtfLZloQYNBJ/Z0tb0ukTytIvIXtGU3/CFGAylMzy4tHyRbwZJ4cEtT+ YYu6Xqjfjxz800EjF0wH5WAatAFxtpdzwdpeIBAU= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from EUR05-AM6-obe.outbound.protection.outlook.com (mail-am6eur05on2069.outbound.protection.outlook.com [40.107.22.69]) by sourceware.org (Postfix) with ESMTPS id B773F395A45D for ; Fri, 13 May 2022 17:11:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B773F395A45D ARC-Seal: i=2; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=pass; b=KgdVcYzHAHfGr0NwKeWhMk+sHVmKg7O/CPiZBNytF9rAQy9ERUQ+F3bGqjj0SJc77A8igjmKHjg1xx4NLiPekPWlEPv0Ls1WOXmmY+M8CLdtSi6NZoHTjLNF2Uv0ja15YtM4uLc5xrcxFJtQCmoCj/Gkxt87ax+9i19opkxlRxOBy4qj/GjasFX9Z1YJYaxMjk3OT66jId/hkyeP4RiJxnVlM2ww4xT509XjZ+1fBh8uTJNTv+Yd1B+/hNBiQs4I9/tOIYTBRqd+K+bbMg5flG+jKuBXQPpr2J/qtazADsi9AOndMssvsBkVCbQKgakoF2nKUOXd9xGOOl6SjbGjtg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=MgUv//frcqQf/FtTB6yBzCmlveNyMnbpKJUNm9mG0AM=; b=Y4zzzBB1XB9BnF3g8K2Q0Qk7dpX5cFJcVoOYHJeTZZrogw+H2fvOv733M51hO08XFhb2iH4O2wjpFueseCq9VNpsau2QgdNTgOdpjeUsfulwJ6RyY6w+nnkY+6T+7NBEn6h0HVqNQSvbBnQdVMJKklvMrOD4YDCwmVW4paBiJRjviZB2V+NqEu+6rApwTivpHBnuia+a3sFtJ7VaCXCdqpe9ashfAXEyPXWMQiwgpeWyWq/jf6v++yQmX15l5eWjmxoRhcoG/3MxNB4U+uHCZVw+FKBUSnz6IysR/ffUZPJU4JsBwGueBEIz9LEY6FDubsb5PP8QhVQK6EV5sVujng== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 63.35.35.123) smtp.rcpttodomain=gcc.gnu.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com]) Received: from AS9PR07CA0052.eurprd07.prod.outlook.com (2603:10a6:20b:46b::27) by PAXPR08MB7044.eurprd08.prod.outlook.com (2603:10a6:102:1dc::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5250.14; Fri, 13 May 2022 17:11:27 +0000 Received: from VE1EUR03FT035.eop-EUR03.prod.protection.outlook.com (2603:10a6:20b:46b:cafe::d4) by AS9PR07CA0052.outlook.office365.com (2603:10a6:20b:46b::27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.5 via Frontend Transport; Fri, 13 May 2022 17:11:26 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by VE1EUR03FT035.mail.protection.outlook.com (10.152.18.110) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5250.13 via Frontend Transport; Fri, 13 May 2022 17:11:26 +0000 Received: ("Tessian outbound 9a0893f586e2:v119"); Fri, 13 May 2022 17:11:24 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 5566aaad68648cee X-CR-MTA-TID: 64aa7808 Received: from f4d1c62ece52.2 by 64aa7808-outbound-1.mta.getcheckrecipient.com id EC344E5A-9AAC-4DB5-9F8E-E41D0E7E02F8.1; Fri, 13 May 2022 17:11:18 +0000 Received: from EUR05-VI1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id f4d1c62ece52.2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Fri, 13 May 2022 17:11:18 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=DJLpiwLRla68pbVj97NADahKbcO/Dkho0b2PgC7qofYDYdrg4XAofKwczTGjEcQ8hZk4G6RB2L2sBqoit/abdrUPgDtIRiXMZoxy0hvjiKzlLRHfJqOL1EKcbLnMe+eIzHWVI1ahUeT/rLiHXHnuYPvU/tiG+j1hu4bZMT/obpBlmQtHynD7bl2fVHxex8h/WavdWvfUI8AnzHMuKZD9dZlrz/RFARR4MMjqHC9WOWUBa8gBDjBI2juMKM97ADk8IZ/H2TTXEujlUGoRA9Gj4coSZh6lCoUrBYMxXNQ2Sv37bx2q+f99EpXRYv+L1fztvWn4Muar6RhsNK7DtT1jcA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=MgUv//frcqQf/FtTB6yBzCmlveNyMnbpKJUNm9mG0AM=; b=Iiv2zrSuSMZ7sfMPOOCxyWsidCmjRaXl1/Z7DrS4n7nzdBqtIEekiXzhZfMODYUyHxQ6N4iwOT2LOcvP0Sge4vi+rvw6aCTwq8iRW4W3Gy3MDqGHA3UhKLewFXBzuP9KjeiYAYXOAnM35Fpwm7JwVM7WPEu/6sYvW3n5knuWKNn3DxrODxMeQNVMe+ZuP/Dv0VA8VlcBy4p1SUBmRNXLVxwU96WjEvOsjr7PZp12emMEK6KHX4BCFmvXB61weJJEm5Tcvfhj28jTBntgVOFB5eb/e6hmPhuT6v2SYzurnrlz0Z4mUh1nlHrrwsjnJKv+6PeFJGF45XagzcnSdCPEvg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; Received: from VI1PR08MB5325.eurprd08.prod.outlook.com (2603:10a6:803:13e::17) by DB6PR08MB2933.eurprd08.prod.outlook.com (2603:10a6:6:1c::29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5250.13; Fri, 13 May 2022 17:11:14 +0000 Received: from VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::7c18:b406:6441:f7a3]) by VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::7c18:b406:6441:f7a3%5]) with mapi id 15.20.5250.015; Fri, 13 May 2022 17:11:14 +0000 Date: Fri, 13 May 2022 18:11:12 +0100 To: gcc-patches@gcc.gnu.org Subject: [PATCH 1/3]middle-end: Add the ability to let the target decide the method of argument promotions. Message-ID: Content-Disposition: inline X-ClientProxiedBy: LO4P265CA0070.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:2af::10) To VI1PR08MB5325.eurprd08.prod.outlook.com (2603:10a6:803:13e::17) MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: bfd45da8-c5d8-4de8-d54f-08da35039d69 X-MS-TrafficTypeDiagnostic: DB6PR08MB2933:EE_|VE1EUR03FT035:EE_|PAXPR08MB7044:EE_ X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: 80WvH+AyLHpgbHG+0jIBWJL3NIUcXI+iBXYQF8Et1DWFzJdaqlgHSCxEgc8x36e0Wz02FZdsOinFmI8H64iROytCPpvRKRTXR/slMUBuQDwCEORoZ8yvprzaHelPbVD3U0KzDYc2I1IlCQgWjfdU0b0yDtpRCjSETrKv4/YkbFmymPk8H6q6hj6/uhm2piDYNC5++sKNB0l8t6Yhvd/KzFbraCMbHJBpfkzGvEh+8ZEBuQAptu9dMWwtPkjPBJYJ2ZzOlzZceU8LE8aZ4RG333DDId+/GW0hhxLvYtUw3lLAD4NMJPZA2SE4Z28pfUsl3O1tGPAuf9BeknNfjMlvpTBz03efvAkuDkdhjBlMG/fIWGmb63WOgDBr2LAROXJOT7nOeyyRtpGEKSFbAcA442irhDfSRFHlgmqWdtMHTyqXSXydezZwU5x9wbiroz8VOCyMHgyAJzZsod9p843aPO0iXxFR26nrW9jXXbuHYx9p73vszRDTHS/xbjPGP+BOoKZ4dXt4lYcojsgdYvHqIYQg0s5tcUSGUJfzRyKID/JMGEOsCGtaBdKjsuSrZb/ampKZdmYkpfH0l/RHdpfr8+C1/sbNBMrajBD5CUZcVLnmUTzcGNI2eWqAhLIX6FfGy/4PPlZ7yueDv/JdPYlYQVkpBgPBliKRctQgvKwE4MXK8yDeirPGfVRpkwkLakM/Q7KkjBEo4hrZi5QLLdUbJrfhJxLQvuYH6fSlgDKyF/Q= X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR08MB5325.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230001)(4636009)(366004)(235185007)(2616005)(186003)(44144004)(33964004)(8936002)(5660300002)(6512007)(44832011)(6486002)(508600001)(4743002)(26005)(316002)(36756003)(6506007)(6916009)(66556008)(66946007)(66476007)(86362001)(8676002)(4326008)(2906002)(38100700002)(4216001)(2700100001); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR08MB2933 Original-Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: VE1EUR03FT035.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 59beb297-632d-41fc-1ade-08da35039618 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: w3Tj78vlTkrNxGz7/CgEEimp09dbKyLee2hUNn94INu6V4Fv/ABbaXF0E+APVhHTiPaKAZs2W0WiqDrHAWfvcJZtfQthDAqWOkskvrZwfBphqwOTt6sNym+RoIqR8V1Ao4SSc2/MC4juHwbnH7+XPzHtE/MNLuDHZkRn+H7vWzRb7rJx8PdgfiJuPLNB0+uBzkv9V0jI/f3kWgdUBy5BxmToCnIwyUKeoxdvWp+GjL5asfdXy9J9SOR0HxtM/dlmFdQwKQaqS/ZQyr88kC8yBYd1U0ZNpKLhq9bdTrhDVOnLS7q/nju8HCrK0Cg2XKhEEs4etEoBcwkogUcvlwAg28kS6fPwdS9r47uhKY+eJh6qI5CQdMhvnIgrFhI/gmVkJahquuIuzlabQWdZs14tDxKNBkYLD/lwrzbGmglqFEq/+3blmj6b0wfMTdbHDT9L1TvvRZwFKNMyz02ujlBjR0aUsXmgYDGl3FM7u3v9bDIAVPMY79WiecrlGTzy80Q4CjcQbEiPdbYC0jnTclHn5Ie0ITqUOP+M1nNpKAuN0D4KSEoq0lz55rTBW6WXFdaO4PvQsAIbK71nd6lYRv8k8UmfaxsAfWuIYHdlE2V2S6CaQVmGsC7MWXfNKWaZT8KSpcYNqHFaE8d1Alz+nH1TFhSvlu83oT0/MmdUIlCo9znRDH+mdTxKUWv/PseGssmyxD5bLesrI8gKMhDA8WuiPTiQjMUvXBWByy0XFZu2xDM= X-Forefront-Antispam-Report: CIP:63.35.35.123; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:64aa7808-outbound-1.mta.getcheckrecipient.com; PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com; CAT:NONE; SFS:(13230001)(4636009)(46966006)(40470700004)(36840700001)(70206006)(8676002)(235185007)(2616005)(70586007)(4326008)(6916009)(82310400005)(6506007)(186003)(47076005)(5660300002)(336012)(6486002)(44144004)(33964004)(26005)(4743002)(81166007)(6512007)(356005)(36860700001)(86362001)(36756003)(2906002)(8936002)(316002)(40460700003)(508600001)(44832011)(4216001)(2700100001); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 May 2022 17:11:26.7073 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: bfd45da8-c5d8-4de8-d54f-08da35039d69 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[63.35.35.123]; Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: VE1EUR03FT035.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR08MB7044 X-Spam-Status: No, score=-13.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, KAM_LOTSOFHASH, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, THIS_AD, TXREP, T_SCC_BODY_TEXT_LINE, UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tamar Christina via Gcc-patches From: Tamar Christina Reply-To: Tamar Christina Cc: richard.sandiford@arm.com, nd@arm.com, rguenther@suse.de Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi All, Some targets require function parameters to be promoted to a different type on expand time because the target may not have native instructions to work on such types. As an example the AArch64 port does not have native instructions working on integer 8- or 16-bit values. As such it promotes every parameter of these types to 32-bits. This promotion could be done by a target for two reasons: 1. For correctness. This may be an APCS requirement for instance. 2. For efficiency. By promoting the argument at expansion time we don't have to keep promoting the type back and forth after each operation on it. i.e. the promotion simplies the RTL. This patch adds the ability for a target to decide whether during the expansion to use an extend to handle promotion or to use a paradoxical subreg. A pradoxical subreg can be used when there's no correctness issues and when you still want the RTL efficiency of not doing the promotion constantly. This also allows the target to not need to generate any code when the top bits are not significant. An example is in AArch64 the following extend is unneeded: uint8_t fd2 (uint8_t xr){ return xr + 1; } currently generates: fd2: and w0, w0, 255 add w0, w0, 1 ret instead of fd2: add w0, w0, #1 ret Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. Bootstrapped on x86_64-pc-linux-gnu and no issues Ok for master? Thanks, Tamar gcc/ChangeLog: * cfgexpand.cc (set_rtl): Check for function promotion. * tree-outof-ssa.cc (insert_value_copy_on_edge): Likewise. * function.cc (assign_parm_setup_reg): Likewise. * hooks.cc (hook_bool_mode_mode_int_tree_false, hook_bool_mode_mode_int_tree_true): New. * hooks.h (hook_bool_mode_mode_int_tree_false, hook_bool_mode_mode_int_tree_true): New. * target.def (promote_function_args_subreg_p): New. * doc/tm.texi: Document it. * doc/tm.texi.in: Likewise. --- inline copy of patch -- diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc index d3cc77d2ca98f620b29623fc5696410bad9bc184..df95184cfa185312c2a46cb92daa051718d9f4f3 100644 --- diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc index d3cc77d2ca98f620b29623fc5696410bad9bc184..df95184cfa185312c2a46cb92daa051718d9f4f3 100644 --- a/gcc/cfgexpand.cc +++ b/gcc/cfgexpand.cc @@ -206,14 +206,20 @@ set_rtl (tree t, rtx x) have to compute it ourselves. For RESULT_DECLs, we accept mode mismatches too, as long as we have BLKmode or are not coalescing across variables, so that we don't reject BLKmode PARALLELs or - unpromoted REGs. */ + unpromoted REGs. For any promoted types that result in a + paradoxical subreg also accept the argument. */ gcc_checking_assert (!x || x == pc_rtx || TREE_CODE (t) != SSA_NAME || (SSAVAR (t) && TREE_CODE (SSAVAR (t)) == RESULT_DECL && (promote_ssa_mode (t, NULL) == BLKmode || !flag_tree_coalesce_vars)) || !use_register_for_decl (t) - || GET_MODE (x) == promote_ssa_mode (t, NULL)); + || GET_MODE (x) == promote_ssa_mode (t, NULL) + || targetm.calls.promote_function_args_subreg_p ( + GET_MODE (x), + promote_ssa_mode (t, NULL), + TYPE_UNSIGNED (TREE_TYPE (t)), + SSAVAR (t))); if (x) { diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 2f92d37da8c0091e9879a493cfe8a361eb1d9299..6314cd83a2488dc225d4a1a15599e8e51e639f7f 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -3906,6 +3906,15 @@ cases of mismatch, it also makes for better code on certain machines. The default is to not promote prototypes. @end deftypefn +@deftypefn {Target Hook} bool TARGET_PROMOTE_FUNCTION_ARGS_SUBREG_P (machine_mode @var{mode}, machine_mode @var{promoted_mode}, int @var{unsignedp}, tree @var{v}) +When a function argument is promoted with @code{PROMOTE_MODE} then this +hook is used to determine whether the bits of the promoted type are all +significant in the expression pointed to by V. If they are an extend is +generated, if they are not a paradoxical subreg is created for the argument +from @code{mode} to @code{promoted_mode}. +The default is to promote using an extend. +@end deftypefn + @deftypefn {Target Hook} bool TARGET_PUSH_ARGUMENT (unsigned int @var{npush}) This target hook returns @code{true} if push instructions will be used to pass outgoing arguments. When the push instruction usage is diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index f869ddd5e5b8b7acbd8e9765fb103af24a1085b6..35f955803ec0a5a93be18a028fa1043f90858982 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3103,6 +3103,8 @@ control passing certain arguments in registers. @hook TARGET_PROMOTE_PROTOTYPES +@hook TARGET_PROMOTE_FUNCTION_ARGS_SUBREG_P + @hook TARGET_PUSH_ARGUMENT @defmac PUSH_ARGS_REVERSED diff --git a/gcc/function.cc b/gcc/function.cc index d5ed51a6a663a1ef472f5b1c090543f359c18f42..92f469bfd5d1ebfb09cc94d9be854715cd2f90f8 100644 --- a/gcc/function.cc +++ b/gcc/function.cc @@ -3161,7 +3161,7 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, machine_mode promoted_nominal_mode; int unsignedp = TYPE_UNSIGNED (TREE_TYPE (parm)); bool did_conversion = false; - bool need_conversion, moved; + bool need_conversion, moved, use_subregs; enum insn_code icode; rtx rtl; @@ -3172,7 +3172,20 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, = promote_function_mode (data->nominal_type, data->nominal_mode, &unsignedp, TREE_TYPE (current_function_decl), 2); - parmreg = gen_reg_rtx (promoted_nominal_mode); + /* Check to see how the target wants the promotion of function arguments to + be handled. */ + use_subregs + = targetm.calls.promote_function_args_subreg_p (data->nominal_mode, + promoted_nominal_mode, + unsignedp, parm); + + /* If we're promoting using a paradoxical subreg then we need to keep using + the unpromoted type because that's the only fully defined value. */ + if (use_subregs) + parmreg = gen_reg_rtx (data->nominal_mode); + else + parmreg = gen_reg_rtx (promoted_nominal_mode); + if (!DECL_ARTIFICIAL (parm)) mark_user_reg (parmreg); @@ -3256,9 +3269,19 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, } else t = op1; - rtx_insn *pat = gen_extend_insn (op0, t, promoted_nominal_mode, - data->passed_mode, unsignedp); - emit_insn (pat); + + /* Promote the argument itself now if a target wants it. This + prevents unneeded back and forth convertions in RTL between + the original and promoted type. */ + if (use_subregs) + emit_move_insn (op0, lowpart_subreg (promoted_nominal_mode, t, + data->nominal_mode)); + else + { + rtx_insn *pat = gen_extend_insn (op0, t, promoted_nominal_mode, + data->passed_mode, unsignedp); + emit_insn (pat); + } insns = get_insns (); moved = true; diff --git a/gcc/hooks.h b/gcc/hooks.h index 1056e1e9e4dc3e6ce298557351047caa2f84227f..8d68de5cdb9adaea0a79ebf6de599f66b40aa67a 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -31,6 +31,8 @@ extern bool hook_bool_const_int_const_int_true (const int, const int); extern bool hook_bool_mode_false (machine_mode); extern bool hook_bool_mode_true (machine_mode); extern bool hook_bool_mode_mode_true (machine_mode, machine_mode); +extern bool hook_bool_mode_mode_int_tree_false (machine_mode, machine_mode, int, tree); +extern bool hook_bool_mode_mode_int_tree_true (machine_mode, machine_mode, int, tree); extern bool hook_bool_mode_const_rtx_false (machine_mode, const_rtx); extern bool hook_bool_mode_const_rtx_true (machine_mode, const_rtx); extern bool hook_bool_mode_rtx_false (machine_mode, rtx); diff --git a/gcc/hooks.cc b/gcc/hooks.cc index b29233f4f852fb81ede75a5065d743cd16cc9219..7647774f9e8efbbe13d5607e4a4b2f1c9d22f045 100644 --- a/gcc/hooks.cc +++ b/gcc/hooks.cc @@ -89,6 +89,22 @@ hook_bool_mode_mode_true (machine_mode, machine_mode) return true; } +/* Generic hook that takes (machine_mode, machine_mode, int, tree) and + returns false. */ +bool +hook_bool_mode_mode_int_tree_false (machine_mode, machine_mode, int, tree) +{ + return false; +} + +/* Generic hook that takes (machine_mode, machine_mode, int, tree) and + returns true. */ +bool +hook_bool_mode_mode_int_tree_true (machine_mode, machine_mode, int, tree) +{ + return true; +} + /* Generic hook that takes (machine_mode, const_rtx) and returns false. */ bool hook_bool_mode_const_rtx_false (machine_mode, const_rtx) diff --git a/gcc/target.def b/gcc/target.def index 72c2e1ef756cf70a1c92abe81f8a6577eaaa2501..bdbacf8c5fd7b0626a37951f6f6ec649f3194977 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4561,6 +4561,17 @@ The default is to not promote prototypes.", bool, (const_tree fntype), hook_bool_const_tree_false) +DEFHOOK +(promote_function_args_subreg_p, + "When a function argument is promoted with @code{PROMOTE_MODE} then this\n\ +hook is used to determine whether the bits of the promoted type are all\n\ +significant in the expression pointed to by V. If they are an extend is\n\ +generated, if they are not a paradoxical subreg is created for the argument\n\ +from @code{mode} to @code{promoted_mode}.\n\ +The default is to promote using an extend.", + bool, (machine_mode mode, machine_mode promoted_mode, int unsignedp, tree v), + hook_bool_mode_mode_int_tree_false) + DEFHOOK (struct_value_rtx, "This target hook should return the location of the structure value\n\ diff --git a/gcc/tree-outof-ssa.cc b/gcc/tree-outof-ssa.cc index ec883126ad86d86a2c2dafee4592b8d83e2ed917..0f437023983baa0f23da25221f7bce8fc559a8b8 100644 --- a/gcc/tree-outof-ssa.cc +++ b/gcc/tree-outof-ssa.cc @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-coalesce.h" #include "tree-outof-ssa.h" #include "dojump.h" +#include "target.h" /* FIXME: A lot of code here deals with expanding to RTL. All that code should be in cfgexpand.cc. */ @@ -333,7 +334,10 @@ insert_value_copy_on_edge (edge e, int dest, tree src, location_t locus) dest_mode = GET_MODE (dest_rtx); gcc_assert (src_mode == TYPE_MODE (TREE_TYPE (name))); gcc_assert (!REG_P (dest_rtx) - || dest_mode == promote_ssa_mode (name, &unsignedp)); + || dest_mode == promote_ssa_mode (name, &unsignedp) + || targetm.calls.promote_function_args_subreg_p ( + dest_mode, promote_ssa_mode (name, NULL), unsignedp, + name)); if (src_mode != dest_mode) { --- a/gcc/cfgexpand.cc +++ b/gcc/cfgexpand.cc @@ -206,14 +206,20 @@ set_rtl (tree t, rtx x) have to compute it ourselves. For RESULT_DECLs, we accept mode mismatches too, as long as we have BLKmode or are not coalescing across variables, so that we don't reject BLKmode PARALLELs or - unpromoted REGs. */ + unpromoted REGs. For any promoted types that result in a + paradoxical subreg also accept the argument. */ gcc_checking_assert (!x || x == pc_rtx || TREE_CODE (t) != SSA_NAME || (SSAVAR (t) && TREE_CODE (SSAVAR (t)) == RESULT_DECL && (promote_ssa_mode (t, NULL) == BLKmode || !flag_tree_coalesce_vars)) || !use_register_for_decl (t) - || GET_MODE (x) == promote_ssa_mode (t, NULL)); + || GET_MODE (x) == promote_ssa_mode (t, NULL) + || targetm.calls.promote_function_args_subreg_p ( + GET_MODE (x), + promote_ssa_mode (t, NULL), + TYPE_UNSIGNED (TREE_TYPE (t)), + SSAVAR (t))); if (x) { diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 2f92d37da8c0091e9879a493cfe8a361eb1d9299..6314cd83a2488dc225d4a1a15599e8e51e639f7f 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -3906,6 +3906,15 @@ cases of mismatch, it also makes for better code on certain machines. The default is to not promote prototypes. @end deftypefn +@deftypefn {Target Hook} bool TARGET_PROMOTE_FUNCTION_ARGS_SUBREG_P (machine_mode @var{mode}, machine_mode @var{promoted_mode}, int @var{unsignedp}, tree @var{v}) +When a function argument is promoted with @code{PROMOTE_MODE} then this +hook is used to determine whether the bits of the promoted type are all +significant in the expression pointed to by V. If they are an extend is +generated, if they are not a paradoxical subreg is created for the argument +from @code{mode} to @code{promoted_mode}. +The default is to promote using an extend. +@end deftypefn + @deftypefn {Target Hook} bool TARGET_PUSH_ARGUMENT (unsigned int @var{npush}) This target hook returns @code{true} if push instructions will be used to pass outgoing arguments. When the push instruction usage is diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index f869ddd5e5b8b7acbd8e9765fb103af24a1085b6..35f955803ec0a5a93be18a028fa1043f90858982 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3103,6 +3103,8 @@ control passing certain arguments in registers. @hook TARGET_PROMOTE_PROTOTYPES +@hook TARGET_PROMOTE_FUNCTION_ARGS_SUBREG_P + @hook TARGET_PUSH_ARGUMENT @defmac PUSH_ARGS_REVERSED diff --git a/gcc/function.cc b/gcc/function.cc index d5ed51a6a663a1ef472f5b1c090543f359c18f42..92f469bfd5d1ebfb09cc94d9be854715cd2f90f8 100644 --- a/gcc/function.cc +++ b/gcc/function.cc @@ -3161,7 +3161,7 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, machine_mode promoted_nominal_mode; int unsignedp = TYPE_UNSIGNED (TREE_TYPE (parm)); bool did_conversion = false; - bool need_conversion, moved; + bool need_conversion, moved, use_subregs; enum insn_code icode; rtx rtl; @@ -3172,7 +3172,20 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, = promote_function_mode (data->nominal_type, data->nominal_mode, &unsignedp, TREE_TYPE (current_function_decl), 2); - parmreg = gen_reg_rtx (promoted_nominal_mode); + /* Check to see how the target wants the promotion of function arguments to + be handled. */ + use_subregs + = targetm.calls.promote_function_args_subreg_p (data->nominal_mode, + promoted_nominal_mode, + unsignedp, parm); + + /* If we're promoting using a paradoxical subreg then we need to keep using + the unpromoted type because that's the only fully defined value. */ + if (use_subregs) + parmreg = gen_reg_rtx (data->nominal_mode); + else + parmreg = gen_reg_rtx (promoted_nominal_mode); + if (!DECL_ARTIFICIAL (parm)) mark_user_reg (parmreg); @@ -3256,9 +3269,19 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, } else t = op1; - rtx_insn *pat = gen_extend_insn (op0, t, promoted_nominal_mode, - data->passed_mode, unsignedp); - emit_insn (pat); + + /* Promote the argument itself now if a target wants it. This + prevents unneeded back and forth convertions in RTL between + the original and promoted type. */ + if (use_subregs) + emit_move_insn (op0, lowpart_subreg (promoted_nominal_mode, t, + data->nominal_mode)); + else + { + rtx_insn *pat = gen_extend_insn (op0, t, promoted_nominal_mode, + data->passed_mode, unsignedp); + emit_insn (pat); + } insns = get_insns (); moved = true; diff --git a/gcc/hooks.h b/gcc/hooks.h index 1056e1e9e4dc3e6ce298557351047caa2f84227f..8d68de5cdb9adaea0a79ebf6de599f66b40aa67a 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -31,6 +31,8 @@ extern bool hook_bool_const_int_const_int_true (const int, const int); extern bool hook_bool_mode_false (machine_mode); extern bool hook_bool_mode_true (machine_mode); extern bool hook_bool_mode_mode_true (machine_mode, machine_mode); +extern bool hook_bool_mode_mode_int_tree_false (machine_mode, machine_mode, int, tree); +extern bool hook_bool_mode_mode_int_tree_true (machine_mode, machine_mode, int, tree); extern bool hook_bool_mode_const_rtx_false (machine_mode, const_rtx); extern bool hook_bool_mode_const_rtx_true (machine_mode, const_rtx); extern bool hook_bool_mode_rtx_false (machine_mode, rtx); diff --git a/gcc/hooks.cc b/gcc/hooks.cc index b29233f4f852fb81ede75a5065d743cd16cc9219..7647774f9e8efbbe13d5607e4a4b2f1c9d22f045 100644 --- a/gcc/hooks.cc +++ b/gcc/hooks.cc @@ -89,6 +89,22 @@ hook_bool_mode_mode_true (machine_mode, machine_mode) return true; } +/* Generic hook that takes (machine_mode, machine_mode, int, tree) and + returns false. */ +bool +hook_bool_mode_mode_int_tree_false (machine_mode, machine_mode, int, tree) +{ + return false; +} + +/* Generic hook that takes (machine_mode, machine_mode, int, tree) and + returns true. */ +bool +hook_bool_mode_mode_int_tree_true (machine_mode, machine_mode, int, tree) +{ + return true; +} + /* Generic hook that takes (machine_mode, const_rtx) and returns false. */ bool hook_bool_mode_const_rtx_false (machine_mode, const_rtx) diff --git a/gcc/target.def b/gcc/target.def index 72c2e1ef756cf70a1c92abe81f8a6577eaaa2501..bdbacf8c5fd7b0626a37951f6f6ec649f3194977 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4561,6 +4561,17 @@ The default is to not promote prototypes.", bool, (const_tree fntype), hook_bool_const_tree_false) +DEFHOOK +(promote_function_args_subreg_p, + "When a function argument is promoted with @code{PROMOTE_MODE} then this\n\ +hook is used to determine whether the bits of the promoted type are all\n\ +significant in the expression pointed to by V. If they are an extend is\n\ +generated, if they are not a paradoxical subreg is created for the argument\n\ +from @code{mode} to @code{promoted_mode}.\n\ +The default is to promote using an extend.", + bool, (machine_mode mode, machine_mode promoted_mode, int unsignedp, tree v), + hook_bool_mode_mode_int_tree_false) + DEFHOOK (struct_value_rtx, "This target hook should return the location of the structure value\n\ diff --git a/gcc/tree-outof-ssa.cc b/gcc/tree-outof-ssa.cc index ec883126ad86d86a2c2dafee4592b8d83e2ed917..0f437023983baa0f23da25221f7bce8fc559a8b8 100644 --- a/gcc/tree-outof-ssa.cc +++ b/gcc/tree-outof-ssa.cc @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-coalesce.h" #include "tree-outof-ssa.h" #include "dojump.h" +#include "target.h" /* FIXME: A lot of code here deals with expanding to RTL. All that code should be in cfgexpand.cc. */ @@ -333,7 +334,10 @@ insert_value_copy_on_edge (edge e, int dest, tree src, location_t locus) dest_mode = GET_MODE (dest_rtx); gcc_assert (src_mode == TYPE_MODE (TREE_TYPE (name))); gcc_assert (!REG_P (dest_rtx) - || dest_mode == promote_ssa_mode (name, &unsignedp)); + || dest_mode == promote_ssa_mode (name, &unsignedp) + || targetm.calls.promote_function_args_subreg_p ( + dest_mode, promote_ssa_mode (name, NULL), unsignedp, + name)); if (src_mode != dest_mode) {