cgraphbuild.c: Include ipa-inline.h.
authorJan Hubicka <jh@suse.cz>
Sat, 16 Apr 2011 09:13:08 +0000 (11:13 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 16 Apr 2011 09:13:08 +0000 (09:13 +0000)
* cgraphbuild.c: Include ipa-inline.h.
(reset_inline_failed): Use initialize_inline_failed.
* cgraph.c: Include ipa-inline.h.
(cgraph_create_node_1): Do not initialize estimated_growth.
(initialize_inline_failed): More to ipa-inline-analysis.c
(dump_cgraph_node): Do not dump inline flags.
* cgraph.h (cgraph_local_info): Remove inlineable, versionable
and disregard_inline_limits flags.
(cgrpah_global_info): Remove estimated_stack_size, stack_frame_offset,
time, size, estimated_growth.
* ipa-cp.c (ipcp_versionable_function_p, ipcp_generate_summary): Update.
* cgraphunit.c (cgraph_decide_is_function_needed): Use
DECL_DISREGARD_INLINE_LIMITS.
(cgraph_analyze_function): Do not initialize
node->local.disregard_inline_limits.
* lto-cgraph.c (lto_output_node, input_overwrite_node): Do not stream
inlinable, versionable and disregard_inline_limits.
* ipa-inline.c (cgraph_clone_inlined_nodes, cgraph_mark_inline_edge,
cgraph_check_inline_limits, cgraph_default_inline_p, cgraph_edge_badness,
update_caller_keys, update_callee_keys, add_new_edges_to_heap): Update.
(cgraph_decide_inlining_of_small_function): Update; set CIF_FUNCTION_NOT_INLINABLE
for uninlinable functions.
(cgraph_decide_inlining, cgraph_edge_early_inlinable_p,
cgraph_decide_inlining_incrementally): Update.
* ipa-inline.h (inline_summary): Add inlinable, versionable, disregard_inline_limits,
estimated_stack_size, stack_frame_offset, time, size and estimated_growth
parameters.
(estimate_edge_growth): Update.
(initialize_inline_failed): Declare.
* ipa-split.c: Include ipa-inline.h
(execute_split_functions): Update.
* ipa.c (cgraph_postorder): Use DECL_DISREGARD_INLINE_LIMITS.
(cgraph_remove_unreachable_nodes): Do not clear inlinable flag.
(record_cdtor_fn): Use DECL_DISREGARD_INLINE_LIMITS.
* ipa-inline-analysis.c (inline_node_removal_hook): Update; set
estimated_growth to INT_MIN.
(inline_node_duplication_hook): Likewise.
(dump_inline_summary): Dump new fields.
(compute_inline_parameters): Update.
(estimate_edge_time, estimate_time_after_inlining,
estimate_size_after_inlining, estimate_growth, inline_read_summary,
inline_write_summary):
(initialize_inline_failed): Move here from cgraph.c.
* tree-sra.c: Include ipa-inline.h.
(ipa_sra_preliminary_function_checks): Update.
* lto/lto.c (lto_balanced_map): Update.
Update.
* Makefile.in: (cgraph.o, cgraphbuild.o): Add dependency on
ipa-inline.h

From-SVN: r172581

16 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphbuild.c
gcc/cgraphunit.c
gcc/ipa-cp.c
gcc/ipa-inline-analysis.c
gcc/ipa-inline.c
gcc/ipa-inline.h
gcc/ipa-split.c
gcc/ipa.c
gcc/lto-cgraph.c
gcc/lto/ChangeLog
gcc/lto/lto.c
gcc/tree-sra.c

index e3a583af770ec0826ad9e9d52db0aa095da1ddef..237f2fda1ce8a82bb5bd130fcc70f630e649fe07 100644 (file)
@@ -1,3 +1,53 @@
+2011-04-16  Jan Hubicka  <jh@suse.cz>
+
+       * cgraphbuild.c: Include ipa-inline.h.
+       (reset_inline_failed): Use initialize_inline_failed.
+       * cgraph.c: Include ipa-inline.h.
+       (cgraph_create_node_1): Do not initialize estimated_growth.
+       (initialize_inline_failed): More to ipa-inline-analysis.c
+       (dump_cgraph_node): Do not dump inline flags.
+       * cgraph.h (cgraph_local_info): Remove inlineable, versionable
+       and disregard_inline_limits flags.
+       (cgrpah_global_info): Remove estimated_stack_size, stack_frame_offset,
+       time, size, estimated_growth.
+       * ipa-cp.c (ipcp_versionable_function_p, ipcp_generate_summary): Update.
+       * cgraphunit.c (cgraph_decide_is_function_needed): Use
+       DECL_DISREGARD_INLINE_LIMITS.
+       (cgraph_analyze_function): Do not initialize
+       node->local.disregard_inline_limits.
+       * lto-cgraph.c (lto_output_node, input_overwrite_node): Do not stream
+       inlinable, versionable and disregard_inline_limits.
+       * ipa-inline.c (cgraph_clone_inlined_nodes, cgraph_mark_inline_edge,
+       cgraph_check_inline_limits, cgraph_default_inline_p, cgraph_edge_badness,
+       update_caller_keys, update_callee_keys, add_new_edges_to_heap): Update.
+       (cgraph_decide_inlining_of_small_function): Update; set CIF_FUNCTION_NOT_INLINABLE
+       for uninlinable functions.
+       (cgraph_decide_inlining, cgraph_edge_early_inlinable_p,
+       cgraph_decide_inlining_incrementally): Update.
+       * ipa-inline.h (inline_summary): Add inlinable, versionable, disregard_inline_limits,
+       estimated_stack_size, stack_frame_offset, time, size and estimated_growth
+       parameters.
+       (estimate_edge_growth): Update.
+       (initialize_inline_failed): Declare.
+       * ipa-split.c: Include ipa-inline.h
+       (execute_split_functions): Update.
+       * ipa.c (cgraph_postorder): Use DECL_DISREGARD_INLINE_LIMITS.
+       (cgraph_remove_unreachable_nodes): Do not clear inlinable flag.
+       (record_cdtor_fn): Use DECL_DISREGARD_INLINE_LIMITS.
+       * ipa-inline-analysis.c (inline_node_removal_hook): Update; set
+       estimated_growth to INT_MIN.
+       (inline_node_duplication_hook): Likewise.
+       (dump_inline_summary): Dump new fields.
+       (compute_inline_parameters): Update.
+       (estimate_edge_time, estimate_time_after_inlining,
+       estimate_size_after_inlining, estimate_growth, inline_read_summary,
+       inline_write_summary):
+       (initialize_inline_failed): Move here from cgraph.c.
+       * tree-sra.c: Include ipa-inline.h.
+       (ipa_sra_preliminary_function_checks): Update.
+       * Makefile.in: (cgraph.o, cgraphbuild.o): Add dependency on
+       ipa-inline.h
+
 2011-04-16  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/sse.md (V16): New mode iterator.
index 04b10cd8cd920b47bc5c90218a66c0709467db27..f88d61d7bbcf7afde0e0c8a724d5e3012b0f257c 100644 (file)
@@ -2983,7 +2983,8 @@ cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    langhooks.h toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \
    gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
    $(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) cif-code.def \
-   value-prof.h $(EXCEPT_H) $(IPA_UTILS_H) $(DIAGNOSTIC_CORE_H)
+   value-prof.h $(EXCEPT_H) $(IPA_UTILS_H) $(DIAGNOSTIC_CORE_H) \
+   ipa-inline.h
 cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) \
    $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
@@ -2993,7 +2994,8 @@ cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    tree-pretty-print.h gimple-pretty-print.h
 cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \
-   $(TREE_FLOW_H) $(TREE_PASS_H) $(IPA_UTILS_H) $(EXCEPT_H)
+   $(TREE_FLOW_H) $(TREE_PASS_H) $(IPA_UTILS_H) $(EXCEPT_H) \
+   ipa-inline.h
 varpool.o : varpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) $(CGRAPH_H) langhooks.h $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) \
    $(GGC_H) $(TIMEVAR_H) debug.h $(TARGET_H) output.h $(GIMPLE_H) \
index 09436c7cfb575c4653f93e7094a050c348468d8f..31c5b59960a5e9f8f6e6be8dc5653ba57e3fa6b0 100644 (file)
@@ -98,6 +98,7 @@ The callgraph:
 #include "rtl.h"
 #include "ipa-utils.h"
 #include "lto-streamer.h"
+#include "ipa-inline.h"
 
 const char * const ld_plugin_symbol_resolution_names[]=
 {
@@ -476,7 +477,6 @@ cgraph_create_node_1 (void)
   if (cgraph_nodes)
     cgraph_nodes->previous = node;
   node->previous = NULL;
-  node->global.estimated_growth = INT_MIN;
   node->frequency = NODE_FREQUENCY_NORMAL;
   node->count_materialization_scale = REG_BR_PROB_BASE;
   ipa_empty_ref_list (&node->ref_list);
@@ -970,28 +970,6 @@ cgraph_create_edge_including_clones (struct cgraph_node *orig,
       }
 }
 
-/* Give initial reasons why inlining would fail on EDGE.  This gets either
-   nullified or usually overwritten by more precise reasons later.  */
-
-static void
-initialize_inline_failed (struct cgraph_edge *e)
-{
-  struct cgraph_node *callee = e->callee;
-
-  if (e->indirect_unknown_callee)
-    e->inline_failed = CIF_INDIRECT_UNKNOWN_CALL;
-  else if (!callee->analyzed)
-    e->inline_failed = CIF_BODY_NOT_AVAILABLE;
-  else if (callee->local.redefined_extern_inline)
-    e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
-  else if (!callee->local.inlinable)
-    e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
-  else if (e->call_stmt && gimple_call_cannot_inline_p (e->call_stmt))
-    e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
-  else
-    e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
-}
-
 /* Allocate a cgraph_edge structure and fill it with data according to the
    parameters of which only CALLEE can be NULL (when creating an indirect call
    edge).  */
@@ -1899,12 +1877,6 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
             ld_plugin_symbol_resolution_names[(int)node->resolution]);
   if (node->local.finalized)
     fprintf (f, " finalized");
-  if (node->local.disregard_inline_limits)
-    fprintf (f, " always_inline");
-  else if (node->local.inlinable)
-    fprintf (f, " inlinable");
-  else if (node->local.versionable)
-    fprintf (f, " versionable");
   if (node->local.redefined_extern_inline)
     fprintf (f, " redefined_extern_inline");
   if (TREE_ASM_WRITTEN (node->decl))
index eb5154638bc8fd653164a0c6f1891b159e62fc8f..199349b3991ca33ae70cc4de4b5e5d033d295705 100644 (file)
@@ -88,20 +88,10 @@ struct GTY(()) cgraph_local_info {
   /* Set once it has been finalized so we consider it to be output.  */
   unsigned finalized : 1;
 
-  /* False when there something makes inlining impossible (such as va_arg).  */
-  unsigned inlinable : 1;
-
-  /* False when there something makes versioning impossible.
-     Currently computed and used only by ipa-cp.  */
-  unsigned versionable : 1;
-
   /* False when function calling convention and signature can not be changed.
      This is the case when __builtin_apply_args is used.  */
   unsigned can_change_signature : 1;
 
-  /* True when function should be inlined independently on its size.  */
-  unsigned disregard_inline_limits : 1;
-
   /* True when the function has been originally extern inline, but it is
      redefined now.  */
   unsigned redefined_extern_inline : 1;
@@ -115,21 +105,9 @@ struct GTY(()) cgraph_local_info {
    once compilation is finished.  Available only with -funit-at-a-time.  */
 
 struct GTY(()) cgraph_global_info {
-  /* Estimated stack frame consumption by the function.  */
-  HOST_WIDE_INT estimated_stack_size;
-  /* Expected offset of the stack frame of inlined function.  */
-  HOST_WIDE_INT stack_frame_offset;
-
   /* For inline clones this points to the function they will be
      inlined into.  */
   struct cgraph_node *inlined_to;
-
-  /* Estimated size of the function after inlining.  */
-  int time;
-  int size;
-
-  /* Estimated growth after inlining.  INT_MIN if not computed.  */
-  int estimated_growth;
 };
 
 /* Information about the function that is propagated by the RTL backend.
index 935462eda83f995dd0ab3558d4cb6fcadee5f8a9..3a2cb676679ca47ff6fa1e1fbf066cb585e7420e 100644 (file)
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "ipa-utils.h"
 #include "except.h"
+#include "ipa-inline.h"
 
 /* Context of record_reference.  */
 struct record_reference_ctx
@@ -207,16 +208,7 @@ reset_inline_failed (struct cgraph_node *node)
   for (e = node->callers; e; e = e->next_caller)
     {
       e->callee->global.inlined_to = NULL;
-      if (!node->analyzed)
-       e->inline_failed = CIF_BODY_NOT_AVAILABLE;
-      else if (node->local.redefined_extern_inline)
-       e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
-      else if (!node->local.inlinable)
-       e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
-      else if (e->call_stmt_cannot_inline_p)
-       e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
-      else
-       e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
+      initialize_inline_failed (e);
     }
 }
 
index 539dbf98244dfc5a4e70273f4fa67352fb87f345..6b3ddb5562f145757b0d3453d5a889c69ea5ecf3 100644 (file)
@@ -172,7 +172,7 @@ cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
   if (flag_keep_inline_functions
       && DECL_DECLARED_INLINE_P (decl)
       && !DECL_EXTERNAL (decl)
-      && !lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl)))
+      && !DECL_DISREGARD_INLINE_LIMITS (decl))
      return true;
 
   /* If we decided it was needed before, but at the time we didn't have
@@ -191,7 +191,7 @@ cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
      to change the behavior here.  */
   if (((TREE_PUBLIC (decl)
        || (!optimize
-           && !node->local.disregard_inline_limits
+           && !DECL_DISREGARD_INLINE_LIMITS (decl)
            && !DECL_DECLARED_INLINE_P (decl)
            && !(DECL_CONTEXT (decl)
                 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)))
@@ -783,11 +783,6 @@ cgraph_analyze_function (struct cgraph_node *node)
 
   assign_assembler_name_if_neeeded (node->decl);
 
-  /* disregard_inline_limits affects topological order of the early optimization,
-     so we need to compute it ahead of rest of inline parameters.  */
-  node->local.disregard_inline_limits
-    = DECL_DISREGARD_INLINE_LIMITS (node->decl);
-
   /* Make sure to gimplify bodies only once.  During analyzing a
      function we lower it, which will require gimplified nested
      functions, so we can end up here with an already gimplified
index 4cee1d481e66bdcb711795b52b77c85a99d1c77d..5ec0b2c7acaa431ff91b698eea20a383bec3c097 100644 (file)
@@ -424,7 +424,7 @@ ipcp_versionable_function_p (struct cgraph_node *node)
   /* There are a number of generic reasons functions cannot be versioned.  We
      also cannot remove parameters if there are type attributes such as fnspec
      present.  */
-  if (!node->local.versionable
+  if (!inline_summary (node)->versionable
       || TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
     return false;
 
@@ -1577,7 +1577,7 @@ ipcp_generate_summary (void)
        /* Unreachable nodes should have been eliminated before ipcp.  */
        gcc_assert (node->needed || node->reachable);
 
-       node->local.versionable = tree_versionable_function_p (node->decl);
+       inline_summary (node)->versionable = tree_versionable_function_p (node->decl);
        ipa_analyze_node (node);
       }
 }
index 47bd2a8c1da1ab4ed4a64b89077786a3e402f020..6ab3e4733f73fbdc86bf6ac05c7ae2481fec1a76 100644 (file)
@@ -100,11 +100,13 @@ inline_summary_alloc (void)
 static void
 inline_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
 {
+  struct inline_summary *info;
   if (VEC_length (inline_summary_t, inline_summary_vec)
       <= (unsigned)node->uid)
     return;
-  memset (inline_summary (node),
-         0, sizeof (inline_summary_t));
+  info = inline_summary (node);
+  info->estimated_growth = INT_MIN;
+  memset (info, 0, sizeof (inline_summary_t));
 }
 
 /* Hook that is called by cgraph.c when a node is duplicated.  */
@@ -113,9 +115,12 @@ static void
 inline_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
                              ATTRIBUTE_UNUSED void *data)
 {
+  struct inline_summary *info;
   inline_summary_alloc ();
-  memcpy (inline_summary (dst), inline_summary (src),
+  info = inline_summary (dst);
+  memcpy (info, inline_summary (src),
          sizeof (struct inline_summary));
+  info->estimated_growth = INT_MIN;
 }
 
 static void
@@ -124,18 +129,24 @@ dump_inline_summary (FILE *f, struct cgraph_node *node)
   if (node->analyzed)
     {
       struct inline_summary *s = inline_summary (node);
-      fprintf (f, "Inline summary for %s/%i\n", cgraph_node_name (node),
+      fprintf (f, "Inline summary for %s/%i", cgraph_node_name (node),
               node->uid);
-      fprintf (f, "  self time:       %i, benefit: %i\n",
+      if (s->disregard_inline_limits)
+       fprintf (f, " always_inline");
+      if (s->inlinable)
+       fprintf (f, " inlinable");
+      if (s->versionable)
+       fprintf (f, " versionable");
+      fprintf (f, "\n  self time:       %i, benefit: %i\n",
               s->self_time, s->time_inlining_benefit);
-      fprintf (f, "  global time:     %i\n", node->global.time);
+      fprintf (f, "  global time:     %i\n", s->time);
       fprintf (f, "  self size:       %i, benefit: %i\n",
               s->self_size, s->size_inlining_benefit);
-      fprintf (f, "  global size:     %i", node->global.size);
+      fprintf (f, "  global size:     %i", s->size);
       fprintf (f, "  self stack:      %i\n",
               (int)s->estimated_self_stack_size);
       fprintf (f, "  global stack:    %i\n\n",
-              (int)node->global.estimated_stack_size);
+              (int)s->estimated_stack_size);
     }
 }
 
@@ -155,6 +166,26 @@ dump_inline_summaries (FILE *f)
       dump_inline_summary (f, node);
 }
 
+/* Give initial reasons why inlining would fail on EDGE.  This gets either
+   nullified or usually overwritten by more precise reasons later.  */
+
+void
+initialize_inline_failed (struct cgraph_edge *e)
+{
+  struct cgraph_node *callee = e->callee;
+
+  if (e->indirect_unknown_callee)
+    e->inline_failed = CIF_INDIRECT_UNKNOWN_CALL;
+  else if (!callee->analyzed)
+    e->inline_failed = CIF_BODY_NOT_AVAILABLE;
+  else if (callee->local.redefined_extern_inline)
+    e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
+  else if (e->call_stmt && gimple_call_cannot_inline_p (e->call_stmt))
+    e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
+  else
+    e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
+}
+
 /* See if statement might disappear after inlining.
    0 - means not eliminated
    1 - half of statements goes away
@@ -317,24 +348,27 @@ compute_inline_parameters (struct cgraph_node *node)
 {
   HOST_WIDE_INT self_stack_size;
   struct cgraph_edge *e;
+  struct inline_summary *info;
 
   gcc_assert (!node->global.inlined_to);
 
   inline_summary_alloc ();
 
+  info = inline_summary (node);
+
   /* Estimate the stack size for the function if we're optimizing.  */
   self_stack_size = optimize ? estimated_stack_frame_size (node) : 0;
-  inline_summary (node)->estimated_self_stack_size = self_stack_size;
-  node->global.estimated_stack_size = self_stack_size;
-  node->global.stack_frame_offset = 0;
+  info->estimated_self_stack_size = self_stack_size;
+  info->estimated_stack_size = self_stack_size;
+  info->stack_frame_offset = 0;
 
   /* Can this function be inlined at all?  */
-  node->local.inlinable = tree_inlinable_function_p (node->decl);
-  if (!node->local.inlinable)
-    node->local.disregard_inline_limits = 0;
+  info->inlinable = tree_inlinable_function_p (node->decl);
+  if (!info->inlinable)
+    info->disregard_inline_limits = 0;
 
   /* Inlinable functions always can change signature.  */
-  if (node->local.inlinable)
+  if (info->inlinable)
     node->local.can_change_signature = true;
   else
     {
@@ -349,8 +383,13 @@ compute_inline_parameters (struct cgraph_node *node)
   estimate_function_body_sizes (node);
 
   /* Inlining characteristics are maintained by the cgraph_mark_inline.  */
-  node->global.time = inline_summary (node)->self_time;
-  node->global.size = inline_summary (node)->self_size;
+  info->time = info->self_time;
+  info->size = info->self_size;
+  info->estimated_growth = INT_MIN;
+  info->stack_frame_offset = 0;
+  info->estimated_stack_size = info->estimated_self_stack_size;
+  info->disregard_inline_limits
+    = DECL_DISREGARD_INLINE_LIMITS (node->decl);
 }
 
 
@@ -390,10 +429,12 @@ static inline int
 estimate_edge_time (struct cgraph_edge *edge)
 {
   int call_stmt_time;
+  struct inline_summary *info = inline_summary (edge->callee);
+
   call_stmt_time = edge->call_stmt_time;
   gcc_checking_assert (call_stmt_time);
-  return (((gcov_type)edge->callee->global.time
-          - inline_summary (edge->callee)->time_inlining_benefit
+  return (((gcov_type)info->time
+          - info->time_inlining_benefit
           - call_stmt_time) * edge->frequency
          + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE;
 }
@@ -405,7 +446,7 @@ int
 estimate_time_after_inlining (struct cgraph_node *node,
                              struct cgraph_edge *edge)
 {
-  gcov_type time = node->global.time + estimate_edge_time (edge);
+  gcov_type time = inline_summary (node)->time + estimate_edge_time (edge);
   if (time < 0)
     time = 0;
   if (time > MAX_TIME)
@@ -421,7 +462,7 @@ int
 estimate_size_after_inlining (struct cgraph_node *node,
                              struct cgraph_edge *edge)
 {
-  int size = node->global.size + estimate_edge_growth (edge);
+  int size = inline_summary (node)->size + estimate_edge_growth (edge);
   gcc_assert (size >= 0);
   return size;
 }
@@ -435,9 +476,10 @@ estimate_growth (struct cgraph_node *node)
   int growth = 0;
   struct cgraph_edge *e;
   bool self_recursive = false;
+  struct inline_summary *info = inline_summary (node);
 
-  if (node->global.estimated_growth != INT_MIN)
-    return node->global.estimated_growth;
+  if (info->estimated_growth != INT_MIN)
+    return info->estimated_growth;
 
   for (e = node->callers; e; e = e->next_caller)
     {
@@ -453,15 +495,15 @@ estimate_growth (struct cgraph_node *node)
      some inlining.  */
   if (cgraph_will_be_removed_from_program_if_no_direct_calls (node)
       && !DECL_EXTERNAL (node->decl) && !self_recursive)
-    growth -= node->global.size;
+    growth -= info->size;
   /* COMDAT functions are very often not shared across multiple units since they
      come from various template instantiations.  Take this into account.  */
   else  if (DECL_COMDAT (node->decl) && !self_recursive
            && cgraph_can_remove_if_no_direct_calls_p (node))
-    growth -= (node->global.size
+    growth -= (info->size
               * (100 - PARAM_VALUE (PARAM_COMDAT_SHARING_PROBABILITY)) + 50) / 100;
 
-  node->global.estimated_growth = growth;
+  info->estimated_growth = growth;
   return growth;
 }
 
@@ -561,19 +603,25 @@ inline_read_summary (void)
              struct cgraph_node *node;
              struct inline_summary *info;
              lto_cgraph_encoder_t encoder;
+             struct bitpack_d bp;
 
              index = lto_input_uleb128 (ib);
              encoder = file_data->cgraph_node_encoder;
              node = lto_cgraph_encoder_deref (encoder, index);
              info = inline_summary (node);
 
-             node->global.estimated_stack_size
+             info->estimated_stack_size
                = info->estimated_self_stack_size = lto_input_uleb128 (ib);
-             node->global.time = info->self_time = lto_input_uleb128 (ib);
+             info->time = info->self_time = lto_input_uleb128 (ib);
              info->time_inlining_benefit = lto_input_uleb128 (ib);
-             node->global.size = info->self_size = lto_input_uleb128 (ib);
+             info->size = info->self_size = lto_input_uleb128 (ib);
              info->size_inlining_benefit = lto_input_uleb128 (ib);
-             node->global.estimated_growth = INT_MIN;
+             info->estimated_growth = INT_MIN;
+
+             bp = lto_input_bitpack (ib);
+             info->inlinable = bp_unpack_value (&bp, 1);
+             info->versionable = bp_unpack_value (&bp, 1);
+             info->disregard_inline_limits = bp_unpack_value (&bp, 1);
            }
 
          lto_destroy_simple_input_block (file_data,
@@ -623,6 +671,8 @@ inline_write_summary (cgraph_node_set set,
       if (node->analyzed)
        {
          struct inline_summary *info = inline_summary (node);
+         struct bitpack_d bp;
+
          lto_output_uleb128_stream (ob->main_stream,
                                     lto_cgraph_encoder_encode (encoder, node));
          lto_output_sleb128_stream (ob->main_stream,
@@ -635,6 +685,11 @@ inline_write_summary (cgraph_node_set set,
                                     info->self_time);
          lto_output_sleb128_stream (ob->main_stream,
                                     info->time_inlining_benefit);
+         bp = bitpack_create (ob->main_stream);
+         bp_pack_value (&bp, info->inlinable, 1);
+         bp_pack_value (&bp, info->versionable, 1);
+         bp_pack_value (&bp, info->disregard_inline_limits, 1);
+         lto_output_bitpack (&bp);
        }
     }
   lto_destroy_simple_output_block (ob);
index 1dbb3248fabcd89ea421f325b9018546396c9cca..c605eaed937d650d37c6d2cec53b9dbb9f8da132 100644 (file)
@@ -156,6 +156,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
                            bool update_original)
 {
   HOST_WIDE_INT peak;
+  struct inline_summary *caller_info, *callee_info;
 
   if (duplicate)
     {
@@ -184,7 +185,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
          gcc_assert (!e->callee->global.inlined_to);
          if (e->callee->analyzed && !DECL_EXTERNAL (e->callee->decl))
            {
-             overall_size -= e->callee->global.size;
+             overall_size -= inline_summary (e->callee)->size;
              nfunctions_inlined++;
            }
          duplicate = false;
@@ -201,17 +202,20 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
        }
     }
 
+  callee_info = inline_summary (e->callee);
+  caller_info = inline_summary (e->caller);
+
   if (e->caller->global.inlined_to)
     e->callee->global.inlined_to = e->caller->global.inlined_to;
   else
     e->callee->global.inlined_to = e->caller;
-  e->callee->global.stack_frame_offset
-    = e->caller->global.stack_frame_offset
-      + inline_summary (e->caller)->estimated_self_stack_size;
-  peak = e->callee->global.stack_frame_offset
-      + inline_summary (e->callee)->estimated_self_stack_size;
-  if (e->callee->global.inlined_to->global.estimated_stack_size < peak)
-    e->callee->global.inlined_to->global.estimated_stack_size = peak;
+  callee_info->stack_frame_offset
+    = caller_info->stack_frame_offset
+      + caller_info->estimated_self_stack_size;
+  peak = callee_info->stack_frame_offset
+      + callee_info->estimated_self_stack_size;
+  if (inline_summary (e->callee->global.inlined_to)->estimated_stack_size < peak)
+    inline_summary (e->callee->global.inlined_to)->estimated_stack_size = peak;
   cgraph_propagate_frequency (e->callee);
 
   /* Recursively clone all bodies.  */
@@ -233,6 +237,7 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original,
   int old_size = 0, new_size = 0;
   struct cgraph_node *to = NULL;
   struct cgraph_edge *curr = e;
+  struct inline_summary *info;
 
   /* Don't inline inlined edges.  */
   gcc_assert (e->inline_failed);
@@ -248,10 +253,11 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original,
   for (;e && !e->inline_failed; e = e->caller->callers)
     {
       to = e->caller;
-      old_size = e->caller->global.size;
+      info = inline_summary (to);
+      old_size = info->size;
       new_size = estimate_size_after_inlining (to, curr);
-      to->global.size = new_size;
-      to->global.time = estimate_time_after_inlining (to, curr);
+      info->size = new_size;
+      info->time = estimate_time_after_inlining (to, curr);
     }
   gcc_assert (curr->callee->global.inlined_to == to);
   if (new_size > old_size)
@@ -280,23 +286,27 @@ cgraph_check_inline_limits (struct cgraph_edge *e,
   int newsize;
   int limit;
   HOST_WIDE_INT stack_size_limit, inlined_stack;
+  struct inline_summary *info, *what_info;
 
   if (to->global.inlined_to)
     to = to->global.inlined_to;
 
+  info = inline_summary (to);
+  what_info = inline_summary (what);
+
   /* When inlining large function body called once into small function,
      take the inlined function as base for limiting the growth.  */
-  if (inline_summary (to)->self_size > inline_summary(what)->self_size)
-    limit = inline_summary (to)->self_size;
+  if (info->self_size > what_info->self_size)
+    limit = info->self_size;
   else
-    limit = inline_summary (what)->self_size;
+    limit = what_info->self_size;
 
   limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;
 
   /* Check the size after inlining against the function limits.  But allow
      the function to shrink if it went over the limits by forced inlining.  */
   newsize = estimate_size_after_inlining (to, e);
-  if (newsize >= to->global.size
+  if (newsize >= info->size
       && newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
       && newsize > limit)
     {
@@ -305,13 +315,13 @@ cgraph_check_inline_limits (struct cgraph_edge *e,
       return false;
     }
 
-  stack_size_limit = inline_summary (to)->estimated_self_stack_size;
+  stack_size_limit = info->estimated_self_stack_size;
 
   stack_size_limit += stack_size_limit * PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) / 100;
 
-  inlined_stack = (to->global.stack_frame_offset
-                  + inline_summary (to)->estimated_self_stack_size
-                  + what->global.estimated_stack_size);
+  inlined_stack = (info->stack_frame_offset
+                  + info->estimated_self_stack_size
+                  + what_info->estimated_stack_size);
   if (inlined_stack  > stack_size_limit
       && inlined_stack > PARAM_VALUE (PARAM_LARGE_STACK_FRAME))
     {
@@ -328,8 +338,9 @@ static bool
 cgraph_default_inline_p (struct cgraph_node *n, cgraph_inline_failed_t *reason)
 {
   tree decl = n->decl;
+  struct inline_summary *info = inline_summary (n);
 
-  if (n->local.disregard_inline_limits)
+  if (info->disregard_inline_limits)
     return true;
 
   if (!flag_inline_small_functions && !DECL_DECLARED_INLINE_P (decl))
@@ -354,7 +365,7 @@ cgraph_default_inline_p (struct cgraph_node *n, cgraph_inline_failed_t *reason)
 
   if (DECL_DECLARED_INLINE_P (decl))
     {
-      if (n->global.size >= MAX_INLINE_INSNS_SINGLE)
+      if (info->size >= MAX_INLINE_INSNS_SINGLE)
        {
          if (reason)
            *reason = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
@@ -363,7 +374,7 @@ cgraph_default_inline_p (struct cgraph_node *n, cgraph_inline_failed_t *reason)
     }
   else
     {
-      if (n->global.size >= MAX_INLINE_INSNS_AUTO)
+      if (info->size >= MAX_INLINE_INSNS_AUTO)
        {
          if (reason)
            *reason = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
@@ -385,8 +396,9 @@ cgraph_edge_badness (struct cgraph_edge *edge, bool dump)
 {
   gcov_type badness;
   int growth;
+  struct inline_summary *callee_info = inline_summary (edge->callee);
 
-  if (edge->callee->local.disregard_inline_limits)
+  if (callee_info->disregard_inline_limits)
     return INT_MIN;
 
   growth = estimate_edge_growth (edge);
@@ -398,11 +410,11 @@ cgraph_edge_badness (struct cgraph_edge *edge, bool dump)
               cgraph_node_name (edge->callee));
       fprintf (dump_file, "      growth %i, time %i-%i, size %i-%i\n",
               growth,
-              edge->callee->global.time,
-              inline_summary (edge->callee)->time_inlining_benefit
+              callee_info->time,
+              callee_info->time_inlining_benefit
               + edge->call_stmt_time,
-              edge->callee->global.size,
-              inline_summary (edge->callee)->size_inlining_benefit
+              callee_info->size,
+              callee_info->size_inlining_benefit
               + edge->call_stmt_size);
     }
 
@@ -422,7 +434,7 @@ cgraph_edge_badness (struct cgraph_edge *edge, bool dump)
       badness =
        ((int)
         ((double) edge->count * INT_MIN / max_count / (max_benefit + 1)) *
-        (inline_summary (edge->callee)->time_inlining_benefit
+        (callee_info->time_inlining_benefit
          + edge->call_stmt_time + 1)) / growth;
       if (dump)
        {
@@ -453,9 +465,9 @@ cgraph_edge_badness (struct cgraph_edge *edge, bool dump)
       int growth_for_all;
       badness = growth * 10000;
       benefitperc =
-       100 * (inline_summary (edge->callee)->time_inlining_benefit
+       100 * (callee_info->time_inlining_benefit
               + edge->call_stmt_time)
-           / (edge->callee->global.time + 1) + 1;
+           / (callee_info->time + 1) + 1;
       benefitperc = MIN (benefitperc, 100);
       div *= benefitperc;
 
@@ -543,13 +555,13 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
   struct cgraph_edge *edge;
   cgraph_inline_failed_t failed_reason;
 
-  if (!node->local.inlinable
+  if (!inline_summary (node)->inlinable
       || cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE
       || node->global.inlined_to)
     return;
   if (!bitmap_set_bit (updated_nodes, node->uid))
     return;
-  node->global.estimated_growth = INT_MIN;
+  inline_summary (node)->estimated_growth = INT_MIN;
 
   /* See if there is something to do.  */
   for (edge = node->callers; edge; edge = edge->next_caller)
@@ -586,7 +598,7 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node,
                    bitmap updated_nodes)
 {
   struct cgraph_edge *e = node->callees;
-  node->global.estimated_growth = INT_MIN;
+  inline_summary (node)->estimated_growth = INT_MIN;
 
   if (!e)
     return;
@@ -596,11 +608,11 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node,
     else
       {
        if (e->inline_failed
-           && e->callee->local.inlinable
+           && inline_summary (e->callee)->inlinable
            && cgraph_function_body_availability (e->callee) >= AVAIL_AVAILABLE
            && !bitmap_bit_p (updated_nodes, e->callee->uid))
          {
-           node->global.estimated_growth = INT_MIN;
+           inline_summary (node)->estimated_growth = INT_MIN;
            /* If function becomes uninlinable, we need to remove it from the heap.  */
            if (!cgraph_default_inline_p (e->callee, &e->inline_failed))
              update_caller_keys (heap, e->callee, updated_nodes);
@@ -632,7 +644,7 @@ update_all_callee_keys (fibheap_t heap, struct cgraph_node *node,
                        bitmap updated_nodes)
 {
   struct cgraph_edge *e = node->callees;
-  node->global.estimated_growth = INT_MIN;
+  inline_summary (node)->estimated_growth = INT_MIN;
 
   if (!e)
     return;
@@ -709,7 +721,7 @@ cgraph_decide_recursive_inlining (struct cgraph_edge *edge,
 
   /* It does not make sense to recursively inline always-inline functions
      as we are going to sorry() on the remaining calls anyway.  */
-  if (node->local.disregard_inline_limits
+  if (inline_summary (node)->disregard_inline_limits
       && lookup_attribute ("always_inline", DECL_ATTRIBUTES (node->decl)))
     return false;
 
@@ -811,8 +823,8 @@ cgraph_decide_recursive_inlining (struct cgraph_edge *edge,
   if (dump_file)
     fprintf (dump_file,
             "\n   Inlined %i times, body grown from size %i to %i, time %i to %i\n", n,
-            master_clone->global.size, node->global.size,
-            master_clone->global.time, node->global.time);
+            inline_summary (master_clone)->size, inline_summary (node)->size,
+            inline_summary (master_clone)->time, inline_summary (node)->time);
 
   /* Remove master clone we used for inlining.  We rely that clones inlined
      into master clone gets queued just before master clone so we don't
@@ -870,7 +882,7 @@ add_new_edges_to_heap (fibheap_t heap, VEC (cgraph_edge_p, heap) *new_edges)
       struct cgraph_edge *edge = VEC_pop (cgraph_edge_p, new_edges);
 
       gcc_assert (!edge->aux);
-      if (edge->callee->local.inlinable
+      if (inline_summary (edge->callee)->inlinable
          && edge->inline_failed
          && cgraph_default_inline_p (edge->callee, &edge->inline_failed))
         edge->aux = fibheap_insert (heap, cgraph_edge_badness (edge, false), edge);
@@ -905,26 +917,37 @@ cgraph_decide_inlining_of_small_functions (void)
   /* Put all inline candidates into the heap.  */
 
   for (node = cgraph_nodes; node; node = node->next)
-    {
-      if (!node->local.inlinable || !node->callers)
-       continue;
-      if (dump_file)
-       fprintf (dump_file, "Considering inline candidate %s.\n", cgraph_node_name (node));
+    if (node->analyzed)
+      {
+       struct inline_summary *info = inline_summary (node);
 
-      node->global.estimated_growth = INT_MIN;
-      if (!cgraph_default_inline_p (node, &failed_reason))
-       {
-         cgraph_set_inline_failed (node, failed_reason);
-         continue;
-       }
+       if (!info->inlinable || !node->callers)
+         {
+           struct cgraph_edge *e;
+           for (e = node->callers; e; e = e->next_caller)
+             {
+               gcc_assert (e->inline_failed);
+               e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
+             }
+           continue;
+         }
+       if (dump_file)
+         fprintf (dump_file, "Considering inline candidate %s.\n", cgraph_node_name (node));
 
-      for (edge = node->callers; edge; edge = edge->next_caller)
-       if (edge->inline_failed)
+       info->estimated_growth = INT_MIN;
+       if (!cgraph_default_inline_p (node, &failed_reason))
          {
-           gcc_assert (!edge->aux);
-           edge->aux = fibheap_insert (heap, cgraph_edge_badness (edge, false), edge);
+           cgraph_set_inline_failed (node, failed_reason);
+           continue;
          }
-    }
+
+       for (edge = node->callers; edge; edge = edge->next_caller)
+         if (edge->inline_failed)
+           {
+             gcc_assert (!edge->aux);
+             edge->aux = fibheap_insert (heap, cgraph_edge_badness (edge, false), edge);
+           }
+      }
 
   max_size = compute_max_insns (overall_size);
   min_size = overall_size;
@@ -963,7 +986,7 @@ cgraph_decide_inlining_of_small_functions (void)
          fprintf (dump_file,
                   "\nConsidering %s with %i size\n",
                   cgraph_node_name (edge->callee),
-                  edge->callee->global.size);
+                  inline_summary (edge->callee)->size);
          fprintf (dump_file,
                   " to be inlined into %s in %s:%i\n"
                   " Estimated growth after inlined into all callees is %+i insns.\n"
@@ -1007,7 +1030,7 @@ cgraph_decide_inlining_of_small_functions (void)
          if (where->global.inlined_to)
            {
              edge->inline_failed
-               = (edge->callee->local.disregard_inline_limits
+               = (inline_summary (edge->callee)->disregard_inline_limits
                   ? CIF_RECURSIVE_INLINING : CIF_UNSPECIFIED);
              if (dump_file)
                fprintf (dump_file, " inline_failed:Recursive inlining performed only for function itself.\n");
@@ -1015,7 +1038,7 @@ cgraph_decide_inlining_of_small_functions (void)
            }
        }
 
-      if (edge->callee->local.disregard_inline_limits)
+      if (inline_summary (edge->callee)->disregard_inline_limits)
        ;
       else if (!cgraph_maybe_hot_edge_p (edge))
        not_good = CIF_UNLIKELY_CALL;
@@ -1112,8 +1135,8 @@ cgraph_decide_inlining_of_small_functions (void)
                   " Inlined into %s which now has time %i and size %i,"
                   "net change of %+i.\n",
                   cgraph_node_name (edge->caller),
-                  edge->caller->global.time,
-                  edge->caller->global.size,
+                  inline_summary (edge->caller)->time,
+                  inline_summary (edge->caller)->size,
                   overall_size - old_size);
        }
       if (min_size > overall_size)
@@ -1142,7 +1165,7 @@ cgraph_decide_inlining_of_small_functions (void)
          fprintf (dump_file,
                   "\nSkipping %s with %i size\n",
                   cgraph_node_name (edge->callee),
-                  edge->callee->global.size);
+                  inline_summary (edge->callee)->size);
          fprintf (dump_file,
                   " called by %s in %s:%i\n"
                   " Estimated growth after inlined into all callees is %+i insns.\n"
@@ -1159,7 +1182,7 @@ cgraph_decide_inlining_of_small_functions (void)
          if (dump_flags & TDF_DETAILS)
            cgraph_edge_badness (edge, true);
        }
-      if (!edge->callee->local.disregard_inline_limits && edge->inline_failed)
+      if (!inline_summary (edge->callee)->disregard_inline_limits && edge->inline_failed)
        edge->inline_failed = CIF_INLINE_UNIT_GROWTH_LIMIT;
     }
 
@@ -1287,13 +1310,14 @@ cgraph_decide_inlining (void)
     if (node->analyzed)
       {
        struct cgraph_edge *e;
+       struct inline_summary *info = inline_summary (node);
 
-       gcc_assert (inline_summary (node)->self_size == node->global.size);
+       gcc_assert (info->self_size == info->size);
        if (!DECL_EXTERNAL (node->decl))
-         initial_size += node->global.size;
+         initial_size += info->size;
        for (e = node->callees; e; e = e->next_callee)
          {
-           int benefit = (inline_summary (node)->time_inlining_benefit
+           int benefit = (info->time_inlining_benefit
                           + e->call_stmt_time);
            if (max_count < e->count)
              max_count = e->count;
@@ -1362,7 +1386,7 @@ cgraph_decide_inlining (void)
              && !node->callers->next_caller
              && !node->global.inlined_to
              && cgraph_will_be_removed_from_program_if_no_direct_calls (node)
-             && node->local.inlinable
+             && inline_summary (node)->inlinable
              && cgraph_function_body_availability (node) >= AVAIL_AVAILABLE
              && node->callers->inline_failed
              && node->callers->caller != node
@@ -1377,11 +1401,11 @@ cgraph_decide_inlining (void)
                {
                  fprintf (dump_file,
                           "\nConsidering %s size %i.\n",
-                          cgraph_node_name (node), node->global.size);
+                          cgraph_node_name (node), inline_summary (node)->size);
                  fprintf (dump_file,
                           " Called once from %s %i insns.\n",
                           cgraph_node_name (node->callers->caller),
-                          node->callers->caller->global.size);
+                          inline_summary (node->callers->caller)->size);
                }
 
              if (cgraph_check_inline_limits (node->callers, &reason))
@@ -1393,7 +1417,7 @@ cgraph_decide_inlining (void)
                             " Inlined into %s which now has %i size"
                             " for a net change of %+i size.\n",
                             cgraph_node_name (caller),
-                            caller->global.size,
+                            inline_summary (caller)->size,
                             overall_size - old_size);
                }
              else
@@ -1442,7 +1466,7 @@ leaf_node_p (struct cgraph_node *n)
 static bool
 cgraph_edge_early_inlinable_p (struct cgraph_edge *e, FILE *file)
 {
-  if (!e->callee->local.inlinable)
+  if (!inline_summary (e->callee)->inlinable)
     {
       if (file)
        fprintf (file, "Not inlining: Function not inlinable.\n");
@@ -1482,7 +1506,7 @@ cgraph_perform_always_inlining (struct cgraph_node *node)
 
   for (e = node->callees; e; e = e->next_callee)
     {
-      if (!e->callee->local.disregard_inline_limits)
+      if (!inline_summary (e->callee)->disregard_inline_limits)
        continue;
 
       if (dump_file)
@@ -1524,16 +1548,16 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node)
 
   /* Never inline regular functions into always-inline functions
      during incremental inlining.  */
-  if (node->local.disregard_inline_limits)
+  if (inline_summary (node)->disregard_inline_limits)
     return false;
 
   for (e = node->callees; e; e = e->next_callee)
     {
       int allowed_growth = 0;
 
-      if (!e->callee->local.inlinable
+      if (!inline_summary (e->callee)->inlinable
          || !e->inline_failed
-         || e->callee->local.disregard_inline_limits)
+         || inline_summary (e->callee)->disregard_inline_limits)
        continue;
 
       /* Do not consider functions not declared inline.  */
index e9a7db21043f3b5cedba4d0e724f0488c2c6a57f..58bcdd968b94de9afc3ff7f509fdc40ff381ce2d 100644 (file)
@@ -23,9 +23,10 @@ along with GCC; see the file COPYING3.  If not see
 
 struct inline_summary
 {
+  /* Information about the function body itself.  */
+
   /* Estimated stack frame consumption by the function.  */
   HOST_WIDE_INT estimated_self_stack_size;
-
   /* Size of the function body.  */
   int self_size;
   /* How many instructions are likely going to disappear after inlining.  */
@@ -34,6 +35,29 @@ struct inline_summary
   int self_time;
   /* How much time is going to be saved by inlining.  */
   int time_inlining_benefit;
+
+  /* False when there something makes inlining impossible (such as va_arg).  */
+  unsigned inlinable : 1;
+  /* False when there something makes versioning impossible.
+     Currently computed and used only by ipa-cp.  */
+  unsigned versionable : 1;
+  /* True when function should be inlined independently on its size.  */
+  unsigned disregard_inline_limits : 1;
+
+  /* Information about function that will result after applying all the
+     inline decisions present in the callgraph.  Generally kept up to
+     date only for functions that are not inline clones. */
+
+  /* Estimated stack frame consumption by the function.  */
+  HOST_WIDE_INT estimated_stack_size;
+  /* Expected offset of the stack frame of inlined function.  */
+  HOST_WIDE_INT stack_frame_offset;
+  /* Estimated size of the function after inlining.  */
+  int time;
+  int size;
+  /* Cached estimated growth after inlining.
+     INT_MIN if not computed.  */
+  int estimated_growth;
 };
 
 typedef struct inline_summary inline_summary_t;
@@ -47,6 +71,7 @@ void inline_generate_summary (void);
 void inline_read_summary (void);
 void inline_write_summary (cgraph_node_set, varpool_node_set);
 void inline_free_summary (void);
+void initialize_inline_failed (struct cgraph_edge *);
 int estimate_time_after_inlining (struct cgraph_node *, struct cgraph_edge *);
 int estimate_size_after_inlining (struct cgraph_node *, struct cgraph_edge *);
 int estimate_growth (struct cgraph_node *);
@@ -63,10 +88,10 @@ static inline int
 estimate_edge_growth (struct cgraph_edge *edge)
 {
   int call_stmt_size;
+  struct inline_summary *info = inline_summary (edge->callee);
   call_stmt_size = edge->call_stmt_size;
   gcc_checking_assert (call_stmt_size);
-  return (edge->callee->global.size
-         - inline_summary (edge->callee)->size_inlining_benefit
+  return (info->size
+         - info->size_inlining_benefit
          - call_stmt_size);
 }
-
index 60102db336d777a93f6c4d3c39b121a18721e681..47109abf37ee782fbd5ac99d40c283a45780c303 100644 (file)
@@ -92,6 +92,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "fibheap.h"
 #include "params.h"
 #include "gimple-pretty-print.h"
+#include "ipa-inline.h"
 
 /* Per basic block info.  */
 
@@ -1281,13 +1282,13 @@ execute_split_functions (void)
     }
   /* This can be relaxed; function might become inlinable after splitting
      away the uninlinable part.  */
-  if (!node->local.inlinable)
+  if (!inline_summary (node)->inlinable)
     {
       if (dump_file)
        fprintf (dump_file, "Not splitting: not inlinable.\n");
       return 0;
     }
-  if (node->local.disregard_inline_limits)
+  if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
     {
       if (dump_file)
        fprintf (dump_file, "Not splitting: disregarding inline limits.\n");
index 84a3d97e8a9b609bde904723eb92ecb1d7024e1e..e58fb23b256c50a5c4da87b31e8d83b97cf193ca 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -78,8 +78,8 @@ cgraph_postorder (struct cgraph_node **order)
                  /* Break possible cycles involving always-inline
                     functions by ignoring edges from always-inline
                     functions to non-always-inline functions.  */
-                 if (edge->caller->local.disregard_inline_limits
-                     && !edge->callee->local.disregard_inline_limits)
+                 if (DECL_DISREGARD_INLINE_LIMITS (edge->caller->decl)
+                     && !DECL_DISREGARD_INLINE_LIMITS (edge->callee->decl))
                    continue;
                  if (!edge->caller->aux)
                    {
@@ -380,7 +380,6 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
          cgraph_node_remove_callees (node);
          ipa_remove_all_references (&node->ref_list);
          node->analyzed = false;
-         node->local.inlinable = false;
        }
       if (!node->aux)
        {
@@ -421,7 +420,6 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
                  if (!clone)
                    {
                      cgraph_release_function_body (node);
-                     node->local.inlinable = false;
                      if (node->prev_sibling_clone)
                        node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
                      else if (node->clone_of)
@@ -1629,7 +1627,7 @@ record_cdtor_fn (struct cgraph_node *node)
   if (DECL_STATIC_DESTRUCTOR (node->decl))
     VEC_safe_push (tree, heap, static_dtors, node->decl);
   node = cgraph_get_node (node->decl);
-  node->local.disregard_inline_limits = 1;
+  DECL_DISREGARD_INLINE_LIMITS (node->decl) = 1;
 }
 
 /* Define global constructors/destructor functions for the CDTORS, of
index c1544577dd5a28171a770dcfe4ab42c4ec071ab6..861a37b55a1fb8c50fcadb8c728028b3a08654b1 100644 (file)
@@ -489,10 +489,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
   bp_pack_value (&bp, node->local.local, 1);
   bp_pack_value (&bp, node->local.externally_visible, 1);
   bp_pack_value (&bp, node->local.finalized, 1);
-  bp_pack_value (&bp, node->local.inlinable, 1);
-  bp_pack_value (&bp, node->local.versionable, 1);
   bp_pack_value (&bp, node->local.can_change_signature, 1);
-  bp_pack_value (&bp, node->local.disregard_inline_limits, 1);
   bp_pack_value (&bp, node->local.redefined_extern_inline, 1);
   bp_pack_value (&bp, node->local.vtable_method, 1);
   bp_pack_value (&bp, node->needed, 1);
@@ -928,10 +925,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
   node->local.local = bp_unpack_value (bp, 1);
   node->local.externally_visible = bp_unpack_value (bp, 1);
   node->local.finalized = bp_unpack_value (bp, 1);
-  node->local.inlinable = bp_unpack_value (bp, 1);
-  node->local.versionable = bp_unpack_value (bp, 1);
   node->local.can_change_signature = bp_unpack_value (bp, 1);
-  node->local.disregard_inline_limits = bp_unpack_value (bp, 1);
   node->local.redefined_extern_inline = bp_unpack_value (bp, 1);
   node->local.vtable_method = bp_unpack_value (bp, 1);
   node->needed = bp_unpack_value (bp, 1);
index 45dd300dedddd27980078cef8256df01257f050b..6c87a38f9ae51ff73a3e934e15fb13867a57d48e 100644 (file)
@@ -1,3 +1,7 @@
+2011-04-16  Jan Hubicka  <jh@suse.cz>
+
+       * lto.c (lto_balanced_map): Update.
+
 2011-04-14  Jan Hubicka  <jh@suse.cz>
 
        * lto.c: Include ipa-inline.h
index 9103af45202ab3fb883fbb402d1aaa5f34a2aa20..f515aaac94f6f48dfee79443b096a44cf3681f11 100644 (file)
@@ -1030,7 +1030,7 @@ lto_balanced_map (void)
       if (partition_cgraph_node_p (node))
        {
          order[n_nodes++] = node;
-          total_size += node->global.size;
+          total_size += inline_summary (node)->size;
        }
     }
   free (postorder);
@@ -1049,7 +1049,7 @@ lto_balanced_map (void)
     {
       if (!order[i]->aux)
         add_cgraph_node_to_partition (partition, order[i]);
-      total_size -= order[i]->global.size;
+      total_size -= inline_summary (order[i])->size;
 
       /* Once we added a new node to the partition, we also want to add
          all referenced variables unless they was already added into some
index 95a9f1b1235faacd1b50a30e224532376162de8d..56a93462d33cc8c809a73428755f4cb3b7c4c454 100644 (file)
@@ -91,6 +91,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dbgcnt.h"
 #include "tree-inline.h"
 #include "gimple-pretty-print.h"
+#include "ipa-inline.h"
 
 /* Enumeration of all aggregate reductions we can do.  */
 enum sra_mode { SRA_MODE_EARLY_IPA,   /* early call regularization */
@@ -4469,7 +4470,7 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node)
     }
 
   if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
-      && node->global.size >= MAX_INLINE_INSNS_AUTO)
+      && inline_summary(node)->size >= MAX_INLINE_INSNS_AUTO)
     {
       if (dump_file)
        fprintf (dump_file, "Function too big to be made truly local.\n");