From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mxout.security-mail.net (mxout.security-mail.net [85.31.212.43]) by sourceware.org (Postfix) with ESMTPS id E56343858C2A for ; Tue, 12 Sep 2023 10:07:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E56343858C2A Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=kalrayinc.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=kalrayinc.com Received: from localhost (fx303.security-mail.net [127.0.0.1]) by fx303.security-mail.net (Postfix) with ESMTP id C799C30EF4E for ; Tue, 12 Sep 2023 12:07:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kalrayinc.com; s=sec-sig-email; t=1694513250; bh=wHo1bmr3IzdE+g8Br+EnRrfRN2vVm/Xr/wzPWg2EtL8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=FvS9rR/lmo7doTT/L1wgdJbKdWg4GaYjR4AtWloeoKH2VU3l9hhXXh8F6mpQ9stOv hETDeWy6JX1zr3jhXqxyrJrw/XB8c/NML+4ApewZmE5DBx1ndK4/KQYZMyHejJ7EJZ fE2a66AdEfwsDbhn46qEExSg/8B+cxAetwHGKAdY= Received: from fx303 (fx303.security-mail.net [127.0.0.1]) by fx303.security-mail.net (Postfix) with ESMTP id A0CB230ED41 for ; Tue, 12 Sep 2023 12:07:30 +0200 (CEST) Received: from FRA01-MR2-obe.outbound.protection.outlook.com (mail-mr2fra01lp0107.outbound.protection.outlook.com [104.47.25.107]) by fx303.security-mail.net (Postfix) with ESMTPS id 61FCB30ED2D for ; Tue, 12 Sep 2023 12:07:29 +0200 (CEST) Received: from PR1P264MB3448.FRAP264.PROD.OUTLOOK.COM (2603:10a6:102:184::6) by MRZP264MB2442.FRAP264.PROD.OUTLOOK.COM (2603:10a6:501:7::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6768.35; Tue, 12 Sep 2023 10:07:27 +0000 Received: from PR1P264MB3448.FRAP264.PROD.OUTLOOK.COM ([fe80::ad9:f173:8a66:3461]) by PR1P264MB3448.FRAP264.PROD.OUTLOOK.COM ([fe80::ad9:f173:8a66:3461%7]) with mapi id 15.20.6768.029; Tue, 12 Sep 2023 10:07:27 +0000 X-Virus-Scanned: E-securemail Secumail-id: <8b24.65003861.61145.0> ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Wg/JHPFQMW9TUVw3sKFXd0aMxlGwxRdFLRqawLxumL7dJcCB48Y0wvuIY31QnWl+B3ioCRlD4A5aQAxBiB4T/N5pXcHCuc3evjTewugNqp+eXs2t6A7gdapPiW2iZWdH4gSU/xP+QJ4M5cnyH/bG3oA3vW8ixVVpciKuBNJ1c9kzK1Z3FYyJBS0o6bx2SAkwyWZF9bpKmDINmiOH25saeYNIoXi/osR7DaglLV0OcfXh0kJ8IJoLOAUN3pJyeCr/sBlIKuUbhrKGc9v2lztW0+zWXUV6qe2oubR0xOUIqt8uiinORpBeMXGuB09nNUQ2Lh0eXHlyQPUfSYpnRA16Lg== 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=ziSU5xSauICmW21GhO5kC5mwCotL8cp7sIMji9wtSAU=; b=CHQL+dzNo3YAtB7mUtvfOwUazBrLDVqVdcPqzZeFwgy3vFS+kGHzGU2AjgjX5wu5lppxbVk4e8ygrp1TdyFQBq0kY21gE/BsAzdby5lmZPhrBfmTY5NNfddVt+vJ9PGcP31HWekyf1u25SpShy/IUfF8jSFZFtWPIrQdILhTnoG8Q0476/gVKJ/k6BzAzoOBWi4Quh57Vr2RD/XtOlymsHXWJAEqu0j6YH0/hhr7FEVqCDwUAdd5JwbmgBLPHO0kAkEmU14tYHD7/cpZp7Ob9Dio2nwnMO1NxM2bwp0pnhP+5YlXhIWhoVRF5mrwy7irLHN0naZlbyxPxMnxJBebYQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=kalrayinc.com; dmarc=pass action=none header.from=kalrayinc.com; dkim=pass header.d=kalrayinc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kalrayinc.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ziSU5xSauICmW21GhO5kC5mwCotL8cp7sIMji9wtSAU=; b=For1SffAICkAb6sJW4gsppT3eimzOevvZCnYpLDl9rD36N+YCHDdhqqCwRNLYJdAOVaAv9eJEUachYlaUa3TygyuZ2ncyj3pMvA2IgDTJOyIltmj7Xs8DW0Z4TXebJaxh8j0bQ80J6EZ+W++Q6/6D/OU5iJr8HGWhtyzEzADsXb5pWrRHIT8V1kivcdBCYwUyGlbuuZ1o9+bJ0kEQK+SshrB7on+0egijFMM9mYpnegveFJq4uZb0P/pW1dmeqeKhzMl9dAkFfM85nGBQEBDUrtiWNfUI1+dO9ZyX1uDk9N0tyJTWmZGEvP7lbMZALrsLP4Zay6Xt9b2cwoR7wXPeA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=kalrayinc.com; From: Sylvain Noiry To: gcc-patches@gcc.gnu.org Cc: Sylvain Noiry Subject: [PATCH v2 01/11] Native complex ops : Conditional lowering Date: Tue, 12 Sep 2023 12:07:03 +0200 Message-ID: <20230912100713.1074-2-snoiry@kalrayinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230912100713.1074-1-snoiry@kalrayinc.com> References: <20230717090250.4645-10-snoiry@kalrayinc.com> <20230912100713.1074-1-snoiry@kalrayinc.com> X-ClientProxiedBy: LNXP123CA0004.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:d2::16) To PR1P264MB3448.FRAP264.PROD.OUTLOOK.COM (2603:10a6:102:184::6) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PR1P264MB3448:EE_|MRZP264MB2442:EE_ X-MS-Office365-Filtering-Correlation-Id: 9de627ad-74da-4714-b771-08dbb378117e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: mYwWSVaYRvR8ZoPhypFRpxID9zNuUmD8YPY8yC+ZtTCdgl61pdizl8I+PUdXc6hE6SvLcqUrk63S807p6OSnlNbHDoDhTKe/hfAovl+JpKLXeHoBvLJeErIsTrPE75HebtzFSfbWUaVgR3ryXtOArFXP7bkXrkJXtRXROv2wJ1+BFYNMilEv9YOq57JbzVkJExOKrXE0iKFESJ3uY/dDbAU9v+wYTGGTTh3fTZxadPSbbg2gBVo5O3u6SpP6g2cDcZIIQWJCiyMyQ/P4cO0CoMg5MkQBuC8RUv9CbtMKwYvLshiO4X3eZLPNk/MMZe4dy0/l376EKMkoDN8PAS0RUUFo6CT5DwPV8bhVjTx6zWcuCJYORKpBSVr6Y+z3oXW6AWz3pc1sH3VKicTfpxSNM2q9a09MvCUULq3B1AHwvcsPhf00sO1OgEmx3p8MAO+3QxG05FVsuqgW0m6CmCAjBcAKGIYKWXn1COveLgIYSetSKuAdiq0t8xV6gc/kFz1HWH0rIIXj+j4IGN3Z89FMJOJhdWfJ6nZvBS2aFm93aj1RlDgiF9yPM0VPcyzX1w4f X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PR1P264MB3448.FRAP264.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230031)(136003)(366004)(376002)(346002)(396003)(39860400002)(451199024)(186009)(1800799009)(1076003)(107886003)(2616005)(5660300002)(4326008)(8936002)(8676002)(6512007)(26005)(6486002)(6666004)(6506007)(83380400001)(66476007)(66556008)(66946007)(38100700002)(478600001)(41300700001)(6916009)(316002)(36756003)(86362001)(30864003)(2906002);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: I5KlsipHN3b3I0BsXSvMbIn+150mcnQcQlSLYX3PT7D4bGSwj4K2UUeW2JfR7NREsO6KS9epbB9i7mvIk5442H5t+jCenAAxvkMlya24Hd/npmbnP2gcknqmPnMSSy9ydA/0WCjZisVDfBltuSUJWt5E+sRM1rv1bI6LVj7LYPHOQ1IuiU/RYZjev7wQmmCSAB/hZBr0LuZFWDcZ+y8tqChrAYphDnfA55+hboKd4YktArgjBwnC7uAj+ZgzIcyNUOA1FsvgQg+m13fmo5xYCRe/rGqAhLyGtSZ4M8H4EEsXxlWrsVuJ1u5YIGEJ58sf1S6tPriJv2aTozgFZZBzDnvTqP3HSeUD+XhXiat5/doSLa4VOdtbrrpsTczhza0BvFHovGfi4A9hdQCHDi1ZujSW1v1oSb31TJ6mZo2sbUBPYwpyWwi1/ZTqOdqoyA+hCsCo5P8Iv0OUo6aF2Wu1ZA2aZUHuP8su0Zh/DC64VdJPpspybs9aXVOVHk7q4OlR/lIp/KMMq2i/rmtDUJHDU61ZSkSUvmhoAnN8Qh/THYTov0LZsiHRK/SSO6KddATEDQFGJ1//MmcSP5R14LeMVH0hdCVMsIrhb/MKvzIE78A9vbGSnGCKnCESUw/fOANb4aB+8XU1jWygLVlG9WcFCGL8ua4V8TeCe0ylI5RApcHN59ZhrEWQ53tQ4ZQ6Rvs7R2VRFqd3v7Lkf5SuJK1leu+2BQ2nuHukQRnvJMVTrZN/brWGGqeGjTVp1Ys5jLVEcR8HPaok5p+pbgAVxDQVrrxuqFi3MnjHvHqWUzElYLi3NugfLyOmpxFgW4aLrc4XXq5ur8gTfTXqiG4HMx724EK47ly3L4NvOfxAfPsYmWZgdYk2F8e1LztQBu9ayzAFlXNS3254yGJTX4XO5oRF0n0oD+1fzDni63v+wJlJgaL6IZAnvXHaMAMAtrScNVXe 8JFjVUb81V4/EJoXEv7003duTFeValQwRtECPqzcRjcL3gVOatyEB5Eoa4uDA0oZLEy3fE/PckdSFvfhTpYnTaibu3gOaO52dt7/qpHT/eGmBpb63KL+t0YEz5xC7aU84LDj1MuTgHR9XMrGHPy88t2h2xBOKcPGhXRjFy5bOGPxNebvvmYxe34vWDabqby52lEJxx0bQ1FSEG+1mkXAxNyYwtkvthfyNSjeG2u9Ds9s1CkUompPliX3wmUi5wzLXof5uzELrs/7yRJOO4YLaCOPEgMpb50gJJCYrtb+9bbAQlE4WKNVMEKI3mS5Xh/6EHCcf9tbLZhi64wuMzhzd/PLbdnYCbe/L9lv9BiDcqG8t0j7M0/NckN8xx3PYbD3bUgdWScv5RssC8x/UGIItbUKPq6r7BBTWY0gydj2x1ObI0QBFoiOUXtaD3Wcv+CiIeyOWxcosEbbqgfWW2KSs4vPXM4F6eKn9Iz+jgi3b4lgt4EROLog7YVCQjabcVHg58k+PCJCHzwS9YlYSoPB1XWndi+8Xm4U8bxAxGmJY6GhxY/V69ZM1qfKt/+iiaW9y8zPXmmFPz1gveDmps16ec+PcHesTtGI9vcPib8UtBFngQumL2t6Pjl9hp830WkFK2A4ZDaK6+TQlniwyV2Keg== X-OriginatorOrg: kalrayinc.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9de627ad-74da-4714-b771-08dbb378117e X-MS-Exchange-CrossTenant-AuthSource: PR1P264MB3448.FRAP264.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Sep 2023 10:07:27.5135 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8931925d-7620-4a64-b7fe-20afd86363d3 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: hpfrOYrZ3MmhUFaddFi1zxBlFQZuXO3YojrMc5j0U7BLcJFkrhm0zrYQ1/pu9KwqMWOBoEwb0ihOBl1A4pdHtQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MRZP264MB2442 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-ALTERMIMEV2_out: done X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_ASCII_DIVIDERS,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Summary: Allow the cplxlower pass to identify if an operation does not need to be lowered through optabs. In this case, lowering is not performed. The cplxlower pass now has to handle a mix of lowered and non-lowered operations. A quick access to both parts of a complex constant is also implemented. gcc/lto/ChangeLog: * lto-common.cc (compare_tree_sccs_1): Handle both parts of a complex constant gcc/ChangeLog: * coretypes.h: Add enum for complex parts * gensupport.cc (match_pattern): Add complex types * lto-streamer-out.cc (DFS::DFS_write_tree_body): (hash_tree): Handle both parts of a complex constant * tree-complex.cc (get_component_var): Support handling of both parts of a complex (get_component_ssa_name): Likewise (set_component_ssa_name): Likewise (extract_component): Likewise (update_complex_components): Likewise (update_complex_components_on_edge): Likewise (update_complex_assignment): Likewise (update_phi_components): Likewise (expand_complex_move): Likewise (expand_complex_asm): Update with complex_part_t (complex_component_cst_p): New: check if a complex component is a constant (target_native_complex_operation): New: Check if complex operation is supported natively by the backend, through the optab (expand_complex_operations_1): Condionally lowered ops (tree_lower_complex): Support handling of both parts of a complex * tree-core.h (struct GTY): Add field for both parts of the tree_complex struct * tree-streamer-in.cc (lto_input_ts_complex_tree_pointers): Handle both parts of a complex constant * tree-streamer-out.cc (write_ts_complex_tree_pointers): Likewise * tree.cc (build_complex): likewise * tree.h (class auto_suppress_location_wrappers): (type_has_mode_precision_p): Add special case for complex * tree-dfa.cc (get_ref_base_and_extent): Handle REALPART_EXPR and IMAGPART_EXPR --- gcc/coretypes.h | 11 ++ gcc/gensupport.cc | 2 + gcc/lto-streamer-out.cc | 2 + gcc/lto/lto-common.cc | 2 + gcc/tree-complex.cc | 401 ++++++++++++++++++++++++++++++--------- gcc/tree-core.h | 1 + gcc/tree-dfa.cc | 3 + gcc/tree-streamer-in.cc | 1 + gcc/tree-streamer-out.cc | 1 + gcc/tree.cc | 8 + gcc/tree.h | 15 +- 11 files changed, 358 insertions(+), 89 deletions(-) diff --git a/gcc/coretypes.h b/gcc/coretypes.h index f86dc169a40..76f49f25cad 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -448,6 +448,17 @@ enum optimize_size_level OPTIMIZE_SIZE_MAX }; +/* Part of a complex. */ + +enum complex_part_e +{ + REAL_P = 0, + IMAG_P = 1, + BOTH_P = 2 +}; + +typedef enum complex_part_e complex_part_t; + /* Support for user-provided GGC and PCH markers. The first parameter is a pointer to a pointer, the second either NULL if the pointer to pointer points into a GC object or the actual pointer address if diff --git a/gcc/gensupport.cc b/gcc/gensupport.cc index f7164b3214d..54f7b3cfe81 100644 --- a/gcc/gensupport.cc +++ b/gcc/gensupport.cc @@ -3746,9 +3746,11 @@ match_pattern (optab_pattern *p, const char *name, const char *pat) break; if (*p == 0 && (! force_int || mode_class[i] == MODE_INT + || mode_class[i] == MODE_COMPLEX_INT || mode_class[i] == MODE_VECTOR_INT) && (! force_partial_int || mode_class[i] == MODE_INT + || mode_class[i] == MODE_COMPLEX_INT || mode_class[i] == MODE_PARTIAL_INT || mode_class[i] == MODE_VECTOR_INT) && (! force_float diff --git a/gcc/lto-streamer-out.cc b/gcc/lto-streamer-out.cc index 5ffa8954022..38c48e44867 100644 --- a/gcc/lto-streamer-out.cc +++ b/gcc/lto-streamer-out.cc @@ -985,6 +985,7 @@ DFS::DFS_write_tree_body (struct output_block *ob, { DFS_follow_tree_edge (TREE_REALPART (expr)); DFS_follow_tree_edge (TREE_IMAGPART (expr)); + DFS_follow_tree_edge (TREE_COMPLEX_BOTH_PARTS (expr)); } if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL)) @@ -1417,6 +1418,7 @@ hash_tree (struct streamer_tree_cache_d *cache, hash_map *map, { visit (TREE_REALPART (t)); visit (TREE_IMAGPART (t)); + visit (TREE_COMPLEX_BOTH_PARTS (t)); } if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL)) diff --git a/gcc/lto/lto-common.cc b/gcc/lto/lto-common.cc index 703e665b698..f647ee62f9e 100644 --- a/gcc/lto/lto-common.cc +++ b/gcc/lto/lto-common.cc @@ -1408,6 +1408,8 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map) { compare_tree_edges (TREE_REALPART (t1), TREE_REALPART (t2)); compare_tree_edges (TREE_IMAGPART (t1), TREE_IMAGPART (t2)); + compare_tree_edges (TREE_COMPLEX_BOTH_PARTS (t1), + TREE_COMPLEX_BOTH_PARTS (t2)); } if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL)) diff --git a/gcc/tree-complex.cc b/gcc/tree-complex.cc index 688fe13989c..d889a99d513 100644 --- a/gcc/tree-complex.cc +++ b/gcc/tree-complex.cc @@ -42,6 +42,10 @@ along with GCC; see the file COPYING3. If not see #include "cfganal.h" #include "gimple-fold.h" #include "diagnostic-core.h" +#include "target.h" +#include "memmodel.h" +#include "optabs-tree.h" +#include "internal-fn.h" /* For each complex ssa name, a lattice value. We're interested in finding @@ -74,7 +78,7 @@ static vec complex_lattice_values; the hashtable. */ static int_tree_htab_type *complex_variable_components; -/* For each complex SSA_NAME, a pair of ssa names for the components. */ +/* For each complex SSA_NAME, three ssa names for the components. */ static vec complex_ssa_name_components; /* Vector of PHI triplets (original complex PHI and corresponding real and @@ -476,17 +480,27 @@ create_one_component_var (tree type, tree orig, const char *prefix, /* Retrieve a value for a complex component of VAR. */ static tree -get_component_var (tree var, bool imag_p) +get_component_var (tree var, complex_part_t part) { - size_t decl_index = DECL_UID (var) * 2 + imag_p; + size_t decl_index = DECL_UID (var) * 3 + part; tree ret = cvc_lookup (decl_index); if (ret == NULL) { - ret = create_one_component_var (TREE_TYPE (TREE_TYPE (var)), var, - imag_p ? "CI" : "CR", - imag_p ? "$imag" : "$real", - imag_p ? IMAGPART_EXPR : REALPART_EXPR); + switch (part) + { + case REAL_P: + ret = create_one_component_var (TREE_TYPE (TREE_TYPE (var)), var, + "CR", "$real", REALPART_EXPR); + break; + case IMAG_P: + ret = create_one_component_var (TREE_TYPE (TREE_TYPE (var)), var, + "CI", "$imag", IMAGPART_EXPR); + break; + case BOTH_P: + ret = var; + break; + } cvc_insert (decl_index, ret); } @@ -496,13 +510,15 @@ get_component_var (tree var, bool imag_p) /* Retrieve a value for a complex component of SSA_NAME. */ static tree -get_component_ssa_name (tree ssa_name, bool imag_p) +get_component_ssa_name (tree ssa_name, complex_part_t part) { complex_lattice_t lattice = find_lattice_value (ssa_name); size_t ssa_name_index; tree ret; - if (lattice == (imag_p ? ONLY_REAL : ONLY_IMAG)) + if (((lattice == ONLY_IMAG) && (part == REAL_P)) + || ((lattice == ONLY_REAL) && (part == IMAG_P))) + { tree inner_type = TREE_TYPE (TREE_TYPE (ssa_name)); if (SCALAR_FLOAT_TYPE_P (inner_type)) @@ -511,14 +527,33 @@ get_component_ssa_name (tree ssa_name, bool imag_p) return build_int_cst (inner_type, 0); } - ssa_name_index = SSA_NAME_VERSION (ssa_name) * 2 + imag_p; + if (part == BOTH_P) + return ssa_name; + + ssa_name_index = SSA_NAME_VERSION (ssa_name) * 3 + part; + unsigned length = complex_ssa_name_components.length (); + + /* Increase size of dynamic array if needed. */ + if (ssa_name_index >= length) + { + size_t new_size = 2 * length; + complex_ssa_name_components.safe_grow_cleared (new_size, true); + complex_lattice_values.safe_grow_cleared (new_size, true); + } + ret = complex_ssa_name_components[ssa_name_index]; if (ret == NULL) { if (SSA_NAME_VAR (ssa_name)) - ret = get_component_var (SSA_NAME_VAR (ssa_name), imag_p); + ret = get_component_var (SSA_NAME_VAR (ssa_name), part); else - ret = TREE_TYPE (TREE_TYPE (ssa_name)); + { + if (part == BOTH_P) + ret = TREE_TYPE (ssa_name); + else + ret = TREE_TYPE (TREE_TYPE (ssa_name)); + } + ret = make_ssa_name (ret); /* Copy some properties from the original. In particular, whether it @@ -542,7 +577,7 @@ get_component_ssa_name (tree ssa_name, bool imag_p) gimple_seq of stuff that needs doing. */ static gimple_seq -set_component_ssa_name (tree ssa_name, bool imag_p, tree value) +set_component_ssa_name (tree ssa_name, complex_part_t part, tree value) { complex_lattice_t lattice = find_lattice_value (ssa_name); size_t ssa_name_index; @@ -553,14 +588,25 @@ set_component_ssa_name (tree ssa_name, bool imag_p, tree value) /* We know the value must be zero, else there's a bug in our lattice analysis. But the value may well be a variable known to contain zero. We should be safe ignoring it. */ - if (lattice == (imag_p ? ONLY_REAL : ONLY_IMAG)) + if (((lattice == ONLY_IMAG) && (part == REAL_P)) + || ((lattice == ONLY_REAL) && (part == IMAG_P))) return NULL; /* If we've already assigned an SSA_NAME to this component, then this means that our walk of the basic blocks found a use before the set. This is fine. Now we should create an initialization for the value we created earlier. */ - ssa_name_index = SSA_NAME_VERSION (ssa_name) * 2 + imag_p; + ssa_name_index = SSA_NAME_VERSION (ssa_name) * 3 + part; + unsigned length = complex_ssa_name_components.length (); + + /* Increase size of dynamic array if needed. */ + if (ssa_name_index >= length) + { + size_t new_size = 2 * length; + complex_ssa_name_components.safe_grow (new_size, true); + complex_lattice_values.safe_grow (new_size, true); + } + comp = complex_ssa_name_components[ssa_name_index]; if (comp) ; @@ -584,7 +630,7 @@ set_component_ssa_name (tree ssa_name, bool imag_p, tree value) && (!SSA_NAME_VAR (value) || DECL_IGNORED_P (SSA_NAME_VAR (value))) && !DECL_IGNORED_P (SSA_NAME_VAR (ssa_name))) { - comp = get_component_var (SSA_NAME_VAR (ssa_name), imag_p); + comp = get_component_var (SSA_NAME_VAR (ssa_name), part); replace_ssa_name_symbol (value, comp); } @@ -595,7 +641,7 @@ set_component_ssa_name (tree ssa_name, bool imag_p, tree value) /* Finally, we need to stabilize the result by installing the value into a new ssa name. */ else - comp = get_component_ssa_name (ssa_name, imag_p); + comp = get_component_ssa_name (ssa_name, part); /* Do all the work to assign VALUE to COMP. */ list = NULL; @@ -612,13 +658,14 @@ set_component_ssa_name (tree ssa_name, bool imag_p, tree value) Emit any new code before gsi. */ static tree -extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p, +extract_component (gimple_stmt_iterator * gsi, tree t, complex_part_t part, bool gimple_p, bool phiarg_p = false) { switch (TREE_CODE (t)) { case COMPLEX_CST: - return imagpart_p ? TREE_IMAGPART (t) : TREE_REALPART (t); + return (part == BOTH_P) ? t : (part == IMAG_P) ? + TREE_IMAGPART (t) : TREE_REALPART (t); case COMPLEX_EXPR: gcc_unreachable (); @@ -627,11 +674,14 @@ extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p, { tree inner_type = TREE_TYPE (TREE_TYPE (t)); t = unshare_expr (t); - TREE_TYPE (t) = inner_type; - TREE_OPERAND (t, 1) = TYPE_SIZE (inner_type); - if (imagpart_p) - TREE_OPERAND (t, 2) = size_binop (PLUS_EXPR, TREE_OPERAND (t, 2), - TYPE_SIZE (inner_type)); + if (part != BOTH_P) + { + TREE_TYPE (t) = inner_type; + TREE_OPERAND (t, 1) = TYPE_SIZE (inner_type); + if (part == IMAG_P) + TREE_OPERAND (t, 2) = size_binop (PLUS_EXPR, TREE_OPERAND (t, 2), + TYPE_SIZE (inner_type)); + } if (gimple_p) t = force_gimple_operand_gsi (gsi, t, true, NULL, true, GSI_SAME_STMT); @@ -646,10 +696,11 @@ extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p, case VIEW_CONVERT_EXPR: case MEM_REF: { - tree inner_type = TREE_TYPE (TREE_TYPE (t)); - - t = build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR), - inner_type, unshare_expr (t)); + if (part == BOTH_P) + t = unshare_expr (t); + else + t = build1 (((part == IMAG_P) ? IMAGPART_EXPR : REALPART_EXPR), + (TREE_TYPE (TREE_TYPE (t))), unshare_expr (t)); if (gimple_p) t = force_gimple_operand_gsi (gsi, t, true, NULL, true, @@ -659,10 +710,12 @@ extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p, } case SSA_NAME: - t = get_component_ssa_name (t, imagpart_p); - if (TREE_CODE (t) == SSA_NAME && SSA_NAME_DEF_STMT (t) == NULL) - gcc_assert (phiarg_p); - return t; + { + t = get_component_ssa_name (t, part); + if (TREE_CODE (t) == SSA_NAME && SSA_NAME_DEF_STMT (t) == NULL) + gcc_assert (phiarg_p); + return t; + } default: gcc_unreachable (); @@ -673,18 +726,29 @@ extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p, static void update_complex_components (gimple_stmt_iterator *gsi, gimple *stmt, tree r, - tree i) + tree i, tree b = NULL) { tree lhs; gimple_seq list; + gcc_assert (b || (r && i)); lhs = gimple_get_lhs (stmt); + if (!b) + b = lhs; + if (!r) + r = build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (b)), unshare_expr (b)); + if (!i) + i = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (b)), unshare_expr (b)); + + list = set_component_ssa_name (lhs, REAL_P, r); + if (list) + gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING); - list = set_component_ssa_name (lhs, false, r); + list = set_component_ssa_name (lhs, IMAG_P, i); if (list) gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING); - list = set_component_ssa_name (lhs, true, i); + list = set_component_ssa_name (lhs, BOTH_P, b); if (list) gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING); } @@ -694,11 +758,11 @@ update_complex_components_on_edge (edge e, tree lhs, tree r, tree i) { gimple_seq list; - list = set_component_ssa_name (lhs, false, r); + list = set_component_ssa_name (lhs, REAL_P, r); if (list) gsi_insert_seq_on_edge (e, list); - list = set_component_ssa_name (lhs, true, i); + list = set_component_ssa_name (lhs, IMAG_P, i); if (list) gsi_insert_seq_on_edge (e, list); } @@ -707,19 +771,24 @@ update_complex_components_on_edge (edge e, tree lhs, tree r, tree i) /* Update an assignment to a complex variable in place. */ static void -update_complex_assignment (gimple_stmt_iterator *gsi, tree r, tree i) +update_complex_assignment (gimple_stmt_iterator * gsi, tree r, tree i, + tree b = NULL) { gimple *old_stmt = gsi_stmt (*gsi); - gimple_assign_set_rhs_with_ops (gsi, COMPLEX_EXPR, r, i); + if (b == NULL) + gimple_assign_set_rhs_with_ops (gsi, COMPLEX_EXPR, r, i); + else + /* dummy assignment, but pr45569.C fails if removed. */ + gimple_assign_set_rhs_from_tree (gsi, b); + gimple *stmt = gsi_stmt (*gsi); update_stmt (stmt); if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index); - update_complex_components (gsi, gsi_stmt (*gsi), r, i); + update_complex_components (gsi, gsi_stmt (*gsi), r, i, b); } - /* Generate code at the entry point of the function to initialize the component variables for a complex parameter. */ @@ -768,7 +837,8 @@ update_phi_components (basic_block bb) for (j = 0; j < 2; j++) { - tree l = get_component_ssa_name (gimple_phi_result (phi), j > 0); + tree l = get_component_ssa_name (gimple_phi_result (phi), + (complex_part_t) j); if (TREE_CODE (l) == SSA_NAME) p[j] = create_phi_node (l, bb); } @@ -779,7 +849,9 @@ update_phi_components (basic_block bb) for (j = 0; j < 2; j++) if (p[j]) { - comp = extract_component (NULL, arg, j > 0, false, true); + comp = + extract_component (NULL, arg, (complex_part_t) j, false, + true); if (TREE_CODE (comp) == SSA_NAME && SSA_NAME_DEF_STMT (comp) == NULL) { @@ -815,7 +887,7 @@ static void expand_complex_move (gimple_stmt_iterator *gsi, tree type) { tree inner_type = TREE_TYPE (type); - tree r, i, lhs, rhs; + tree r, i, b, lhs, rhs; gimple *stmt = gsi_stmt (*gsi); if (is_gimple_assign (stmt)) @@ -862,16 +934,13 @@ expand_complex_move (gimple_stmt_iterator *gsi, tree type) else { if (gimple_assign_rhs_code (stmt) != COMPLEX_EXPR) - { - r = extract_component (gsi, rhs, 0, true); - i = extract_component (gsi, rhs, 1, true); - } + update_complex_assignment (gsi, NULL, NULL, + extract_component (gsi, rhs, + BOTH_P, true)); else - { - r = gimple_assign_rhs1 (stmt); - i = gimple_assign_rhs2 (stmt); - } - update_complex_assignment (gsi, r, i); + update_complex_assignment (gsi, + gimple_assign_rhs1 (stmt), + gimple_assign_rhs2 (stmt), NULL); } } else if (rhs @@ -883,24 +952,18 @@ expand_complex_move (gimple_stmt_iterator *gsi, tree type) location_t loc; loc = gimple_location (stmt); - r = extract_component (gsi, rhs, 0, false); - i = extract_component (gsi, rhs, 1, false); - - x = build1 (REALPART_EXPR, inner_type, unshare_expr (lhs)); - t = gimple_build_assign (x, r); - gimple_set_location (t, loc); - gsi_insert_before (gsi, t, GSI_SAME_STMT); + b = extract_component (gsi, rhs, BOTH_P, false); if (stmt == gsi_stmt (*gsi)) { - x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs)); + x = unshare_expr (lhs); gimple_assign_set_lhs (stmt, x); - gimple_assign_set_rhs1 (stmt, i); + gimple_assign_set_rhs1 (stmt, b); } else { - x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs)); - t = gimple_build_assign (x, i); + x = unshare_expr (lhs); + t = gimple_build_assign (x, b); gimple_set_location (t, loc); gsi_insert_before (gsi, t, GSI_SAME_STMT); @@ -1641,26 +1704,101 @@ expand_complex_asm (gimple_stmt_iterator *gsi) } /* Make sure to not ICE later, see PR105165. */ tree zero = build_zero_cst (TREE_TYPE (TREE_TYPE (op))); - set_component_ssa_name (op, false, zero); - set_component_ssa_name (op, true, zero); + set_component_ssa_name (op, REAL_P, zero); + set_component_ssa_name (op, IMAG_P, zero); + set_component_ssa_name (op, BOTH_P, zero); continue; } tree type = TREE_TYPE (op); tree inner_type = TREE_TYPE (type); tree r = build1 (REALPART_EXPR, inner_type, op); tree i = build1 (IMAGPART_EXPR, inner_type, op); - gimple_seq list = set_component_ssa_name (op, false, r); + tree b = op; + gimple_seq list = set_component_ssa_name (op, REAL_P, r); if (list) gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING); - list = set_component_ssa_name (op, true, i); + list = set_component_ssa_name (op, IMAG_P, i); + if (list) + gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING); + + list = set_component_ssa_name (op, BOTH_P, b); if (list) gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING); } } } +/* Returns true if a complex component is a constant. */ + +static bool +complex_component_cst_p (tree cplx, complex_part_t part) +{ + switch (TREE_CODE (cplx)) + { + case COMPLEX_CST: + return true; + + case SSA_NAME: + { + size_t ssa_name_index = SSA_NAME_VERSION (cplx) * 3 + part; + tree val = complex_ssa_name_components[ssa_name_index]; + return (val) ? CONSTANT_CLASS_P (val) : false; + } + + default: + return false; + } +} + +/* Returns true if the target support a particular complex operation + natively. */ + +static bool +target_native_complex_operation (enum tree_code code, tree type, + tree inner_type, tree ac, tree bc, + complex_lattice_t al, complex_lattice_t bl) +{ + /* Lower trivial complex operations. + ------------------------------------------------------------------- + | a \ b | UNINITIALIZED | ONLY_REAL | ONLY_IMAG | VARYING | + ------------------------------------------------------------------- + | UNINITIALIZED | xxxxxxxxxxxxx | xxxxxxxxx | xxxxxxxxx | xxxxxxx | + ------------------------------------------------------------------- + | ONLY_REAL | lower | lower | native | native | + ------------------------------------------------------------------- + | ONLY_IMAG | lower | native | lower | native | + ------------------------------------------------------------------- + | VARYING | native | native | native | native | + ------------------------------------------------------------------- */ + if (((al != VARYING) && (bl != VARYING)) + && ((bl == UNINITIALIZED) + || (al == bl))) + return false; + + /* Do not use native operations when a part of the result is constant. */ + if ((bl == UNINITIALIZED) + && (complex_component_cst_p (ac, REAL_P) + || complex_component_cst_p (ac, IMAG_P))) + return false; + else if ((bl != UNINITIALIZED) + && + ((complex_component_cst_p (ac, REAL_P) + && complex_component_cst_p (bc, REAL_P)) + || (complex_component_cst_p (ac, IMAG_P) + && complex_component_cst_p (bc, IMAG_P)))) + return false; + + optab op = optab_for_tree_code (code, inner_type, optab_default); + + /* No need to search if operation is not in the optab. */ + if (op == unknown_optab) + return false; + + return optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing; +} + /* Process one statement. If we identify a complex operation, expand it. */ static void @@ -1729,14 +1867,17 @@ expand_complex_operations_1 (gimple_stmt_iterator *gsi) && TREE_CODE (lhs) == SSA_NAME) { rhs = gimple_assign_rhs1 (stmt); + enum tree_code rhs_code = gimple_assign_rhs_code (stmt); rhs = extract_component (gsi, TREE_OPERAND (rhs, 0), - gimple_assign_rhs_code (stmt) - == IMAGPART_EXPR, - false); + (rhs_code == IMAGPART_EXPR) ? IMAG_P + : (rhs_code == REALPART_EXPR) ? REAL_P + : BOTH_P, false); gimple_assign_set_rhs_from_tree (gsi, rhs); stmt = gsi_stmt (*gsi); update_stmt (stmt); } + else if (is_gimple_call (stmt)) + return; } return; } @@ -1755,19 +1896,6 @@ expand_complex_operations_1 (gimple_stmt_iterator *gsi) bc = gimple_cond_rhs (stmt); } - ar = extract_component (gsi, ac, false, true); - ai = extract_component (gsi, ac, true, true); - - if (ac == bc) - br = ar, bi = ai; - else if (bc) - { - br = extract_component (gsi, bc, 0, true); - bi = extract_component (gsi, bc, 1, true); - } - else - br = bi = NULL_TREE; - al = find_lattice_value (ac); if (al == UNINITIALIZED) al = VARYING; @@ -1783,6 +1911,102 @@ expand_complex_operations_1 (gimple_stmt_iterator *gsi) bl = VARYING; } + if (target_native_complex_operation + (code, type, inner_type, ac, bc, al, bl)) + { + tree ab, bb, rb; + gimple_seq stmts = NULL; + location_t loc = gimple_location (gsi_stmt (*gsi)); + + ab = extract_component (gsi, ac, BOTH_P, true); + if (ac == bc) + bb = ab; + else if (bc) + { + bb = extract_component (gsi, bc, BOTH_P, true); + } + else + bb = NULL_TREE; + + switch (code) + { + case PLUS_EXPR: + case MINUS_EXPR: + case MULT_EXPR: + rb = gimple_build (&stmts, loc, code, type, ab, bb); + gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); + update_complex_assignment (gsi, NULL, NULL, rb); + break; + + case NEGATE_EXPR: + case CONJ_EXPR: + rb = gimple_build (&stmts, loc, code, type, ab); + gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); + update_complex_assignment (gsi, NULL, NULL, rb); + break; + + case EQ_EXPR: + case NE_EXPR: + { + gimple *stmt = gsi_stmt (*gsi); + rb = gimple_build (&stmts, loc, code, type, ab, bb); + switch (gimple_code (stmt)) + { + case GIMPLE_RETURN: + { + greturn *return_stmt = as_a < greturn * >(stmt); + gimple_return_set_retval (return_stmt, + fold_convert (type, rb)); + } + break; + + case GIMPLE_ASSIGN: + update_complex_assignment (gsi, NULL, NULL, rb); + gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); + break; + + case GIMPLE_COND: + { + gcond *cond_stmt = as_a < gcond * >(stmt); + gimple_cond_set_code (cond_stmt, EQ_EXPR); + gimple_cond_set_lhs (cond_stmt, rb); + gimple_cond_set_rhs (cond_stmt, boolean_true_node); + } + break; + + default: + break; + } + break; + } + + + /* Not supported yet. */ + case TRUNC_DIV_EXPR: + case CEIL_DIV_EXPR: + case FLOOR_DIV_EXPR: + case ROUND_DIV_EXPR: + case RDIV_EXPR: + + default: + gcc_unreachable (); + } + return; + } + + ar = extract_component (gsi, ac, REAL_P, true); + ai = extract_component (gsi, ac, IMAG_P, true); + + if (ac == bc) + br = ar, bi = ai; + else if (bc) + { + br = extract_component (gsi, bc, REAL_P, true); + bi = extract_component (gsi, bc, IMAG_P, true); + } + else + br = bi = NULL_TREE; + switch (code) { case PLUS_EXPR: @@ -1819,8 +2043,8 @@ expand_complex_operations_1 (gimple_stmt_iterator *gsi) gcc_unreachable (); } } - + /* Entry point for complex operation lowering during optimization. */ static unsigned int @@ -1845,8 +2069,8 @@ tree_lower_complex (void) complex_variable_components = new int_tree_htab_type (10); - complex_ssa_name_components.create (2 * num_ssa_names); - complex_ssa_name_components.safe_grow_cleared (2 * num_ssa_names, true); + complex_ssa_name_components.create (3 * num_ssa_names); + complex_ssa_name_components.safe_grow_cleared (3 * num_ssa_names, true); update_parameter_components (); @@ -1879,7 +2103,8 @@ tree_lower_complex (void) || is_gimple_min_invariant (op)) continue; tree arg = gimple_phi_arg_def (phis_to_revisit[j], l); - op = extract_component (NULL, arg, k > 0, false, false); + op = extract_component (NULL, arg, (complex_part_t) k, + false, false); SET_PHI_ARG_DEF (phi, l, op); } } diff --git a/gcc/tree-core.h b/gcc/tree-core.h index 91551fde900..19293e03af6 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -1487,6 +1487,7 @@ struct GTY(()) tree_complex { struct tree_typed typed; tree real; tree imag; + tree both; }; struct GTY(()) tree_vector { diff --git a/gcc/tree-dfa.cc b/gcc/tree-dfa.cc index ad8cfedec8c..42c254cbfed 100644 --- a/gcc/tree-dfa.cc +++ b/gcc/tree-dfa.cc @@ -394,6 +394,9 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset, size_tree = TREE_OPERAND (exp, 1); exp = TREE_OPERAND (exp, 0); } + else if (TREE_CODE (exp) == REALPART_EXPR + || TREE_CODE (exp) == IMAGPART_EXPR) + exp = TREE_OPERAND (exp, 0); else if (!VOID_TYPE_P (TREE_TYPE (exp))) { machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); diff --git a/gcc/tree-streamer-in.cc b/gcc/tree-streamer-in.cc index 5bead0c3c6a..a1fa2cb9eea 100644 --- a/gcc/tree-streamer-in.cc +++ b/gcc/tree-streamer-in.cc @@ -695,6 +695,7 @@ lto_input_ts_complex_tree_pointers (class lto_input_block *ib, { TREE_REALPART (expr) = stream_read_tree_ref (ib, data_in); TREE_IMAGPART (expr) = stream_read_tree_ref (ib, data_in); + TREE_COMPLEX_BOTH_PARTS (expr) = stream_read_tree_ref (ib, data_in); } diff --git a/gcc/tree-streamer-out.cc b/gcc/tree-streamer-out.cc index ff9694e17dd..be7314ef748 100644 --- a/gcc/tree-streamer-out.cc +++ b/gcc/tree-streamer-out.cc @@ -592,6 +592,7 @@ write_ts_complex_tree_pointers (struct output_block *ob, tree expr) { stream_write_tree_ref (ob, TREE_REALPART (expr)); stream_write_tree_ref (ob, TREE_IMAGPART (expr)); + stream_write_tree_ref (ob, TREE_COMPLEX_BOTH_PARTS (expr)); } diff --git a/gcc/tree.cc b/gcc/tree.cc index b34d75f8c85..73b72f80d25 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -2500,6 +2500,14 @@ build_complex (tree type, tree real, tree imag) tree t = make_node (COMPLEX_CST); + /* Represent both parts as a constant vector. */ + tree vector_type = build_vector_type (TREE_TYPE (real), 2); + tree_vector_builder v (vector_type, 1, 2); + v.quick_push (real); + v.quick_push (imag); + tree both = v.build (); + + TREE_COMPLEX_BOTH_PARTS (t) = both; TREE_REALPART (t) = real; TREE_IMAGPART (t) = imag; TREE_TYPE (t) = type ? type : build_complex_type (TREE_TYPE (real)); diff --git a/gcc/tree.h b/gcc/tree.h index 54cf8282cb2..572d90283af 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -647,6 +647,12 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, #define SCALAR_FLOAT_TYPE_P(TYPE) (TREE_CODE (TYPE) == REAL_TYPE) +/* Nonzero if TYPE represents a complex integer type. */ + +#define COMPLEX_INTEGER_TYPE_P(TYPE) \ + (TREE_CODE (TYPE) == COMPLEX_TYPE \ + && TREE_CODE (TREE_TYPE (TYPE)) == INTEGER_TYPE) + /* Nonzero if TYPE represents a complex floating-point type. */ #define COMPLEX_FLOAT_TYPE_P(TYPE) \ @@ -1170,6 +1176,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, /* In a COMPLEX_CST node. */ #define TREE_REALPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.real) #define TREE_IMAGPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.imag) +#define TREE_COMPLEX_BOTH_PARTS(NODE) (COMPLEX_CST_CHECK (NODE)->complex.both) /* In a VECTOR_CST node. See generic.texi for details. */ #define VECTOR_CST_NELTS(NODE) (TYPE_VECTOR_SUBPARTS (TREE_TYPE (NODE))) @@ -2234,6 +2241,8 @@ class auto_suppress_location_wrappers (as_a (TYPE_CHECK (NODE)->type_common.mode)) #define SCALAR_FLOAT_TYPE_MODE(NODE) \ (as_a (TYPE_CHECK (NODE)->type_common.mode)) +#define COMPLEX_TYPE_MODE(NODE) \ + (as_a (TYPE_CHECK (NODE)->type_common.mode)) #define SET_TYPE_MODE(NODE, MODE) \ (TYPE_CHECK (NODE)->type_common.mode = (MODE)) @@ -6733,7 +6742,11 @@ extern const builtin_structptr_type builtin_structptr_types[6]; inline bool type_has_mode_precision_p (const_tree t) { - return known_eq (TYPE_PRECISION (t), GET_MODE_PRECISION (TYPE_MODE (t))); + if (TREE_CODE (t) == COMPLEX_TYPE) + return known_eq (2 * TYPE_PRECISION (TREE_TYPE (t)), + GET_MODE_PRECISION (TYPE_MODE (t))); + else + return known_eq (TYPE_PRECISION (t), GET_MODE_PRECISION (TYPE_MODE (t))); } /* Helper functions for fndecl_built_in_p. */ -- 2.17.1