From e7f2301855b432e057acd267e5df455fee60abef Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 16 Apr 2011 11:13:08 +0200 Subject: [PATCH] cgraphbuild.c: Include ipa-inline.h. * 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 --- gcc/ChangeLog | 50 +++++++++++ gcc/Makefile.in | 6 +- gcc/cgraph.c | 30 +------ gcc/cgraph.h | 22 ----- gcc/cgraphbuild.c | 12 +-- gcc/cgraphunit.c | 9 +- gcc/ipa-cp.c | 4 +- gcc/ipa-inline-analysis.c | 115 ++++++++++++++++++------- gcc/ipa-inline.c | 174 ++++++++++++++++++++++---------------- gcc/ipa-inline.h | 33 +++++++- gcc/ipa-split.c | 5 +- gcc/ipa.c | 8 +- gcc/lto-cgraph.c | 6 -- gcc/lto/ChangeLog | 4 + gcc/lto/lto.c | 4 +- gcc/tree-sra.c | 3 +- 16 files changed, 288 insertions(+), 197 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e3a583af770..237f2fda1ce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,53 @@ +2011-04-16 Jan Hubicka + + * 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 * config/i386/sse.md (V16): New mode iterator. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 04b10cd8cd9..f88d61d7bbc 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -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) \ diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 09436c7cfb5..31c5b59960a 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -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)) diff --git a/gcc/cgraph.h b/gcc/cgraph.h index eb5154638bc..199349b3991 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -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. diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index 935462eda83..3a2cb676679 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -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); } } diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 539dbf98244..6b3ddb5562f 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -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 diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 4cee1d481e6..5ec0b2c7aca 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -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); } } diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 47bd2a8c1da..6ab3e4733f7 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -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); diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 1dbb3248fab..c605eaed937 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -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. */ diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h index e9a7db21043..58bcdd968b9 100644 --- a/gcc/ipa-inline.h +++ b/gcc/ipa-inline.h @@ -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); } - diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 60102db336d..47109abf37e 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -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"); diff --git a/gcc/ipa.c b/gcc/ipa.c index 84a3d97e8a9..e58fb23b256 100644 --- 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 diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index c1544577dd5..861a37b55a1 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -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); diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 45dd300dedd..6c87a38f9ae 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,7 @@ +2011-04-16 Jan Hubicka + + * lto.c (lto_balanced_map): Update. + 2011-04-14 Jan Hubicka * lto.c: Include ipa-inline.h diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 9103af45202..f515aaac94f 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -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 diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 95a9f1b1235..56a93462d33 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -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"); -- 2.30.2