public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jan Hubicka <hubicka@ucw.cz>
To: gcc-patches@gcc.gnu.org
Subject: Propagate will_be_nonconstant in ipa-analysis
Date: Thu, 28 Apr 2011 12:42:00 -0000	[thread overview]
Message-ID: <20110428111604.GC1199@kam.mff.cuni.cz> (raw)


Hi,
tthis patch makes inliner to handle nested expressions when trying to figure out what
will be constant after inlining.  This is done by simple propagation across SSA names.
We can't really handle PHIs well, since we know name will be constant, but we don't know
what, so this is a lot weakter than SCCP, should be enough for cases inliner is interested in.

We would get better results running this in DFS order, but at the momemnt we don't have any
funcition computing it when cfun is not set.  I will do that incrementally.

Bootstrapped/regtested x86_64-linux, will commit it later today.

Honza

	* ipa-inline-analysis.c (will_be_nonconstant_predicate): Take nonconstant_names
	array.
	(estimate_function_body_sizes): Build nonconstant_names array; handle
	BUILT_IN_CONSTANT_P.
Index: ipa-inline-analysis.c
===================================================================
*** ipa-inline-analysis.c	(revision 173042)
--- ipa-inline-analysis.c	(working copy)
*************** edge_execution_predicate (struct ipa_nod
*** 931,940 ****
  			gimple_cond_rhs (last));
  }
  
  static struct predicate
  will_be_nonconstant_predicate (struct ipa_node_params *info,
  			       struct inline_summary *summary,
! 			       gimple stmt)
  {
    struct predicate p = true_predicate ();
    ssa_op_iter iter;
--- 931,953 ----
  			gimple_cond_rhs (last));
  }
  
+ 
+ /* We keep info about constantness of SSA names.  */
+ 
+ typedef struct predicate predicate_t;
+ DEF_VEC_O (predicate_t);
+ DEF_VEC_ALLOC_O (predicate_t, heap);
+ 
+ 
+ /* Return predicate specifying when the STMT might have result that is not a compile
+    time constant.  */
+ 
  static struct predicate
  will_be_nonconstant_predicate (struct ipa_node_params *info,
  			       struct inline_summary *summary,
! 			       gimple stmt,
! 			       VEC (predicate_t, heap) *nonconstant_names)
! 			      
  {
    struct predicate p = true_predicate ();
    ssa_op_iter iter;
*************** will_be_nonconstant_predicate (struct ip
*** 949,955 ****
        && gimple_code (stmt) != GIMPLE_SWITCH)
      return p;
  
!   /* Stores and loads will stay anyway.  */
    if (gimple_vuse (stmt))
      return p;
  
--- 962,969 ----
        && gimple_code (stmt) != GIMPLE_SWITCH)
      return p;
  
!   /* Stores and loads will stay anyway.
!      TODO: Constant memory accesses could be handled here, too.  */
    if (gimple_vuse (stmt))
      return p;
  
*************** will_be_nonconstant_predicate (struct ip
*** 957,977 ****
       adding conditionals.  */
    FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
      {
!       /* TODO: handle nested expressions and constant
! 	 array accesses.  */
!       if (TREE_CODE (use) != SSA_NAME
! 	  || !SSA_NAME_IS_DEFAULT_DEF (use)
! 	  || ipa_get_param_decl_index (info, SSA_NAME_VAR (use)) < 0)
  	return p;
      }
    op_non_const = false_predicate ();
    FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
      {
!       p = add_condition (summary,
! 			 ipa_get_param_decl_index (info, SSA_NAME_VAR (use)),
! 			 IS_NOT_CONSTANT, NULL);
        op_non_const = or_predicates (&p, &op_non_const);
      }
    return op_non_const;
  }
  
--- 971,1006 ----
       adding conditionals.  */
    FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
      {
!       if (TREE_CODE (use) != SSA_NAME)
  	return p;
+       /* For arguments we can build a condition.  */
+       if (SSA_NAME_IS_DEFAULT_DEF (use)
+ 	  && ipa_get_param_decl_index (info, SSA_NAME_VAR (use)) >= 0)
+ 	continue;
+       /* If we know when operand is constant,
+ 	 we still can say something useful.  */
+       if (!true_predicate_p (VEC_index (predicate_t, nonconstant_names,
+ 					SSA_NAME_VERSION (use))))
+ 	continue;
+       return p;
      }
    op_non_const = false_predicate ();
    FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
      {
!       if (SSA_NAME_IS_DEFAULT_DEF (use)
! 	  && ipa_get_param_decl_index (info, SSA_NAME_VAR (use)) >= 0)
! 	p = add_condition (summary,
! 			   ipa_get_param_decl_index (info, SSA_NAME_VAR (use)),
! 			   IS_NOT_CONSTANT, NULL);
!       else
! 	p = *VEC_index (predicate_t, nonconstant_names,
! 			SSA_NAME_VERSION (use));
        op_non_const = or_predicates (&p, &op_non_const);
      }
+   if (gimple_code (stmt) == GIMPLE_ASSIGN
+       && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
+     VEC_replace (predicate_t, nonconstant_names,
+ 		 SSA_NAME_VERSION (gimple_assign_lhs (stmt)), &op_non_const);
    return op_non_const;
  }
  
*************** estimate_function_body_sizes (struct cgr
*** 994,1002 ****
    int freq;
    struct inline_summary *info = inline_summary (node);
    struct predicate bb_predicate;
!   struct ipa_node_params *parms_info;
  
!   parms_info = ipa_node_params_vector && !early ? IPA_NODE_REF (node) : NULL;
  
    info->conds = 0;
    info->entry = 0;
--- 1023,1037 ----
    int freq;
    struct inline_summary *info = inline_summary (node);
    struct predicate bb_predicate;
!   struct ipa_node_params *parms_info = NULL;
!   VEC (predicate_t, heap) *nonconstant_names = NULL;
  
!   if (ipa_node_params_vector && !early && optimize)
!     {
!       parms_info = IPA_NODE_REF (node);
!       VEC_safe_grow_cleared (predicate_t, heap, nonconstant_names,
! 			     VEC_length (tree, SSANAMES (my_function)));
!     }
  
    info->conds = 0;
    info->entry = 0;
*************** estimate_function_body_sizes (struct cgr
*** 1014,1020 ****
    bb_predicate = not_inlined_predicate ();
    account_size_time (info, 2 * INLINE_SIZE_SCALE, 0, &bb_predicate);
  
- 
    gcc_assert (my_function && my_function->cfg);
    FOR_EACH_BB_FN (bb, my_function)
      {
--- 1049,1054 ----
*************** estimate_function_body_sizes (struct cgr
*** 1063,1068 ****
--- 1097,1115 ----
  	      struct cgraph_edge *edge = cgraph_edge (node, stmt);
  	      struct inline_edge_summary *es = inline_edge_summary (edge);
  
+ 	      /* Special case: results of BUILT_IN_CONSTANT_P will be always
+ 		 resolved as constant.  We however don't want to optimize
+ 		 out the cgraph edges.  */
+ 	      if (nonconstant_names
+ 		  && gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P)
+ 		  && gimple_call_lhs (stmt)
+ 		  && TREE_CODE (gimple_call_lhs (stmt)) == SSA_NAME)
+ 		{
+ 		  struct predicate false_p = false_predicate ();
+ 		  VEC_replace (predicate_t, nonconstant_names,
+ 			       SSA_NAME_VERSION (gimple_call_lhs (stmt)), &false_p);
+ 		}
+ 
  	      es->call_stmt_size = this_size;
  	      es->call_stmt_time = this_time;
  	      es->loop_depth = bb->loop_depth;
*************** estimate_function_body_sizes (struct cgr
*** 1098,1104 ****
  	      if (parms_info)
  		{
  		  will_be_nonconstant
! 		     = will_be_nonconstant_predicate (parms_info, info, stmt);
  		  p = and_predicates (&bb_predicate, &will_be_nonconstant);
  		}
  	      else
--- 1145,1152 ----
  	      if (parms_info)
  		{
  		  will_be_nonconstant
! 		     = will_be_nonconstant_predicate (parms_info, info,
! 						      stmt, nonconstant_names);
  		  p = and_predicates (&bb_predicate, &will_be_nonconstant);
  		}
  	      else
*************** estimate_function_body_sizes (struct cgr
*** 1131,1136 ****
--- 1179,1185 ----
      time = MAX_TIME;
    inline_summary (node)->self_time = time;
    inline_summary (node)->self_size = size;
+   VEC_free (predicate_t, heap, nonconstant_names);
    if (dump_file)
      {
        fprintf (dump_file, "\n");

                 reply	other threads:[~2011-04-28 11:16 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110428111604.GC1199@kam.mff.cuni.cz \
    --to=hubicka@ucw.cz \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).