Patchwork [4.5,2/2] IPA-SRA versioning for 4.5

login
register
mail settings
Submitter Martin Jambor
Date June 28, 2010, 4:56 p.m.
Message ID <20100628165654.809772423@virgil.suse.cz>
Download mbox | patch
Permalink /patch/57170/
State New
Headers show

Comments

Martin Jambor - June 28, 2010, 4:56 p.m.
This is a version of the IPA-SRA versioning patch for the 4.5 branch.
Unlike in the current trunk, cgraph_function_versioning does redirect
recursive calls (and updates cgraph edges accordingly) on the 4.5
branch.  Since versioning already demands that we rebuild all outgoing
cgraph edges, we can then use those instead of another function body
walk.  In any case, we must not attempt to use both and so I simply
deleted the walk alng with the variable that controlled it.

Martin

2010-06-27  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/43905
	* tree-sra.c (encountered_recursive_call): Removed with all its uses.
	(convert_callers): Do not handle recursive calls specially.
	(create_abstract_origin): Removed.
	(modify_function): Version the call graph node instead of creating
	abstract origins and dealing with same_body aliases.
	(ipa_sra_preliminary_function_checks): Check whether the function
	is versionable.
	* Makefile.in (tree-sra.o): Add TREE_INLINE_H to dependencies.

	* testsuite/g++.dg/torture/pr43905.C: New test.

Patch

Index: gcc/testsuite/g++.dg/torture/pr43905.C
===================================================================
--- /dev/null
+++ gcc/testsuite/g++.dg/torture/pr43905.C
@@ -0,0 +1,13 @@ 
+extern void sf ( __const char *);
+struct Matrix{
+  int operator[](int n){
+    sf ( __PRETTY_FUNCTION__);
+  }
+  int operator[](int n)const{
+    sf ( __PRETTY_FUNCTION__);
+  }
+};
+void calcmy(Matrix const &b, Matrix &c, int k){
+  b[k];
+  c[k];
+}
Index: gcc/tree-sra.c
===================================================================
--- gcc/tree-sra.c.orig
+++ gcc/tree-sra.c
@@ -89,6 +89,7 @@  along with GCC; see the file COPYING3.
 #include "params.h"
 #include "target.h"
 #include "flags.h"
+#include "tree-inline.h"
 
 /* Enumeration of all aggregate reductions we can do.  */
 enum sra_mode { SRA_MODE_EARLY_IPA,   /* early call regularization */
@@ -271,9 +272,6 @@  static int func_param_count;
    __builtin_apply_args.  */
 static bool encountered_apply_args;
 
-/* Set by scan_function when it finds a recursive call.  */
-static bool encountered_recursive_call;
-
 /* Set by scan_function when it finds a recursive call with less actual
    arguments than formal parameters..  */
 static bool encountered_unchangable_recursive_call;
@@ -571,7 +569,6 @@  sra_initialize (void)
   base_access_vec = pointer_map_create ();
   memset (&sra_stats, 0, sizeof (sra_stats));
   encountered_apply_args = false;
-  encountered_recursive_call = false;
   encountered_unchangable_recursive_call = false;
 }
 
@@ -1169,12 +1166,9 @@  scan_function (bool (*scan_expr) (tree *
 			  && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
 			encountered_apply_args = true;
 		      if (cgraph_get_node (dest)
-			  == cgraph_get_node (current_function_decl))
-			{
-			  encountered_recursive_call = true;
-			  if (!callsite_has_enough_arguments_p (stmt))
-			    encountered_unchangable_recursive_call = true;
-			}
+			  == cgraph_get_node (current_function_decl)
+			  && !callsite_has_enough_arguments_p (stmt))
+			encountered_unchangable_recursive_call = true;
 		    }
 
 		  if (final_bbs
@@ -4023,7 +4017,6 @@  convert_callers (struct cgraph_node *nod
 {
   tree old_cur_fndecl = current_function_decl;
   struct cgraph_edge *cs;
-  basic_block this_block;
   bitmap recomputed_callers = BITMAP_ALLOC (NULL);
 
   for (cs = node->callers; cs; cs = cs->next_caller)
@@ -4043,7 +4036,8 @@  convert_callers (struct cgraph_node *nod
     }
 
   for (cs = node->callers; cs; cs = cs->next_caller)
-    if (!bitmap_bit_p (recomputed_callers, cs->caller->uid))
+    if (cs->caller != node
+	&& !bitmap_bit_p (recomputed_callers, cs->caller->uid))
       {
 	compute_inline_parameters (cs->caller);
 	bitmap_set_bit (recomputed_callers, cs->caller->uid);
@@ -4051,71 +4045,41 @@  convert_callers (struct cgraph_node *nod
   BITMAP_FREE (recomputed_callers);
 
   current_function_decl = old_cur_fndecl;
-
-  if (!encountered_recursive_call)
-    return;
-
-  FOR_EACH_BB (this_block)
-    {
-      gimple_stmt_iterator gsi;
-
-      for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
-        {
-	  gimple stmt = gsi_stmt (gsi);
-	  tree call_fndecl;
-	  if (gimple_code (stmt) != GIMPLE_CALL)
-	    continue;
-	  call_fndecl = gimple_call_fndecl (stmt);
-	  if (call_fndecl && cgraph_get_node (call_fndecl) == node)
-	    {
-	      if (dump_file)
-		fprintf (dump_file, "Adjusting recursive call");
-	      ipa_modify_call_arguments (NULL, stmt, adjustments);
-	    }
-	}
-    }
-
   return;
 }
 
-/* Create an abstract origin declaration for OLD_DECL and make it an abstract
-   origin of the provided decl so that there are preserved parameters for debug
-   information.  */
-
-static void
-create_abstract_origin (tree old_decl)
-{
-  if (!DECL_ABSTRACT_ORIGIN (old_decl))
-    {
-      tree new_decl = copy_node (old_decl);
-
-      DECL_ABSTRACT (new_decl) = 1;
-      SET_DECL_ASSEMBLER_NAME (new_decl, NULL_TREE);
-      SET_DECL_RTL (new_decl, NULL);
-      DECL_STRUCT_FUNCTION (new_decl) = NULL;
-      DECL_ARTIFICIAL (old_decl) = 1;
-      DECL_ABSTRACT_ORIGIN (old_decl) = new_decl;
-    }
-}
-
 /* Perform all the modification required in IPA-SRA for NODE to have parameters
    as given in ADJUSTMENTS.  */
 
 static void
 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
 {
-  struct cgraph_node *alias;
-  for (alias = node->same_body; alias; alias = alias->next)
-    ipa_modify_formal_parameters (alias->decl, adjustments, "ISRA");
-  /* current_function_decl must be handled last, after same_body aliases,
-     as following functions will use what it computed.  */
-  create_abstract_origin (current_function_decl);
+  struct cgraph_node *new_node;
+  struct cgraph_edge *cs;
+  VEC (cgraph_edge_p, heap) * redirect_callers;
+  int node_callers;
+
+  node_callers = 0;
+  for (cs = node->callers; cs != NULL; cs = cs->next_caller)
+    node_callers++;
+  redirect_callers = VEC_alloc (cgraph_edge_p, heap, node_callers);
+  for (cs = node->callers; cs != NULL; cs = cs->next_caller)
+    VEC_quick_push (cgraph_edge_p, redirect_callers, cs);
+
+  rebuild_cgraph_edges ();
+  pop_cfun ();
+  current_function_decl = NULL_TREE;
+
+  new_node = cgraph_function_versioning (node, redirect_callers, NULL, NULL);
+  current_function_decl = new_node->decl;
+  push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
+
   ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
   scan_function (sra_ipa_modify_expr, sra_ipa_modify_assign,
 		 replace_removed_params_ssa_names, false, adjustments);
   sra_ipa_reset_debug_stmts (adjustments);
-  convert_callers (node, adjustments);
-  cgraph_make_node_local (node);
+  convert_callers (new_node, adjustments);
+  cgraph_make_node_local (new_node);
   return;
 }
 
@@ -4130,6 +4094,13 @@  ipa_sra_preliminary_function_checks (str
     {
       if (dump_file)
 	fprintf (dump_file, "Function not local to this compilation unit.\n");
+      return false;
+    }
+
+  if (!tree_versionable_function_p (node->decl))
+    {
+      if (dump_file)
+	fprintf (dump_file, "Function not local to this compilation unit.\n");
       return false;
     }
 
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in.orig
+++ gcc/Makefile.in
@@ -3000,7 +3000,7 @@  tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_F
 tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h alloc-pool.h \
    $(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) $(IPA_PROP_H) \
    $(DIAGNOSTIC_H) statistics.h $(TREE_DUMP_H) $(TIMEVAR_H) $(PARAMS_H) \
-   $(TARGET_H) $(FLAGS_H) $(EXPR_H)
+   $(TARGET_H) $(FLAGS_H) $(EXPR_H) $(TREE_INLINE_H)
 tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \
     $(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \
     $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \