This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Make ipcp IPA_PASS


Hi,
this patch makes IPCP IPA_PASS (instead of SIMPLE_IPA_PASS).  
The patch updates inliner and ipcp to compute one set of summaries and
I've also fixed some problems in ipcp so one can get clean regtesting
run and bootstrap on i686.  I still get failure on x86_64 with ipcp
enabled, but same failure appears on unpatched ipcp with my fixes
backported (otherwise compilation dies earlier).  I am looking into it.

I didn't updated the transformation to happen later, since this needs
some extra infrastructure.  We need to reorganize ipcp to not use
iteration (I don't think it helps anyway) and the callgraph's clonning
code needs to be updated to be able to deal with versioning.  This is
quite involved, so I would like to deal with this later after debugging
remaining issues with ipcp and trying to enable it by default.

For LTO/whopr it is not completely critical: we can do the job of saving
summaries and experimenting with the idea of bringing functions to
memory early for nontrivial transformations. We will need that for other
passes later anyway.

I will commit it tomorrow if there will be no complains.
Bootstrapped/regtested x86_64-linux and i686-linux (without ipcp enabled by default)

Honza

	* tree-pass.h (pass_ipa_cp): Make ipa_opt_pass.
	* ipa-cp.c (ipcp_update_cloned_node): New function.
	(build_const_val): Handle functions correctly; bring type logic
	into sync with tree-inline.c
	(ipcp_init_stage):  Take care of computing stuff needed by
	indirect inlining; update clones.
	(ipcp_generate_summary): Break out of ipcp_driver.
	(ipcp_driver): Do only execution and transformation.
	(pass_ipa_cp): Make IPA_PASS.
	* tree-ssa-ccp.c (fold_stmt_r): Check type before trying to fold
	offset to address.
	* ipa-inline.c (inline_indirect_intraprocedural_analysis): When doing
	ipcp, some info is already available.
	* ipa-prop.c (ipa_count_arguments): Grow edge lists as needed.
	* tree-inline.c (remap_ssa_name): Unshare expression.
Index: tree-pass.h
===================================================================
*** tree-pass.h	(revision 139234)
--- tree-pass.h	(working copy)
*************** extern struct gimple_opt_pass pass_reset
*** 390,399 ****
  
  /* IPA Passes */
  extern struct ipa_opt_pass pass_ipa_inline;
  extern struct simple_ipa_opt_pass pass_ipa_reference;
  
  extern struct simple_ipa_opt_pass pass_ipa_matrix_reorg;
- extern struct simple_ipa_opt_pass pass_ipa_cp;
  extern struct simple_ipa_opt_pass pass_ipa_early_inline;
  extern struct simple_ipa_opt_pass pass_ipa_pure_const;
  extern struct simple_ipa_opt_pass pass_ipa_type_escape;
--- 390,399 ----
  
  /* IPA Passes */
  extern struct ipa_opt_pass pass_ipa_inline;
+ extern struct ipa_opt_pass pass_ipa_cp;
  extern struct simple_ipa_opt_pass pass_ipa_reference;
  
  extern struct simple_ipa_opt_pass pass_ipa_matrix_reorg;
  extern struct simple_ipa_opt_pass pass_ipa_early_inline;
  extern struct simple_ipa_opt_pass pass_ipa_pure_const;
  extern struct simple_ipa_opt_pass pass_ipa_type_escape;
Index: ipa-cp.c
===================================================================
*** ipa-cp.c	(revision 139234)
--- ipa-cp.c	(working copy)
*************** ipcp_init_cloned_node (struct cgraph_nod
*** 159,164 ****
--- 159,194 ----
    ipa_create_param_decls_array (new_node);
  }
  
+ /* Recompute all local information since node might've got new
+    direct calls after clonning.  */
+ static void
+ ipcp_update_cloned_node (struct cgraph_node *new_node)
+ {
+   /* We might've introduced new direct calls.  */
+   push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
+   current_function_decl = new_node->decl;
+   rebuild_cgraph_edges ();
+ 
+   if (flag_indirect_inlining)
+     {
+       struct cgraph_edge *cs;
+ 
+       ipa_check_create_node_params ();
+       ipa_count_formal_params (new_node);
+       ipa_create_param_decls_array (new_node);
+       ipa_detect_param_modifications (new_node);
+       ipa_analyze_params_uses (new_node);
+ 
+       for (cs = new_node->callees; cs; cs = cs->next_callee)
+ 	{
+ 	  ipa_count_arguments (cs);
+ 	  ipa_compute_jump_functions (cs);
+ 	}
+     }
+   pop_cfun ();
+   current_function_decl = NULL;
+ }
+ 
  /* Return scale for NODE.  */
  static inline gcov_type
  ipcp_get_node_scale (struct cgraph_node *node)
*************** constant_val_insert (tree parm1 ATTRIBUT
*** 377,387 ****
  static tree
  build_const_val (struct ipcp_lattice *lat, tree tree_type)
  {
!   tree const_val = NULL;
  
    gcc_assert (ipcp_lat_is_const (lat));
!   const_val = fold_convert (tree_type, lat->constant);
!   return const_val;
  }
  
  /* Build the tree representing the constant and call constant_val_insert().  */
--- 407,433 ----
  static tree
  build_const_val (struct ipcp_lattice *lat, tree tree_type)
  {
!   tree val;
  
    gcc_assert (ipcp_lat_is_const (lat));
!   val = lat->constant;
! 
!   /* compute_jump_functions inserts FUNCTION_DECL as value of parameter
!      when address of function is taken.  It would make more sense to pass
!      whole ADDR_EXPR, but for now compensate here.  */
!   if ((lat->type == IPA_CONST_VALUE
!         && TREE_CODE (val) == FUNCTION_DECL)
!       || lat->type == IPA_CONST_VALUE_REF)
!     return build_fold_addr_expr_with_type (val, tree_type);
! 
!   if (!useless_type_conversion_p (tree_type, TREE_TYPE (val)))
!     {
!       if (fold_convertible_p (tree_type, val))
! 	return fold_build1 (NOP_EXPR, tree_type, val);
!       else
! 	return fold_build1 (VIEW_CONVERT_EXPR, tree_type, val);
!     }
!   return val;
  }
  
  /* Build the tree representing the constant and call constant_val_insert().  */
*************** ipcp_init_stage (void)
*** 456,461 ****
--- 502,509 ----
  	      /* Handle cases of functions with 
  	         a variable number of parameters.  */
  	      ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee));
+ 	      if (flag_indirect_inlining)
+ 	        ipa_compute_jump_functions (cs);
  	    }
  	  else
  	    ipa_compute_jump_functions (cs);
*************** ipcp_insert_stage (void)
*** 966,972 ****
--- 1014,1023 ----
  	  free_dominance_info (CDI_POST_DOMINATORS);
  	  pop_cfun ();
  	  current_function_decl = NULL;
+ 	  /* We've possibly introduced direct calls.  */
+ 	  ipcp_update_cloned_node (node1);
  	}
+ 
        if (dump_file)
  	dump_function_to_file (node1->decl, dump_file, dump_flags);
      }
*************** ipcp_insert_stage (void)
*** 978,996 ****
  static unsigned int
  ipcp_driver (void)
  {
-   if (dump_file)
-     fprintf (dump_file, "\nIPA constant propagation start:\n");
-   ipa_check_create_node_params ();
-   ipa_check_create_edge_args ();
-   ipa_register_cgraph_hooks ();
-   /* 1. Call the init stage to initialize 
-      the ipa_node_params and ipa_edge_args structures.  */
-   ipcp_init_stage ();
-   if (dump_file)
-     {
-       fprintf (dump_file, "\nIPA structures before propagation:\n");
-       ipcp_print_all_structures (dump_file);
-     }
    /* 2. Do the interprocedural propagation.  */
    ipcp_iterate_stage ();
    if (dump_file)
--- 1029,1034 ----
*************** ipcp_driver (void)
*** 1015,1020 ****
--- 1053,1077 ----
    return 0;
  }
  
+ /* Note function body size.  */
+ static void
+ ipcp_generate_summary (void)
+ {
+   if (dump_file)
+     fprintf (dump_file, "\nIPA constant propagation start:\n");
+   ipa_check_create_node_params ();
+   ipa_check_create_edge_args ();
+   ipa_register_cgraph_hooks ();
+   /* 1. Call the init stage to initialize 
+      the ipa_node_params and ipa_edge_args structures.  */
+   ipcp_init_stage ();
+   if (dump_file)
+     {
+       fprintf (dump_file, "\nIPA structures before propagation:\n");
+       ipcp_print_all_structures (dump_file);
+     }
+ }
+ 
  /* Gate for IPCP optimization.  */
  static bool
  cgraph_gate_cp (void)
*************** cgraph_gate_cp (void)
*** 1022,1031 ****
    return flag_ipa_cp;
  }
  
! struct simple_ipa_opt_pass pass_ipa_cp = 
  {
   {
!   SIMPLE_IPA_PASS,
    "cp",				/* name */
    cgraph_gate_cp,		/* gate */
    ipcp_driver,			/* execute */
--- 1079,1088 ----
    return flag_ipa_cp;
  }
  
! struct ipa_opt_pass pass_ipa_cp = 
  {
   {
!   IPA_PASS,
    "cp",				/* name */
    cgraph_gate_cp,		/* gate */
    ipcp_driver,			/* execute */
*************** struct simple_ipa_opt_pass pass_ipa_cp =
*** 1038,1042 ****
    0,				/* properties_destroyed */
    0,				/* todo_flags_start */
    TODO_dump_cgraph | TODO_dump_func	/* todo_flags_finish */
!  }
  };
--- 1095,1106 ----
    0,				/* properties_destroyed */
    0,				/* todo_flags_start */
    TODO_dump_cgraph | TODO_dump_func	/* todo_flags_finish */
!  },
!  ipcp_generate_summary,			/* generate_summary */
!  NULL,					/* write_summary */
!  NULL,					/* read_summary */
!  NULL,					/* function_read_summary */
!  0,					/* TODOs */
!  NULL,					/* function_transform */
!  NULL,					/* variable_transform */
  };
Index: tree-ssa-ccp.c
===================================================================
*** tree-ssa-ccp.c	(revision 139234)
--- tree-ssa-ccp.c	(working copy)
*************** fold_stmt_r (tree *expr_p, int *walk_sub
*** 2300,2305 ****
--- 2300,2306 ----
        *walk_subtrees = 0;
  
        if (POINTER_TYPE_P (TREE_TYPE (expr))
+           && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (expr)))
  	  && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
  	  && (t = maybe_fold_offset_to_address (TREE_OPERAND (expr, 0),
  						integer_zero_node,
Index: ipa-inline.c
===================================================================
*** ipa-inline.c	(revision 139234)
--- ipa-inline.c	(working copy)
*************** inline_indirect_intraprocedural_analysis
*** 1633,1651 ****
  {
    struct cgraph_edge *cs;
  
!   ipa_count_formal_params (node);
!   ipa_create_param_decls_array (node);
!   ipa_detect_param_modifications (node);
    ipa_analyze_params_uses (node);
  
    if (dump_file)
      ipa_print_node_param_flags (dump_file, node);
  
!   for (cs = node->callees; cs; cs = cs->next_callee)
!     {
!       ipa_count_arguments (cs);
!       ipa_compute_jump_functions (cs);
!     }
  
    if (dump_file)
      ipa_print_node_jump_functions (dump_file, node);
--- 1633,1655 ----
  {
    struct cgraph_edge *cs;
  
!   if (!flag_ipa_cp)
!     {
!       ipa_count_formal_params (node);
!       ipa_create_param_decls_array (node);
!       ipa_detect_param_modifications (node);
!     }
    ipa_analyze_params_uses (node);
  
    if (dump_file)
      ipa_print_node_param_flags (dump_file, node);
  
!   if (!flag_ipa_cp)
!     for (cs = node->callees; cs; cs = cs->next_callee)
!       {
! 	ipa_count_arguments (cs);
! 	ipa_compute_jump_functions (cs);
!       }
  
    if (dump_file)
      ipa_print_node_jump_functions (dump_file, node);
*************** inline_generate_summary (void)
*** 1660,1666 ****
    int nnodes = cgraph_postorder (order);
    int i;
  
!   if (flag_indirect_inlining)
      {
        ipa_register_cgraph_hooks ();
        ipa_check_create_node_params ();
--- 1664,1670 ----
    int nnodes = cgraph_postorder (order);
    int i;
  
!   if (flag_indirect_inlining && !flag_ipa_cp)
      {
        ipa_register_cgraph_hooks ();
        ipa_check_create_node_params ();
Index: ipa-prop.c
===================================================================
*** ipa-prop.c	(revision 139234)
--- ipa-prop.c	(working copy)
*************** ipa_count_arguments (struct cgraph_edge 
*** 238,243 ****
--- 238,247 ----
    stmt = cs->call_stmt;
    gcc_assert (is_gimple_call (stmt));
    arg_num = gimple_call_num_args (stmt);
+   if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
+       <= (unsigned) cgraph_edge_max_uid)
+     VEC_safe_grow_cleared (ipa_edge_args_t, heap,
+ 			   ipa_edge_args_vector, cgraph_edge_max_uid + 1);
    ipa_set_cs_argument_count (IPA_EDGE_REF (cs), arg_num);
  }
  
Index: tree-inline.c
===================================================================
*** tree-inline.c	(revision 139234)
--- tree-inline.c	(working copy)
*************** remap_ssa_name (tree name, copy_body_dat
*** 161,167 ****
  
    n = (tree *) pointer_map_contains (id->decl_map, name);
    if (n)
!     return *n;
  
    /* Do not set DEF_STMT yet as statement is not copied yet. We do that
       in copy_bb.  */
--- 161,167 ----
  
    n = (tree *) pointer_map_contains (id->decl_map, name);
    if (n)
!     return unshare_expr (*n);
  
    /* Do not set DEF_STMT yet as statement is not copied yet. We do that
       in copy_bb.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]