Limit AA walking when inlining analysis examines parameters
authorPaolo Bonzini <bonzini@gnu.org>
Wed, 15 Jul 2015 15:58:43 +0000 (15:58 +0000)
committerMartin Jambor <jamborm@gcc.gnu.org>
Wed, 15 Jul 2015 15:58:43 +0000 (17:58 +0200)
2015-07-15  Paolo Bonzini  <bonzini@gnu.org>
    Martin Jambor  <mjambor@suse.cz>

* ipa-inline-analysis.c (unmodified_parm_or_parm_agg_item): Accept
struct func_body_info* instead of struct ipa_node_params*, expecting
fbi->info to be filled in.  Replace throughout.  Adjust call to
ipa_load_from_parm_agg.
(set_cond_stmt_execution_predicate): Accept struct func_body_info*
instead of struct ipa_node_params*.  Adjust calls to other functions
so that they pass either fbi or fbi->info.
(set_switch_stmt_execution_predicate): Likewise.
(will_be_nonconstant_predicate): Likewise.
(compute_bb_predicates): Likewise.
(estimate_function_body_sizes): Move asserts earlier.  Fill in
struct func_body_info, replace parms_info with fbi.info.  Adjust
calls to functions that now accept struct func_body_info.
* ipa-prop.c (param_aa_status, struct ipa_bb_info): Move to ipa-prop.h.
(struct func_body_info): Likewise.
(ipa_load_from_parm_agg_1): Rename to ipa_load_from_parm_agg,
remove static.  Adjust callers.
(ipa_load_from_parm_agg): Remove.
* ipa-prop.h (param_aa_status, ipa_bb_info): Move from ipa-prop.c.
(func_body_info): Likewise.
(ipa_load_from_parm_agg): Adjust prototype.

Co-Authored-By: Martin Jambor <mjambor@suse.cz>
From-SVN: r225838

gcc/ChangeLog
gcc/ipa-inline-analysis.c
gcc/ipa-prop.c
gcc/ipa-prop.h

index b6ee390d3bb959c7a27c2d78be8e29a2cf773dc5..a2ce483c774f7ec9a7c278b4600633f189b28cbb 100644 (file)
@@ -1,3 +1,28 @@
+2015-07-15  Paolo Bonzini  <bonzini@gnu.org>
+           Martin Jambor  <mjambor@suse.cz>
+
+       * ipa-inline-analysis.c (unmodified_parm_or_parm_agg_item): Accept
+       struct func_body_info* instead of struct ipa_node_params*, expecting
+       fbi->info to be filled in.  Replace throughout.  Adjust call to
+       ipa_load_from_parm_agg.
+       (set_cond_stmt_execution_predicate): Accept struct func_body_info*
+       instead of struct ipa_node_params*.  Adjust calls to other functions
+       so that they pass either fbi or fbi->info.
+       (set_switch_stmt_execution_predicate): Likewise.
+       (will_be_nonconstant_predicate): Likewise.
+       (compute_bb_predicates): Likewise.
+       (estimate_function_body_sizes): Move asserts earlier.  Fill in
+       struct func_body_info, replace parms_info with fbi.info.  Adjust
+       calls to functions that now accept struct func_body_info.
+       * ipa-prop.c (param_aa_status, struct ipa_bb_info): Move to ipa-prop.h.
+       (struct func_body_info): Likewise.
+       (ipa_load_from_parm_agg_1): Rename to ipa_load_from_parm_agg,
+       remove static.  Adjust callers.
+       (ipa_load_from_parm_agg): Remove.
+       * ipa-prop.h (param_aa_status, ipa_bb_info): Move from ipa-prop.c.
+       (func_body_info): Likewise.
+       (ipa_load_from_parm_agg): Adjust prototype.
+
 2015-07-12  Trevor Saunders  <tbsaunde+gcc@tbsaunde.org>
 
        * gensupport.c (rtx_handle_directive): Adjust.
index d5dbfbd68879300c2cd302ec175315ffccee2652..81a6860f1146b03b6e04422ad09c024241f5bed2 100644 (file)
@@ -1574,7 +1574,7 @@ unmodified_parm (gimple stmt, tree op)
    loaded.  */
 
 static bool
-unmodified_parm_or_parm_agg_item (struct ipa_node_params *info,
+unmodified_parm_or_parm_agg_item (struct func_body_info *fbi,
                                  gimple stmt, tree op, int *index_p,
                                  struct agg_position_info *aggpos)
 {
@@ -1583,7 +1583,7 @@ unmodified_parm_or_parm_agg_item (struct ipa_node_params *info,
   gcc_checking_assert (aggpos);
   if (res)
     {
-      *index_p = ipa_get_param_decl_index (info, res);
+      *index_p = ipa_get_param_decl_index (fbi->info, res);
       if (*index_p < 0)
        return false;
       aggpos->agg_contents = false;
@@ -1599,13 +1599,14 @@ unmodified_parm_or_parm_agg_item (struct ipa_node_params *info,
       stmt = SSA_NAME_DEF_STMT (op);
       op = gimple_assign_rhs1 (stmt);
       if (!REFERENCE_CLASS_P (op))
-       return unmodified_parm_or_parm_agg_item (info, stmt, op, index_p,
+       return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p,
                                                 aggpos);
     }
 
   aggpos->agg_contents = true;
-  return ipa_load_from_parm_agg (info, stmt, op, index_p, &aggpos->offset,
-                                &aggpos->by_ref);
+  return ipa_load_from_parm_agg (fbi, fbi->info->descriptors,
+                                stmt, op, index_p, &aggpos->offset,
+                                NULL, &aggpos->by_ref);
 }
 
 /* See if statement might disappear after inlining.
@@ -1744,7 +1745,7 @@ eliminated_by_inlining_prob (gimple stmt)
    predicates to the CFG edges.   */
 
 static void
-set_cond_stmt_execution_predicate (struct ipa_node_params *info,
+set_cond_stmt_execution_predicate (struct func_body_info *fbi,
                                   struct inline_summary *summary,
                                   basic_block bb)
 {
@@ -1767,7 +1768,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
   /* TODO: handle conditionals like
      var = op0 < 4;
      if (var != 0).  */
-  if (unmodified_parm_or_parm_agg_item (info, last, op, &index, &aggpos))
+  if (unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos))
     {
       code = gimple_cond_code (last);
       inverted_code = invert_tree_comparison (code, HONOR_NANS (op));
@@ -1810,8 +1811,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
       || gimple_call_num_args (set_stmt) != 1)
     return;
   op2 = gimple_call_arg (set_stmt, 0);
-  if (!unmodified_parm_or_parm_agg_item
-      (info, set_stmt, op2, &index, &aggpos))
+  if (!unmodified_parm_or_parm_agg_item (fbi, set_stmt, op2, &index, &aggpos))
     return;
   FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE)
     {
@@ -1827,7 +1827,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
    predicates to the CFG edges.   */
 
 static void
-set_switch_stmt_execution_predicate (struct ipa_node_params *info,
+set_switch_stmt_execution_predicate (struct func_body_info *fbi,
                                     struct inline_summary *summary,
                                     basic_block bb)
 {
@@ -1845,7 +1845,7 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
     return;
   gswitch *last = as_a <gswitch *> (lastg);
   op = gimple_switch_index (last);
-  if (!unmodified_parm_or_parm_agg_item (info, last, op, &index, &aggpos))
+  if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos))
     return;
 
   FOR_EACH_EDGE (e, ei, bb->succs)
@@ -1888,8 +1888,8 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
    which it is executable.  */
 
 static void
-compute_bb_predicates (struct cgraph_node *node,
-                      struct ipa_node_params *parms_info,
+compute_bb_predicates (struct func_body_info *fbi,
+                      struct cgraph_node *node,
                       struct inline_summary *summary)
 {
   struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
@@ -1898,8 +1898,8 @@ compute_bb_predicates (struct cgraph_node *node,
 
   FOR_EACH_BB_FN (bb, my_function)
     {
-      set_cond_stmt_execution_predicate (parms_info, summary, bb);
-      set_switch_stmt_execution_predicate (parms_info, summary, bb);
+      set_cond_stmt_execution_predicate (fbi, summary, bb);
+      set_switch_stmt_execution_predicate (fbi, summary, bb);
     }
 
   /* Entry block is always executable.  */
@@ -2031,7 +2031,7 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
    a compile time constant.  */
 
 static struct predicate
-will_be_nonconstant_predicate (struct ipa_node_params *info,
+will_be_nonconstant_predicate (struct func_body_info *fbi,
                               struct inline_summary *summary,
                               gimple stmt,
                               vec<predicate_t> nonconstant_names)
@@ -2065,7 +2065,7 @@ will_be_nonconstant_predicate (struct ipa_node_params *info,
       tree op;
       gcc_assert (gimple_assign_single_p (stmt));
       op = gimple_assign_rhs1 (stmt);
-      if (!unmodified_parm_or_parm_agg_item (info, stmt, op, &base_index,
+      if (!unmodified_parm_or_parm_agg_item (fbi, stmt, op, &base_index,
                                             &aggpos))
        return p;
     }
@@ -2078,7 +2078,7 @@ will_be_nonconstant_predicate (struct ipa_node_params *info,
     {
       tree parm = unmodified_parm (stmt, use);
       /* For arguments we can build a condition.  */
-      if (parm && ipa_get_param_decl_index (info, parm) >= 0)
+      if (parm && ipa_get_param_decl_index (fbi->info, parm) >= 0)
        continue;
       if (TREE_CODE (use) != SSA_NAME)
        return p;
@@ -2099,7 +2099,7 @@ will_be_nonconstant_predicate (struct ipa_node_params *info,
       tree parm = unmodified_parm (stmt, use);
       int index;
 
-      if (parm && (index = ipa_get_param_decl_index (info, parm)) >= 0)
+      if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
        {
          if (index != base_index)
            p = add_condition (summary, index, NULL, CHANGED, NULL_TREE);
@@ -2481,13 +2481,17 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
   int freq;
   struct inline_summary *info = inline_summaries->get (node);
   struct predicate bb_predicate;
-  struct ipa_node_params *parms_info = NULL;
+  struct func_body_info fbi;
   vec<predicate_t> nonconstant_names = vNULL;
   int nblocks, n;
   int *order;
   predicate array_index = true_predicate ();
   gimple fix_builtin_expect_stmt;
 
+  gcc_assert (my_function && my_function->cfg);
+  gcc_assert (cfun == my_function);
+
+  memset(&fbi, 0, sizeof(fbi));
   info->conds = NULL;
   info->entry = NULL;
 
@@ -2510,7 +2514,11 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 
       if (ipa_node_params_sum)
        {
-         parms_info = IPA_NODE_REF (node);
+         fbi.node = node;
+         fbi.info = IPA_NODE_REF (node);
+         fbi.bb_infos = vNULL;
+         fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
+         fbi.param_count = count_formal_params(node->decl);
          nonconstant_names.safe_grow_cleared
            (SSANAMES (my_function)->length ());
        }
@@ -2528,10 +2536,8 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
   bb_predicate = not_inlined_predicate ();
   account_size_time (info, 2 * INLINE_SIZE_SCALE, 0, &bb_predicate);
 
-  gcc_assert (my_function && my_function->cfg);
-  if (parms_info)
-    compute_bb_predicates (node, parms_info, info);
-  gcc_assert (cfun == my_function);
+  if (fbi.info)
+    compute_bb_predicates (&fbi, node, info);
   order = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
   nblocks = pre_and_rev_post_order_compute (NULL, order, false);
   for (n = 0; n < nblocks; n++)
@@ -2548,7 +2554,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
        }
 
       /* TODO: Obviously predicates can be propagated down across CFG.  */
-      if (parms_info)
+      if (fbi.info)
        {
          if (bb->aux)
            bb_predicate = *(struct predicate *) bb->aux;
@@ -2564,7 +2570,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
          dump_predicate (dump_file, info->conds, &bb_predicate);
        }
 
-      if (parms_info && nonconstant_names.exists ())
+      if (fbi.info && nonconstant_names.exists ())
        {
          struct predicate phi_predicate;
          bool first_phi = true;
@@ -2573,7 +2579,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
               gsi_next (&bsi))
            {
              if (first_phi
-                 && !phi_result_unknown_predicate (parms_info, info, bb,
+                 && !phi_result_unknown_predicate (fbi.info, info, bb,
                                                    &phi_predicate,
                                                    nonconstant_names))
                break;
@@ -2682,9 +2688,9 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
          /* TODO: When conditional jump or swithc is known to be constant, but
             we did not translate it into the predicates, we really can account
             just maximum of the possible paths.  */
-         if (parms_info)
+         if (fbi.info)
            will_be_nonconstant
-             = will_be_nonconstant_predicate (parms_info, info,
+             = will_be_nonconstant_predicate (&fbi, info,
                                               stmt, nonconstant_names);
          if (this_time || this_size)
            {
@@ -2699,7 +2705,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
              if (prob == 2 && dump_file && (dump_flags & TDF_DETAILS))
                fprintf (dump_file, "\t\tWill be eliminated by inlining\n");
 
-             if (parms_info)
+             if (fbi.info)
                p = and_predicates (info->conds, &bb_predicate,
                                    &will_be_nonconstant);
              else
@@ -2767,7 +2773,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
                && !is_gimple_min_invariant (niter_desc.niter))
            {
              predicate will_be_nonconstant
-               = will_be_nonconstant_expr_predicate (parms_info, info,
+               = will_be_nonconstant_expr_predicate (fbi.info, info,
                                                      niter_desc.niter,
                                                      nonconstant_names);
              if (!true_predicate_p (&will_be_nonconstant))
@@ -2805,7 +2811,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
                        || is_gimple_min_invariant (iv.step))
                      continue;
                    will_be_nonconstant
-                     = will_be_nonconstant_expr_predicate (parms_info, info,
+                     = will_be_nonconstant_expr_predicate (fbi.info, info,
                                                            iv.step,
                                                            nonconstant_names);
                    if (!true_predicate_p (&will_be_nonconstant))
index 29178d4046f9dd57297684eb0353e43d835cc78b..615f749f8fdcc0ea22a14cf91197682c2cdc40ff 100644 (file)
@@ -70,57 +70,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "domwalk.h"
 #include "builtins.h"
 
-/* Intermediate information that we get from alias analysis about a particular
-   parameter in a particular basic_block.  When a parameter or the memory it
-   references is marked modified, we use that information in all dominatd
-   blocks without cosulting alias analysis oracle.  */
-
-struct param_aa_status
-{
-  /* Set when this structure contains meaningful information.  If not, the
-     structure describing a dominating BB should be used instead.  */
-  bool valid;
-
-  /* Whether we have seen something which might have modified the data in
-     question.  PARM is for the parameter itself, REF is for data it points to
-     but using the alias type of individual accesses and PT is the same thing
-     but for computing aggregate pass-through functions using a very inclusive
-     ao_ref.  */
-  bool parm_modified, ref_modified, pt_modified;
-};
-
-/* Information related to a given BB that used only when looking at function
-   body.  */
-
-struct ipa_bb_info
-{
-  /* Call graph edges going out of this BB.  */
-  vec<cgraph_edge *> cg_edges;
-  /* Alias analysis statuses of each formal parameter at this bb.  */
-  vec<param_aa_status> param_aa_statuses;
-};
-
-/* Structure with global information that is only used when looking at function
-   body. */
-
-struct func_body_info
-{
-  /* The node that is being analyzed.  */
-  cgraph_node *node;
-
-  /* Its info.  */
-  struct ipa_node_params *info;
-
-  /* Information about individual BBs. */
-  vec<ipa_bb_info> bb_infos;
-
-  /* Number of parameters.  */
-  int param_count;
-
-  /* Number of statements already walked by when analyzing this function.  */
-  unsigned int aa_walked;
-};
-
 /* Function summary where the parameter infos are actually stored. */
 ipa_node_params_t *ipa_node_params_sum = NULL;
 /* Vector of IPA-CP transformation data for each clone.  */
@@ -1010,12 +959,12 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
    within the aggregate and whether it is a load from a value passed by
    reference respectively.  */
 
-static bool
-ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
-                         vec<ipa_param_descriptor> descriptors,
-                         gimple stmt, tree op, int *index_p,
-                         HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
-                         bool *by_ref_p)
+bool
+ipa_load_from_parm_agg (struct func_body_info *fbi,
+                       vec<ipa_param_descriptor> descriptors,
+                       gimple stmt, tree op, int *index_p,
+                       HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
+                       bool *by_ref_p)
 {
   int index;
   HOST_WIDE_INT size, max_size;
@@ -1082,18 +1031,6 @@ ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
   return false;
 }
 
-/* Just like the previous function, just without the param_analysis_info
-   pointer, for users outside of this file.  */
-
-bool
-ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
-                       tree op, int *index_p, HOST_WIDE_INT *offset_p,
-                       bool *by_ref_p)
-{
-  return ipa_load_from_parm_agg_1 (NULL, info->descriptors, stmt, op, index_p,
-                                  offset_p, NULL, by_ref_p);
-}
-
 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
    of an assignment statement STMT, try to determine whether we are actually
    handling any of the following cases and construct an appropriate jump
@@ -1977,9 +1914,9 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gcall *call,
   int index;
   gimple def = SSA_NAME_DEF_STMT (target);
   if (gimple_assign_single_p (def)
-      && ipa_load_from_parm_agg_1 (fbi, info->descriptors, def,
-                                  gimple_assign_rhs1 (def), &index, &offset,
-                                  NULL, &by_ref))
+      && ipa_load_from_parm_agg (fbi, info->descriptors, def,
+                                gimple_assign_rhs1 (def), &index, &offset,
+                                NULL, &by_ref))
     {
       struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
       cs->indirect_info->offset = offset;
@@ -5192,8 +5129,8 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
       if (vce)
        continue;
 
-      if (!ipa_load_from_parm_agg_1 (m_fbi, m_descriptors, stmt, rhs, &index,
-                                    &offset, &size, &by_ref))
+      if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index,
+                                  &offset, &size, &by_ref))
        continue;
       for (v = m_aggval; v; v = v->next)
        if (v->index == index
index c4958948e8656e162cf949c48083ef98744aeea6..a6b26b8a4f6639aa3709b2092780f8051433dcc9 100644 (file)
@@ -336,6 +336,57 @@ struct ipa_node_params
   unsigned node_calling_single_call : 1;
 };
 
+/* Intermediate information that we get from alias analysis about a particular
+   parameter in a particular basic_block.  When a parameter or the memory it
+   references is marked modified, we use that information in all dominatd
+   blocks without cosulting alias analysis oracle.  */
+
+struct param_aa_status
+{
+  /* Set when this structure contains meaningful information.  If not, the
+     structure describing a dominating BB should be used instead.  */
+  bool valid;
+
+  /* Whether we have seen something which might have modified the data in
+     question.  PARM is for the parameter itself, REF is for data it points to
+     but using the alias type of individual accesses and PT is the same thing
+     but for computing aggregate pass-through functions using a very inclusive
+     ao_ref.  */
+  bool parm_modified, ref_modified, pt_modified;
+};
+
+/* Information related to a given BB that used only when looking at function
+   body.  */
+
+struct ipa_bb_info
+{
+  /* Call graph edges going out of this BB.  */
+  vec<cgraph_edge *> cg_edges;
+  /* Alias analysis statuses of each formal parameter at this bb.  */
+  vec<param_aa_status> param_aa_statuses;
+};
+
+/* Structure with global information that is only used when looking at function
+   body. */
+
+struct func_body_info
+{
+  /* The node that is being analyzed.  */
+  cgraph_node *node;
+
+  /* Its info.  */
+  struct ipa_node_params *info;
+
+  /* Information about individual BBs. */
+  vec<ipa_bb_info> bb_infos;
+
+  /* Number of parameters.  */
+  int param_count;
+
+  /* Number of statements already walked by when analyzing this function.  */
+  unsigned int aa_walked;
+};
+
 /* ipa_node_params access functions.  Please use these to access fields that
    are or will be shared among various passes.  */
 
@@ -585,8 +636,9 @@ void ipa_analyze_node (struct cgraph_node *);
 /* Aggregate jump function related functions.  */
 tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT,
                                 bool);
-bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *,
-                            HOST_WIDE_INT *, bool *);
+bool ipa_load_from_parm_agg (struct func_body_info *,
+                            vec<ipa_param_descriptor>, gimple, tree, int *,
+                            HOST_WIDE_INT *, HOST_WIDE_INT *, bool *);
 
 /* Debugging interface.  */
 void ipa_print_node_params (FILE *, struct cgraph_node *node);