From patchwork Sat Nov 13 11:15:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 47605 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 167633857C43 for ; Sat, 13 Nov 2021 11:16:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 167633857C43 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1636802184; bh=c7W8RLXSHH3o7UYbKONiHfufMWN6y3R7B4D/83YTJ0k=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=tyHUk/nCurv46uX+RsbjBWCdh8Orqjtdvtka1tKTQ/qnpQlMgpCpAARIHwm6ECON0 H8Wk7Ni0LFbWMcnLv26Ao57b+lt4sEjuiZ1YhV01XTreiYIKI9nZLlGPUNSEuyzyKU fbZ9SysoWmKMEjb1sYsLl597xauYmuwzTbe6UlP8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from nikam.ms.mff.cuni.cz (nikam.ms.mff.cuni.cz [195.113.20.16]) by sourceware.org (Postfix) with ESMTPS id 96DA03858403 for ; Sat, 13 Nov 2021 11:15:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 96DA03858403 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 36BEC280941; Sat, 13 Nov 2021 12:15:52 +0100 (CET) Date: Sat, 13 Nov 2021 12:15:52 +0100 To: gcc-patches@gcc.gnu.org Subject: Enable ipa-sra for functions with fnspec attribute Message-ID: <20211113111552.GB15769@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, KAM_SHORT, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Jan Hubicka via Gcc-patches From: Jan Hubicka Reply-To: Jan Hubicka Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi, this patch enables some ipa-sra on fortran by allowing signature changes on functions with "fn spec" attribute when ipa-modref is enabled. This is possible since ipa-modref knows how to preserve things we trace in fnspec and fnspec generated by fortran forntend are quite simple and can be analysed automatically now. To be sure I will also add code that merge fnspec to parameters. This unfortunately hits bug in ipa-param-manipulation when we remove parameter that specifies size of variable length parameter. For this reason I added a hack that prevent signature changes on such functions and will handle it incrementally. I tried creating C testcase but it is blocked by another problem that we punt ipa-sra on access attribute. This is optimization regression we ought to fix so I filled https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103223. As a followup I will add code classifying the type attributes (we have just few) and get stats on access attribute. Martin, can you please check that the code detecting signature changes is correct and can't be done more easily? Bootstrapped/regtested x86_64-linux, comitted. Honza gcc/ChangeLog: * ipa-fnsummary.c (compute_fn_summary): Do not give up on signature changes on "fn spec" attribute; give up on varadic types. * ipa-param-manipulation.c: Include attribs.h. (build_adjusted_function_type): New parameter ARG_MODIFIED; if it is true remove "fn spec" attribute. (ipa_param_adjustments::build_new_function_type): Update. (ipa_param_body_adjustments::modify_formal_parameters): update. * ipa-sra.c: Include attribs.h. (ipa_sra_preliminary_function_checks): Do not check for TYPE_ATTRIBUTES. diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c index 2cfa9a6d0e9..94a80d3ec90 100644 --- a/gcc/ipa-fnsummary.c +++ b/gcc/ipa-fnsummary.c @@ -3135,10 +3135,38 @@ compute_fn_summary (struct cgraph_node *node, bool early) else info->inlinable = tree_inlinable_function_p (node->decl); - /* Type attributes can use parameter indices to describe them. */ - if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)) - /* Likewise for #pragma omp declare simd functions or functions - with simd attribute. */ + bool no_signature = false; + /* Type attributes can use parameter indices to describe them. + Special case fn spec since we can safely preserve them in + modref summaries. */ + for (tree list = TYPE_ATTRIBUTES (TREE_TYPE (node->decl)); + list && !no_signature; list = TREE_CHAIN (list)) + if (!flag_ipa_modref + || !is_attribute_p ("fn spec", get_attribute_name (list))) + { + if (dump_file) + { + fprintf (dump_file, "No signature change:" + " function type has unhandled attribute %s.\n", + IDENTIFIER_POINTER (get_attribute_name (list))); + } + no_signature = true; + } + for (tree parm = DECL_ARGUMENTS (node->decl); + parm && !no_signature; parm = DECL_CHAIN (parm)) + if (variably_modified_type_p (TREE_TYPE (parm), node->decl)) + { + if (dump_file) + { + fprintf (dump_file, "No signature change:" + " has parameter with variably modified type.\n"); + } + no_signature = true; + } + + /* Likewise for #pragma omp declare simd functions or functions + with simd attribute. */ + if (no_signature || lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (node->decl))) node->can_change_signature = false; diff --git a/gcc/ipa-param-manipulation.c b/gcc/ipa-param-manipulation.c index ae3149718ca..20f41dd5363 100644 --- a/gcc/ipa-param-manipulation.c +++ b/gcc/ipa-param-manipulation.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include "symtab-clones.h" #include "tree-phinodes.h" #include "cfgexpand.h" +#include "attribs.h" /* Actual prefixes of different newly synthetized parameters. Keep in sync @@ -281,11 +282,13 @@ fill_vector_of_new_param_types (vec *new_types, vec *otypes, /* Build and return a function type just like ORIG_TYPE but with parameter types given in NEW_PARAM_TYPES - which can be NULL if, but only if, ORIG_TYPE itself has NULL TREE_ARG_TYPEs. If METHOD2FUNC is true, also make - it a FUNCTION_TYPE instead of FUNCTION_TYPE. */ + it a FUNCTION_TYPE instead of FUNCTION_TYPE. + If ARG_MODIFIED is true drop attributes that are no longer up to date. */ static tree build_adjusted_function_type (tree orig_type, vec *new_param_types, - bool method2func, bool skip_return) + bool method2func, bool skip_return, + bool args_modified) { tree new_arg_types = NULL; if (TYPE_ARG_TYPES (orig_type)) @@ -334,6 +337,17 @@ build_adjusted_function_type (tree orig_type, vec *new_param_types, if (skip_return) TREE_TYPE (new_type) = void_type_node; } + /* We only support one fn spec attribute on type. Be sure to remove it. + Once we support multiple attributes we will need to be able to unshare + the list. */ + if (args_modified && TYPE_ATTRIBUTES (new_type)) + { + gcc_checking_assert + (!TREE_CHAIN (TYPE_ATTRIBUTES (new_type)) + && (is_attribute_p ("fn spec", + get_attribute_name (TYPE_ATTRIBUTES (new_type))))); + TYPE_ATTRIBUTES (new_type) = NULL; + } return new_type; } @@ -460,8 +474,22 @@ ipa_param_adjustments::build_new_function_type (tree old_type, else new_param_types_p = NULL; + /* Check if any params type cares about are modified. In this case will + need to drop some type attributes. */ + bool modified = false; + size_t index = 0; + if (m_adj_params) + for (tree t = TYPE_ARG_TYPES (old_type); + t && (int)index < m_always_copy_start && !modified; + t = TREE_CHAIN (t), index++) + if (index >= m_adj_params->length () + || get_original_index (index) != (int)index) + modified = true; + + return build_adjusted_function_type (old_type, new_param_types_p, - method2func_p (old_type), m_skip_return); + method2func_p (old_type), m_skip_return, + modified); } /* Build variant of function decl ORIG_DECL which has no return value if @@ -1467,12 +1495,23 @@ ipa_param_body_adjustments::modify_formal_parameters () if (fndecl_built_in_p (m_fndecl)) set_decl_built_in_function (m_fndecl, NOT_BUILT_IN, 0); + bool modified = false; + size_t index = 0; + if (m_adj_params) + for (tree t = TYPE_ARG_TYPES (orig_type); + t && !modified; + t = TREE_CHAIN (t), index++) + if (index >= m_adj_params->length () + || (*m_adj_params)[index].op != IPA_PARAM_OP_COPY + || (*m_adj_params)[index].base_index != index) + modified = true; + /* At this point, removing return value is only implemented when going through tree_function_versioning, not when modifying function body directly. */ gcc_assert (!m_adjustments || !m_adjustments->m_skip_return); tree new_type = build_adjusted_function_type (orig_type, &m_new_types, - m_method2func, false); + m_method2func, false, modified); TREE_TYPE (m_fndecl) = new_type; DECL_VIRTUAL_P (m_fndecl) = 0; diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c index 88036590425..cb0e30507a1 100644 --- a/gcc/ipa-sra.c +++ b/gcc/ipa-sra.c @@ -85,6 +85,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-streamer.h" #include "internal-fn.h" #include "symtab-clones.h" +#include "attribs.h" static void ipa_sra_summarize_function (cgraph_node *); @@ -616,13 +617,6 @@ ipa_sra_preliminary_function_checks (cgraph_node *node) return false; } - if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl))) - { - if (dump_file) - fprintf (dump_file, "Function type has attributes. \n"); - return false; - } - if (DECL_DISREGARD_INLINE_LIMITS (node->decl)) { if (dump_file)