public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-5223] Enable ipa-sra with fnspec attributes
@ 2021-11-13 11:14 Jan Hubicka
  0 siblings, 0 replies; only message in thread
From: Jan Hubicka @ 2021-11-13 11:14 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:ecdf414bd89e6ba251f6b3f494407139b4dbae0e

commit r12-5223-gecdf414bd89e6ba251f6b3f494407139b4dbae0e
Author: Jan Hubicka <jh@suse.cz>
Date:   Sat Nov 13 12:13:42 2021 +0100

    Enable ipa-sra with fnspec attributes
    
    Enable 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.
    
    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:
---
 gcc/ipa-fnsummary.c          | 36 +++++++++++++++++++++++++++++----
 gcc/ipa-param-manipulation.c | 47 ++++++++++++++++++++++++++++++++++++++++----
 gcc/ipa-sra.c                |  8 +-------
 3 files changed, 76 insertions(+), 15 deletions(-)

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..991db0d9b1b 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<tree> *new_types, vec<tree> *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<tree> *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<tree> *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)


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-11-13 11:14 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-13 11:14 [gcc r12-5223] Enable ipa-sra with fnspec attributes Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).