OSDN Git Service

* ipa-inline-transform.c (inline_call): Always update jump functions
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 22 Sep 2011 11:57:43 +0000 (11:57 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 22 Sep 2011 11:57:43 +0000 (11:57 +0000)
after inlining.
* ipa-inline.c (ipa_inline): Likewise; do not call
ipa_create_all_structures_for_iinln.
(ipa_inline): Always free jump functions.
* ipa-inline-analysis.c (evaluate_conditions_for_edge): Remove
hack.
(remap_edge_predicates): Fix pasto.
(inline_merge_summary): Remove nlined edge predicate; remove hack.
(inline_analyze_function): Always initialize jump functions.
(inline_generate_summary): Likewise.
(inline_write_summary): Always write jump functions when ipa-cp
is not doing that.
(inline_read_summary): Always read jump functions when ipa-cp
is not doing that.
* ipa-prop.c (iinlining_processed_edges): Remove.
(update_indirect_edges_after_inlining): Do not use
iinlining_processed_edges; instead set param_index to -1.
(propagate_info_to_inlined_callees): Only try to indirect inlining
when asked to do so; update jump functions of indirect calls, too;
remove jump functions of the inlined edge.
(ipa_edge_duplication_hook): Do not copy iinlining_processed_edges.
(ipa_create_all_structures_for_iinln): Remove.
(ipa_free_all_structures_after_iinln): Do not free
iinlining_processed_edges.
* ipa-prop.h (ipa_create_all_structures_for_iinln): Remove.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@179083 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 7291c09..d5cd52f 100644 (file)
@@ -1,3 +1,32 @@
+2011-09-22  Jan Hubicka  <jh@suse.cz>
+
+       * ipa-inline-transform.c (inline_call): Always update jump functions
+       after inlining.
+       * ipa-inline.c (ipa_inline): Likewise; do not call
+       ipa_create_all_structures_for_iinln.
+       (ipa_inline): Always free jump functions.
+       * ipa-inline-analysis.c (evaluate_conditions_for_edge): Remove
+       hack.
+       (remap_edge_predicates): Fix pasto.
+       (inline_merge_summary): Remove nlined edge predicate; remove hack.
+       (inline_analyze_function): Always initialize jump functions.
+       (inline_generate_summary): Likewise.
+       (inline_write_summary): Always write jump functions when ipa-cp
+       is not doing that.
+       (inline_read_summary): Always read jump functions when ipa-cp
+       is not doing that.
+       * ipa-prop.c (iinlining_processed_edges): Remove.
+       (update_indirect_edges_after_inlining): Do not use
+       iinlining_processed_edges; instead set param_index to -1.
+       (propagate_info_to_inlined_callees): Only try to indirect inlining
+       when asked to do so; update jump functions of indirect calls, too;
+       remove jump functions of the inlined edge.
+       (ipa_edge_duplication_hook): Do not copy iinlining_processed_edges.
+       (ipa_create_all_structures_for_iinln): Remove.
+       (ipa_free_all_structures_after_iinln): Do not free
+       iinlining_processed_edges.
+       * ipa-prop.h (ipa_create_all_structures_for_iinln): Remove.
+
 2011-09-22  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * config/arm/predicates.md (expandable_comparison_operator): New
index 3437c1c..5047424 100644 (file)
@@ -619,10 +619,7 @@ evaluate_conditions_for_edge (struct cgraph_edge *e, bool inline_p)
   struct inline_summary *info = inline_summary (callee);
   int i;
 
-  if (ipa_node_params_vector && info->conds
-      /* FIXME: it seems that we forget to get argument count in some cases,
-        probaby for previously indirect edges or so.  */
-      && ipa_get_cs_argument_count (IPA_EDGE_REF (e)))
+  if (ipa_node_params_vector && info->conds)
     {
       struct ipa_node_params *parms_info;
       struct ipa_edge_args *args = IPA_EDGE_REF (e);
@@ -634,7 +631,8 @@ evaluate_conditions_for_edge (struct cgraph_edge *e, bool inline_p)
       else
         parms_info = IPA_NODE_REF (e->caller);
 
-      VEC_safe_grow_cleared (tree, heap, known_vals, count);
+      if (count)
+        VEC_safe_grow_cleared (tree, heap, known_vals, count);
       for (i = 0; i < count; i++)
        {
          tree cst = ipa_cst_from_jfunc (parms_info,
@@ -2062,26 +2060,29 @@ remap_edge_predicates (struct cgraph_node *node,
     {
       struct inline_edge_summary *es = inline_edge_summary (e);
       struct predicate p;
-      if (es->predicate)
+      if (e->inline_failed)
        {
-         p = remap_predicate (info, callee_info,
-                              es->predicate, operand_map, possible_truths,
-                              toplev_predicate);
-         edge_set_predicate (e, &p);
-         /* TODO: We should remove the edge for code that will be optimized out,
-            but we need to keep verifiers and tree-inline happy.
-            Make it cold for now.  */
-         if (false_predicate_p (&p))
+         if (es->predicate)
            {
-             e->count = 0;
-             e->frequency = 0;
+             p = remap_predicate (info, callee_info,
+                                  es->predicate, operand_map, possible_truths,
+                                  toplev_predicate);
+             edge_set_predicate (e, &p);
+             /* TODO: We should remove the edge for code that will be optimized out,
+                but we need to keep verifiers and tree-inline happy.
+                Make it cold for now.  */
+             if (false_predicate_p (&p))
+               {
+                 e->count = 0;
+                 e->frequency = 0;
+               }
            }
+         else
+           edge_set_predicate (e, toplev_predicate);
        }
-      if (!e->inline_failed)
+      else
        remap_edge_predicates (e->callee, info, callee_info, operand_map,
                               possible_truths, toplev_predicate);
-      else
-       edge_set_predicate (e, toplev_predicate);
     }
   for (e = node->indirect_calls; e; e = e->next_callee)
     {
@@ -2122,6 +2123,7 @@ inline_merge_summary (struct cgraph_edge *edge)
   VEC (int, heap) *operand_map = NULL;
   int i;
   struct predicate toplev_predicate;
+  struct predicate true_p = true_predicate ();
   struct inline_edge_summary *es = inline_edge_summary (edge);
 
   if (es->predicate)
@@ -2129,18 +2131,15 @@ inline_merge_summary (struct cgraph_edge *edge)
   else
     toplev_predicate = true_predicate ();
 
-  if (ipa_node_params_vector && callee_info->conds
-      /* FIXME: it seems that we forget to get argument count in some cases,
-        probaby for previously indirect edges or so.
-        Removing the test leads to ICE on tramp3d.  */
-      && ipa_get_cs_argument_count (IPA_EDGE_REF (edge)))
+  if (ipa_node_params_vector && callee_info->conds)
     {
       struct ipa_edge_args *args = IPA_EDGE_REF (edge);
       int count = ipa_get_cs_argument_count (args);
       int i;
 
       clause = evaluate_conditions_for_edge (edge, true);
-      VEC_safe_grow_cleared (int, heap, operand_map, count);
+      if (count)
+        VEC_safe_grow_cleared (int, heap, operand_map, count);
       for (i = 0; i < count; i++)
        {
          struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
@@ -2176,6 +2175,9 @@ inline_merge_summary (struct cgraph_edge *edge)
   inline_update_callee_summaries (edge->callee,
                                  inline_edge_summary (edge)->loop_depth);
 
+  /* We do not maintain predicates of inlined edges, free it.  */
+  edge_set_predicate (edge, &true_p);
+
   info->time = (info->time + INLINE_TIME_SCALE / 2) / INLINE_TIME_SCALE;
   info->size = (info->size + INLINE_SIZE_SCALE / 2) / INLINE_SIZE_SCALE;
 }
@@ -2389,9 +2391,7 @@ inline_analyze_function (struct cgraph_node *node)
   if (dump_file)
     fprintf (dump_file, "\nAnalyzing function: %s/%u\n",
             cgraph_node_name (node), node->uid);
-  /* FIXME: We should remove the optimize check after we ensure we never run
-     IPA passes when not optimizing.  */
-  if (flag_indirect_inlining && optimize && !node->thunk.thunk_p)
+  if (optimize && !node->thunk.thunk_p)
     inline_indirect_intraprocedural_analysis (node);
   compute_inline_parameters (node, false);
 
@@ -2419,8 +2419,7 @@ inline_generate_summary (void)
   function_insertion_hook_holder =
       cgraph_add_function_insertion_hook (&add_new_function, NULL);
 
-  if (flag_indirect_inlining)
-    ipa_register_cgraph_hooks ();
+  ipa_register_cgraph_hooks ();
 
   FOR_EACH_DEFINED_FUNCTION (node)
     if (!node->alias)
@@ -2572,7 +2571,7 @@ inline_read_summary (void)
           this should never happen.  */
        fatal_error ("ipa inline summary is missing in input file");
     }
-  if (flag_indirect_inlining)
+  if (optimize)
     {
       ipa_register_cgraph_hooks ();
       if (!flag_ipa_cp)
@@ -2676,7 +2675,7 @@ inline_write_summary (cgraph_node_set set,
   produce_asm (ob, NULL);
   destroy_output_block (ob);
 
-  if (flag_indirect_inlining && !flag_ipa_cp)
+  if (optimize && !flag_ipa_cp)
     ipa_prop_write_jump_functions (set);
 }
 
index 600eb0d..2609e42 100644 (file)
@@ -248,7 +248,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
     *overall_size += new_size - old_size;
   ncalls_inlined++;
 
-  if (flag_indirect_inlining && optimize)
+  if (optimize)
     return ipa_propagate_indirect_call_infos (curr, new_edges);
   else
     return false;
index 304a4df..f069914 100644 (file)
@@ -1659,10 +1659,8 @@ ipa_inline (void)
     XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
   int i;
 
-  if (in_lto_p && flag_indirect_inlining)
+  if (in_lto_p && optimize)
     ipa_update_after_lto_read ();
-  if (flag_indirect_inlining)
-    ipa_create_all_structures_for_iinln ();
 
   if (dump_file)
     dump_inline_summaries (dump_file);
@@ -1757,7 +1755,7 @@ ipa_inline (void)
     }
 
   /* Free ipa-prop structures if they are no longer needed.  */
-  if (flag_indirect_inlining)
+  if (optimize)
     ipa_free_all_structures_after_iinln ();
 
   if (dump_file)
index 066bbdb..52f583a 100644 (file)
@@ -56,10 +56,6 @@ VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
 /* Vector where the parameter infos are actually stored. */
 VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector;
 
-/* Bitmap with all UIDs of call graph edges that have been already processed
-   by indirect inlining.  */
-static bitmap iinlining_processed_edges;
-
 /* Holders of ipa cgraph hooks: */
 static struct cgraph_edge_hook_list *edge_removal_hook_holder;
 static struct cgraph_node_hook_list *node_removal_hook_holder;
@@ -1699,18 +1695,14 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
       struct ipa_jump_func *jfunc;
 
       next_ie = ie->next_callee;
-      if (bitmap_bit_p (iinlining_processed_edges, ie->uid))
-       continue;
 
-      /* If we ever use indirect edges for anything other than indirect
-        inlining, we will need to skip those with negative param_indices. */
       if (ici->param_index == -1)
        continue;
 
       /* We must check range due to calls with variable number of arguments:  */
       if (ici->param_index >= ipa_get_cs_argument_count (top))
        {
-         bitmap_set_bit (iinlining_processed_edges, ie->uid);
+         ici->param_index = -1;
          continue;
        }
 
@@ -1725,7 +1717,10 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
        }
       else
        /* Either we can find a destination for this edge now or never. */
-       bitmap_set_bit (iinlining_processed_edges, ie->uid);
+       ici->param_index = -1;
+
+      if (!flag_indirect_inlining)
+       continue;
 
       if (ici->polymorphic)
        new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc);
@@ -1771,6 +1766,8 @@ propagate_info_to_inlined_callees (struct cgraph_edge *cs,
       res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
     else
       update_jump_functions_after_inlining (cs, e);
+  for (e = node->indirect_calls; e; e = e->next_callee)
+    update_jump_functions_after_inlining (cs, e);
 
   return res;
 }
@@ -1785,13 +1782,19 @@ bool
 ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
                                   VEC (cgraph_edge_p, heap) **new_edges)
 {
+  bool changed;
   /* Do nothing if the preparation phase has not been carried out yet
      (i.e. during early inlining).  */
   if (!ipa_node_params_vector)
     return false;
   gcc_assert (ipa_edge_args_vector);
 
-  return propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
+  changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
+
+  /* We do not keep jump functions of inlined edges up to date. Better to free
+     them so we do not access them accidentally.  */
+  ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
+  return changed;
 }
 
 /* Frees all dynamically allocated structures that the argument info points
@@ -1889,10 +1892,6 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 
   new_args->jump_functions = VEC_copy (ipa_jump_func_t, gc,
                                       old_args->jump_functions);
-
-  if (iinlining_processed_edges
-      && bitmap_bit_p (iinlining_processed_edges, src->uid))
-    bitmap_set_bit (iinlining_processed_edges, dst->uid);
 }
 
 /* Hook that is called by cgraph.c when a node is duplicated.  */
@@ -1963,21 +1962,13 @@ ipa_unregister_cgraph_hooks (void)
   function_insertion_hook_holder = NULL;
 }
 
-/* Allocate all necessary data structures necessary for indirect inlining.  */
-
-void
-ipa_create_all_structures_for_iinln (void)
-{
-  iinlining_processed_edges = BITMAP_ALLOC (NULL);
-}
-
 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
    longer needed after ipa-cp.  */
 
 void
 ipa_free_all_structures_after_ipa_cp (void)
 {
-  if (!flag_indirect_inlining)
+  if (!optimize)
     {
       ipa_free_all_edge_args ();
       ipa_free_all_node_params ();
@@ -1993,8 +1984,6 @@ ipa_free_all_structures_after_ipa_cp (void)
 void
 ipa_free_all_structures_after_iinln (void)
 {
-  BITMAP_FREE (iinlining_processed_edges);
-
   ipa_free_all_edge_args ();
   ipa_free_all_node_params ();
   ipa_unregister_cgraph_hooks ();
index fafd17d..1b7ba69 100644 (file)
@@ -282,7 +282,6 @@ void ipa_free_edge_args_substructures (struct ipa_edge_args *);
 void ipa_free_node_params_substructures (struct ipa_node_params *);
 void ipa_free_all_node_params (void);
 void ipa_free_all_edge_args (void);
-void ipa_create_all_structures_for_iinln (void);
 void ipa_free_all_structures_after_ipa_cp (void);
 void ipa_free_all_structures_after_iinln (void);
 void ipa_register_cgraph_hooks (void);