From 89c679bd815aae344e78a0fcd7f61d6528a22a8e Mon Sep 17 00:00:00 2001 From: hubicka Date: Fri, 3 Jul 2009 20:28:14 +0000 Subject: * ipa-inline.c (cgraph_decide_inlining_incrementally): When optimizing for size, reduce amount of inlining. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149210 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 28f0ec9862d..040096fa0d1 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1504,7 +1504,8 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, continue; } - if (cgraph_maybe_hot_edge_p (e) && leaf_node_p (e->callee)) + if (cgraph_maybe_hot_edge_p (e) && leaf_node_p (e->callee) + && optimize_function_for_speed_p (cfun)) allowed_growth = PARAM_VALUE (PARAM_EARLY_INLINING_INSNS); /* When the function body would grow and inlining the function won't -- cgit v1.2.1 From 76870d0c4fc737b8793349e53e0a8aab63e3df24 Mon Sep 17 00:00:00 2001 From: jamborm Date: Thu, 30 Jul 2009 16:26:09 +0000 Subject: 2009-07-30 Martin Jambor PR tree-optimization/40570 * ipa-inline.c (cgraph_decide_inlining): Watch out for dead single use inlining loops. * testsuite/gcc.c-torture/compile/pr40570.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@150263 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 040096fa0d1..dde8181c86c 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1227,6 +1227,8 @@ cgraph_decide_inlining (void) && !node->needed && node->local.inlinable && node->callers->inline_failed + && node->callers->caller != node + && node->callers->caller->global.inlined_to != node && !gimple_call_cannot_inline_p (node->callers->call_stmt) && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl)) -- cgit v1.2.1 From 19bcf5214614bfc4322ffbe3d93c2fbcf6c22c26 Mon Sep 17 00:00:00 2001 From: davidxl Date: Wed, 12 Aug 2009 16:51:41 +0000 Subject: Fix to PR41012 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@150703 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index dde8181c86c..79de3634d86 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1006,10 +1006,8 @@ cgraph_decide_inlining_of_small_functions (void) } continue; } - if (!tree_can_inline_p (edge->caller->decl, edge->callee->decl)) + if (!tree_can_inline_p (edge)) { - gimple_call_set_cannot_inline (edge->call_stmt, true); - edge->inline_failed = CIF_TARGET_OPTION_MISMATCH; if (dump_file) fprintf (dump_file, " inline_failed:%s.\n", cgraph_inline_failed_string (edge->inline_failed)); @@ -1184,11 +1182,8 @@ cgraph_decide_inlining (void) if (cgraph_recursive_inlining_p (e->caller, e->callee, &e->inline_failed)) continue; - if (!tree_can_inline_p (e->caller->decl, e->callee->decl)) - { - gimple_call_set_cannot_inline (e->call_stmt, true); - continue; - } + if (!tree_can_inline_p (e)) + continue; if (cgraph_mark_inline_edge (e, true, NULL)) redo_always_inline = true; if (dump_file) @@ -1440,14 +1435,14 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, } continue; } - if (!tree_can_inline_p (node->decl, e->callee->decl)) + if (!tree_can_inline_p (e)) { - gimple_call_set_cannot_inline (e->call_stmt, true); if (dump_file) { indent_to (dump_file, depth); fprintf (dump_file, - "Not inlining: Target specific option mismatch.\n"); + "Not inlining: %s", + cgraph_inline_failed_string (e->inline_failed)); } continue; } @@ -1553,14 +1548,14 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, } continue; } - if (!tree_can_inline_p (node->decl, e->callee->decl)) + if (!tree_can_inline_p (e)) { - gimple_call_set_cannot_inline (e->call_stmt, true); if (dump_file) { indent_to (dump_file, depth); fprintf (dump_file, - "Not inlining: Target specific option mismatch.\n"); + "Not inlining: %s.", + cgraph_inline_failed_string (e->inline_failed)); } continue; } -- cgit v1.2.1 From e38def9ca7953bb5611d08ce8617249516ba5a99 Mon Sep 17 00:00:00 2001 From: rth Date: Mon, 14 Sep 2009 19:18:58 +0000 Subject: Squash commit of EH in gimple git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151696 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 79de3634d86..c6bbece3ace 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1735,7 +1735,6 @@ estimate_function_body_sizes (struct cgraph_node *node) tree arg; int freq; tree funtype = TREE_TYPE (node->decl); - bitmap must_not_throw = must_not_throw_labels (); if (dump_file) { @@ -1748,35 +1747,20 @@ estimate_function_body_sizes (struct cgraph_node *node) freq = compute_call_stmt_bb_frequency (node->decl, bb); for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) { - int this_size = estimate_num_insns (gsi_stmt (bsi), &eni_size_weights); - int this_time = estimate_num_insns (gsi_stmt (bsi), &eni_time_weights); - - /* MUST_NOT_THROW is usually handled by runtime calling terminate and stopping - stacking unwinding. However when there is local cleanup that can resume - to MUST_NOT_THROW then we generate explicit handler containing - std::terminate () call. - - Because inlining of function can introduce new cleanup region, prior - inlining we keep std::terinate () calls for every MUST_NOT_THROW containing - function call. Wast majority of these will be eliminated after inlining - and crossjumping will inify possible duplicated calls. So ignore - the handlers for function body estimates. */ - if (gimple_code (gsi_stmt (bsi)) == GIMPLE_LABEL - && bitmap_bit_p (must_not_throw, - LABEL_DECL_UID (gimple_label_label (gsi_stmt (bsi))))) - { - if (dump_file) - fprintf (dump_file, " MUST_NOT_THROW landing pad. Ignoring whole BB.\n"); - } + gimple stmt = gsi_stmt (bsi); + int this_size = estimate_num_insns (stmt, &eni_size_weights); + int this_time = estimate_num_insns (stmt, &eni_time_weights); + if (dump_file) { - fprintf (dump_file, " freq:%6i size:%3i time:%3i ", freq, this_size, this_time); - print_gimple_stmt (dump_file, gsi_stmt (bsi), 0, 0); + fprintf (dump_file, " freq:%6i size:%3i time:%3i ", + freq, this_size, this_time); + print_gimple_stmt (dump_file, stmt, 0, 0); } this_time *= freq; time += this_time; size += this_size; - if (likely_eliminated_by_inlining_p (gsi_stmt (bsi))) + if (likely_eliminated_by_inlining_p (stmt)) { size_inlining_benefit += this_size; time_inlining_benefit += this_time; @@ -1825,7 +1809,6 @@ estimate_function_body_sizes (struct cgraph_node *node) } inline_summary (node)->time_inlining_benefit = time_inlining_benefit; inline_summary (node)->size_inlining_benefit = size_inlining_benefit; - BITMAP_FREE (must_not_throw); } /* Compute parameters of functions used by inliner. */ -- cgit v1.2.1 From 479e7f003ea19157517399fc36da9d3c14308b51 Mon Sep 17 00:00:00 2001 From: jamborm Date: Tue, 15 Sep 2009 14:04:01 +0000 Subject: 2009-09-14 Martin Jambor * ipa-inline.c (estimate_function_body_sizes): Dump info about individual statements only at TDF_DETAILS dump level. Format source for 80 characters per line. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151722 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index c6bbece3ace..662e13f2512 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1737,9 +1737,8 @@ estimate_function_body_sizes (struct cgraph_node *node) tree funtype = TREE_TYPE (node->decl); if (dump_file) - { - fprintf (dump_file, "Analyzing function body size: %s\n", cgraph_node_name (node)); - } + fprintf (dump_file, "Analyzing function body size: %s\n", + cgraph_node_name (node)); gcc_assert (my_function && my_function->cfg); FOR_EACH_BB_FN (bb, my_function) @@ -1751,7 +1750,7 @@ estimate_function_body_sizes (struct cgraph_node *node) int this_size = estimate_num_insns (stmt, &eni_size_weights); int this_time = estimate_num_insns (stmt, &eni_time_weights); - if (dump_file) + if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, " freq:%6i size:%3i time:%3i ", freq, this_size, this_time); @@ -1764,7 +1763,7 @@ estimate_function_body_sizes (struct cgraph_node *node) { size_inlining_benefit += this_size; time_inlining_benefit += this_time; - if (dump_file) + if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, " Likely eliminated\n"); } gcc_assert (time >= 0); @@ -1775,11 +1774,9 @@ estimate_function_body_sizes (struct cgraph_node *node) time_inlining_benefit = ((time_inlining_benefit + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE); if (dump_file) - { - fprintf (dump_file, "Overall function body time: %i-%i size: %i-%i\n", - (int)time, (int)time_inlining_benefit, - size, size_inlining_benefit); - } + fprintf (dump_file, "Overall function body time: %i-%i size: %i-%i\n", + (int)time, (int)time_inlining_benefit, + size, size_inlining_benefit); time_inlining_benefit += eni_time_weights.call_cost; size_inlining_benefit += eni_size_weights.call_cost; if (!VOID_TYPE_P (TREE_TYPE (funtype))) @@ -1802,11 +1799,9 @@ estimate_function_body_sizes (struct cgraph_node *node) inline_summary (node)->self_time = time; inline_summary (node)->self_size = size; if (dump_file) - { - fprintf (dump_file, "With function call overhead time: %i-%i size: %i-%i\n", - (int)time, (int)time_inlining_benefit, - size, size_inlining_benefit); - } + fprintf (dump_file, "With function call overhead time: %i-%i size: %i-%i\n", + (int)time, (int)time_inlining_benefit, + size, size_inlining_benefit); inline_summary (node)->time_inlining_benefit = time_inlining_benefit; inline_summary (node)->size_inlining_benefit = size_inlining_benefit; } -- cgit v1.2.1 From a1e880328b19d607aeef6885338b2d5df8fe86bb Mon Sep 17 00:00:00 2001 From: hubicka Date: Thu, 1 Oct 2009 23:20:15 +0000 Subject: * cgraph.c (cgraph_clone_node): Add redirect_callers parameter. (cgraph_create_virtual_clone): Just pass redirect_callers around. * cgraph.h (cgraph_clone_node): Update prototype. * ipa-pure-const.c (self_recursive_p): New function. (propagate): Use it. * ipa-inline.c (cgraph_clone_inlined_nodes, * cgraph_decide_recursive_inlining): Update. * gcc.dg/tree-ssa/ipa-cp-1.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152388 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 662e13f2512..8851d605372 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -238,7 +238,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, { struct cgraph_node *n; n = cgraph_clone_node (e->callee, e->count, e->frequency, e->loop_nest, - update_original); + update_original, NULL); cgraph_redirect_edge_callee (e, n); } } @@ -723,7 +723,8 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node, cgraph_node_name (node)); /* We need original clone to copy around. */ - master_clone = cgraph_clone_node (node, node->count, CGRAPH_FREQ_BASE, 1, false); + master_clone = cgraph_clone_node (node, node->count, CGRAPH_FREQ_BASE, 1, + false, NULL); master_clone->needed = true; for (e = master_clone->callees; e; e = e->next_callee) if (!e->inline_failed) -- cgit v1.2.1 From 7bfefa9d2c82e804ef4e59772f4060ac325bf99a Mon Sep 17 00:00:00 2001 From: dnovillo Date: Sat, 3 Oct 2009 21:10:11 +0000 Subject: Merge lto branch into trunk. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152434 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 8851d605372..0a02ae1770a 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -326,7 +326,7 @@ cgraph_mark_inline (struct cgraph_edge *edge) struct cgraph_node *what = edge->callee; struct cgraph_edge *e, *next; - gcc_assert (!gimple_call_cannot_inline_p (edge->call_stmt)); + gcc_assert (!edge->call_stmt_cannot_inline_p); /* Look for all calls, mark them inline and clone recursively all inlined functions. */ for (e = what->callers; e; e = next) @@ -1031,7 +1031,7 @@ cgraph_decide_inlining_of_small_functions (void) else { struct cgraph_node *callee; - if (gimple_call_cannot_inline_p (edge->call_stmt) + if (edge->call_stmt_cannot_inline_p || !cgraph_check_inline_limits (edge->caller, edge->callee, &edge->inline_failed, true)) { @@ -1111,7 +1111,13 @@ cgraph_decide_inlining (void) bool redo_always_inline = true; int initial_size = 0; - cgraph_remove_function_insertion_hook (function_insertion_hook_holder); + /* FIXME lto. We need to rethink how to coordinate different passes. */ + if (flag_ltrans) + return 0; + + /* FIXME lto. We need to re-think about how the passes get invoked. */ + if (!flag_wpa) + cgraph_remove_function_insertion_hook (function_insertion_hook_holder); max_count = 0; max_benefit = 0; @@ -1121,7 +1127,6 @@ cgraph_decide_inlining (void) struct cgraph_edge *e; gcc_assert (inline_summary (node)->self_size == node->global.size); - gcc_assert (node->needed || node->reachable); initial_size += node->global.size; for (e = node->callees; e; e = e->next_callee) if (max_count < e->count) @@ -1129,7 +1134,9 @@ cgraph_decide_inlining (void) if (max_benefit < inline_summary (node)->time_inlining_benefit) max_benefit = inline_summary (node)->time_inlining_benefit; } - gcc_assert (!max_count || (profile_info && flag_branch_probabilities)); + gcc_assert (in_lto_p + || !max_count + || (profile_info && flag_branch_probabilities)); overall_size = initial_size; nnodes = cgraph_postorder (order); @@ -1177,8 +1184,7 @@ cgraph_decide_inlining (void) for (e = node->callers; e; e = next) { next = e->next_caller; - if (!e->inline_failed - || gimple_call_cannot_inline_p (e->call_stmt)) + if (!e->inline_failed || e->call_stmt_cannot_inline_p) continue; if (cgraph_recursive_inlining_p (e->caller, e->callee, &e->inline_failed)) @@ -1225,7 +1231,7 @@ cgraph_decide_inlining (void) && node->callers->inline_failed && node->callers->caller != node && node->callers->caller->global.inlined_to != node - && !gimple_call_cannot_inline_p (node->callers->call_stmt) + && !node->callers->call_stmt_cannot_inline_p && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl)) { @@ -1411,7 +1417,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, if (!e->callee->local.disregard_inline_limits && (mode != INLINE_ALL || !e->callee->local.inlinable)) continue; - if (gimple_call_cannot_inline_p (e->call_stmt)) + if (e->call_stmt_cannot_inline_p) continue; /* When the edge is already inlined, we just need to recurse into it in order to fully flatten the leaves. */ @@ -1529,7 +1535,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, } if (!cgraph_check_inline_limits (node, e->callee, &e->inline_failed, false) - || gimple_call_cannot_inline_p (e->call_stmt)) + || e->call_stmt_cannot_inline_p) { if (dump_file) { @@ -1632,6 +1638,7 @@ static bool cgraph_gate_ipa_early_inlining (void) { return (flag_early_inlining + && !in_lto_p && (flag_branch_probabilities || flag_test_coverage || profile_arc_flag)); } @@ -1919,6 +1926,10 @@ inline_generate_summary (void) { struct cgraph_node *node; + /* FIXME lto. We should not run any IPA-summary pass in LTRANS mode. */ + if (flag_ltrans) + return; + function_insertion_hook_holder = cgraph_add_function_insertion_hook (&add_new_function, NULL); -- cgit v1.2.1 From 59dd48301d310463d3fffaf4c68d8df57fa20073 Mon Sep 17 00:00:00 2001 From: hubicka Date: Wed, 7 Oct 2009 09:01:16 +0000 Subject: * lto-symtab.c (lto_cgraph_replace_node): Assert that inline clones has no address taken. * cgraph.c (cgraph_mark_needed_node): Assert that inline clones are never needed. (cgraph_clone_node): Clear externally_visible flag for clones. * cgraph.h (cgraph_only_called_directly_p, cgraph_can_remove_if_no_direct_calls_p): New predicates. * tree-pass.h (pass_ipa_whole_program_visibility): Declare. * ipa-cp.c (ipcp_cloning_candidate_p): Use new predicate. (ipcp_initialize_node_lattices, ipcp_estimate_growth, ipcp_insert_stage): Likwise. * cgraphunit.c (cgraph_decide_is_function_needed): Do not compute externally_visible flag. (verify_cgraph_node): Verify that inline clones look right. (process_function_and_variable_attributes): Do not set externally_visible flags. (ipa_passes): Avoid executing small_ipa_passes at LTO stage; they've been already run. * lto-cgraph.c (lto_output_node): Assert that inline clones are not boundaries. * ipa-inline.c (cgraph_clone_inlined_nodes): Use new predicates; clear externally_visible when turning into inline clones (cgraph_mark_inline_edge): Use new predicates. (cgraph_estimate_growth): Likewise. (cgraph_decide_inlining): Likewise. * ipa.c (cgraph_postorder): Likewise. (cgraph_remove_unreachable_nodes): Likewise; sanity check that inline clones are not needed. (cgraph_externally_visible_p): New predicate. (function_and_variable_visibility): Add whole_program parameter; always set externally_visible flag; handle COMDAT function privatization. (local_function_and_variable_visibility): New function. (gate_whole_program_function_and_variable_visibility): New function. (whole_program_function_and_variable_visibility): New function. (pass_ipa_whole_program_visibility): New function. * passes.c (init_optimization_passes): Add whole program visibility pass. (do_per_function_toporder, function_called_by_processed_nodes_p): Do not care about needed/reachable flags. * varpool.c: Include flags.h (decide_is_variable_needed): When doing LTO assume whole-program mode. (varpool_finalize_decl): When we are in LTO read-back, all variables are analyzed. (varpool_analyze_pending_decls): Skip analyzis of analyzed vars. * lto/lto.c (read_cgraph_and_symbols): Mark functions neccesary only at ltrans stage; explain why this is needed and should not. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152520 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 0a02ae1770a..18e440a60fe 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -223,7 +223,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, /* We may eliminate the need for out-of-line copy to be output. In that case just go ahead and re-use it. */ if (!e->callee->callers->next_caller - && !e->callee->needed + && cgraph_can_remove_if_no_direct_calls_p (e->callee) && !cgraph_new_nodes) { gcc_assert (!e->callee->global.inlined_to); @@ -233,6 +233,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, nfunctions_inlined++; } duplicate = false; + e->callee->local.externally_visible = false; } else { @@ -286,7 +287,7 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, e->callee->global.inlined = true; if (e->callee->callers->next_caller - || e->callee->needed) + || !cgraph_can_remove_if_no_direct_calls_p (e->callee)) duplicate = true; cgraph_clone_inlined_nodes (e, true, update_original); @@ -368,7 +369,8 @@ cgraph_estimate_growth (struct cgraph_node *node) we decide to not inline for different reasons, but it is not big deal as in that case we will keep the body around, but we will also avoid some inlining. */ - if (!node->needed && !DECL_EXTERNAL (node->decl) && !self_recursive) + if (cgraph_only_called_directly_p (node) + && !DECL_EXTERNAL (node->decl) && !self_recursive) growth -= node->global.size; node->global.estimated_growth = growth; @@ -1226,7 +1228,7 @@ cgraph_decide_inlining (void) if (node->callers && !node->callers->next_caller - && !node->needed + && cgraph_only_called_directly_p (node) && node->local.inlinable && node->callers->inline_failed && node->callers->caller != node -- cgit v1.2.1 From 8867b500961593ba73be72ea17bbbd4f8a2d74ef Mon Sep 17 00:00:00 2001 From: hubicka Date: Thu, 22 Oct 2009 10:02:29 +0000 Subject: * ipa-cp.c (ipcp_write_summary, ipcp_read_summary): New functions. (pass_ipa_cp): Register them. (ipcp_init_stage): Analyze all functions for whopr/lto. (ipcp_propagate_stage): Skip external calls. (ipcp_iterate_stage): Call ipa_update_after_lto_read if needed. * ipa-reference.c (write_node_summary_p): Fix thinko about availability. * cgraphunit.c (ipa_passes): When in lto, ne er produce new summaries; when in ltrans, skip executing of ipa passes since everything should've been done. * ipa-inline.c (cgraph_decide_inlining): Remove FIXMEs. (inline_generate_summary): Likewise. (inline_read_summary): New function. (inline_write_summary): New function. (pass_ipa_inline): Register new hooks. * ipa-prop.c: Inlcude lto-streamer.h (ipa_edge_args_vector): Update declaration. (ipa_count_arguments, ipa_compute_jump_functions, ipa_free_edge_args_substructures): Move ipa_edge_args_vector into ggc. (ipa_write_jump_function, ipa_read_jump_function, ipa_write_node_info, ipa_read_node_info): New static functions. (ipa_prop_write_jump_functions, ipa_prop_read_jump_functions): Update. (duplicate_array): Use xmalloc. (duplicate_ggc_array): New. (ipa_edge_duplication_hook): Use it. (ipa_update_after_lto_read): New function. * ipa-prop.h (ipa_prop_write_jump_functions, ipa_prop_read_jump_functions): Declare. (ipa_pass_through_data, ipa_ancestor_jf_data, ipa_member_ptr_cst, jump_func_value, ipa_member_ptr_cst, ipa_edge_args): Add GTY markers. (ipa_edge_args_vector): Move into GGC. (ipa_check_create_edge_args): Update. (ipa_update_after_lto_read): New. * passes.c (ipa_write_summaries_1): When in wpa, do not write summaries. (ipa_read_summaries): When in ltrans, so not read summaries. * lto-streamer.c (lto_get_section_name): Add LTO_section_jump_functions. * lto-streamer.h (LTO_section_jump_functions): New section. (produce_asm): Declare. * lto-cgraph.c (output_cgraph): Output edges in reverse order. * lto-streamer-out.c (produce_asm): Export. * lto-streamer-in.c: Include tree-pass.h (input_function): Free dominance info when done. (lto_read_body): Push ipa_inline in ltrans stage. * gengtype.c (open_base_files): Add ipa-prop.h into includes. * Makefile.in (GTFILES): Add ipa-prop.h * lto.c (lto_fixup_jump_functions): New function. (lto_fixup_decls): Use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153449 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 46 +++++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 18e440a60fe..9e1bc9f4883 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1113,13 +1113,9 @@ cgraph_decide_inlining (void) bool redo_always_inline = true; int initial_size = 0; - /* FIXME lto. We need to rethink how to coordinate different passes. */ - if (flag_ltrans) - return 0; - - /* FIXME lto. We need to re-think about how the passes get invoked. */ - if (!flag_wpa) - cgraph_remove_function_insertion_hook (function_insertion_hook_holder); + cgraph_remove_function_insertion_hook (function_insertion_hook_holder); + if (in_lto_p && flag_indirect_inlining) + ipa_update_after_lto_read (); max_count = 0; max_benefit = 0; @@ -1928,10 +1924,6 @@ inline_generate_summary (void) { struct cgraph_node *node; - /* FIXME lto. We should not run any IPA-summary pass in LTRANS mode. */ - if (flag_ltrans) - return; - function_insertion_hook_holder = cgraph_add_function_insertion_hook (&add_new_function, NULL); @@ -1976,6 +1968,34 @@ inline_transform (struct cgraph_node *node) return todo | execute_fixup_cfg (); } +/* Read inline summary. Jump functions are shared among ipa-cp + and inliner, so when ipa-cp is active, we don't need to write them + twice. */ + +static void +inline_read_summary (void) +{ + if (flag_indirect_inlining) + { + ipa_register_cgraph_hooks (); + if (!flag_ipa_cp) + ipa_prop_read_jump_functions (); + } + function_insertion_hook_holder = + cgraph_add_function_insertion_hook (&add_new_function, NULL); +} + +/* Write inline summary for node in SET. + Jump functions are shared among ipa-cp and inliner, so when ipa-cp is + active, we don't need to write them twice. */ + +static void +inline_write_summary (cgraph_node_set set) +{ + if (flag_indirect_inlining && !flag_ipa_cp) + ipa_prop_write_jump_functions (set); +} + struct ipa_opt_pass_d pass_ipa_inline = { { @@ -1995,8 +2015,8 @@ struct ipa_opt_pass_d pass_ipa_inline = | TODO_remove_functions /* todo_flags_finish */ }, inline_generate_summary, /* generate_summary */ - NULL, /* write_summary */ - NULL, /* read_summary */ + inline_write_summary, /* write_summary */ + inline_read_summary, /* read_summary */ NULL, /* function_read_summary */ 0, /* TODOs */ inline_transform, /* function_transform */ -- cgit v1.2.1 From 13ea1784af6bf316db969e8ec33be8cc1a9bf716 Mon Sep 17 00:00:00 2001 From: hubicka Date: Thu, 22 Oct 2009 13:31:48 +0000 Subject: * ipa-cp.c (ipcp_read_summary): Remove now invalid FIXME and flag_ltrans check. * ipa-inline.c (cgraph_mark_inline_edge, cgraph_decide_inlining_of_small_function, cgraph_decide_inlining, inline_read_summary): Disable indirect inlining for WPA for time being. PR tree-optimize/40556 * ipa-inline.c (cgraph_early_inlining): Fix iterations condition. Fix PR number for earlier patch to: PR lto/41730 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153456 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 9e1bc9f4883..81c3379ca2e 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -310,7 +310,7 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, overall_size -= orig_size; ncalls_inlined++; - if (flag_indirect_inlining) + if (flag_indirect_inlining && !flag_wpa) return ipa_propagate_indirect_call_infos (curr, new_edges); else return false; @@ -876,7 +876,7 @@ cgraph_decide_inlining_of_small_functions (void) int min_size, max_size; VEC (cgraph_edge_p, heap) *new_indirect_edges = NULL; - if (flag_indirect_inlining) + if (flag_indirect_inlining && !flag_wpa) new_indirect_edges = VEC_alloc (cgraph_edge_p, heap, 8); if (dump_file) @@ -1023,10 +1023,10 @@ cgraph_decide_inlining_of_small_functions (void) if (where->global.inlined_to) where = where->global.inlined_to; if (!cgraph_decide_recursive_inlining (where, - flag_indirect_inlining + flag_indirect_inlining && !flag_wpa ? &new_indirect_edges : NULL)) continue; - if (flag_indirect_inlining) + if (flag_indirect_inlining && !flag_wpa) add_new_edges_to_heap (heap, new_indirect_edges); update_callee_keys (heap, where, updated_nodes); } @@ -1045,7 +1045,7 @@ cgraph_decide_inlining_of_small_functions (void) } callee = edge->callee; cgraph_mark_inline_edge (edge, true, &new_indirect_edges); - if (flag_indirect_inlining) + if (flag_indirect_inlining && !flag_wpa) add_new_edges_to_heap (heap, new_indirect_edges); update_callee_keys (heap, callee, updated_nodes); @@ -1114,7 +1114,7 @@ cgraph_decide_inlining (void) int initial_size = 0; cgraph_remove_function_insertion_hook (function_insertion_hook_holder); - if (in_lto_p && flag_indirect_inlining) + if (in_lto_p && flag_indirect_inlining && !flag_wpa) ipa_update_after_lto_read (); max_count = 0; @@ -1268,7 +1268,7 @@ cgraph_decide_inlining (void) } /* Free ipa-prop structures if they are no longer needed. */ - if (flag_indirect_inlining) + if (flag_indirect_inlining && !flag_wpa) free_all_ipa_structures_after_iinln (); if (dump_file) @@ -1589,10 +1589,10 @@ cgraph_early_inlining (void) if (sorrycount || errorcount) return 0; - while (cgraph_decide_inlining_incrementally (node, - iterations - ? INLINE_SIZE_NORECURSIVE : INLINE_SIZE, 0) - && iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS)) + while (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) + && cgraph_decide_inlining_incrementally (node, + iterations + ? INLINE_SIZE_NORECURSIVE : INLINE_SIZE, 0)) { timevar_push (TV_INTEGRATION); todo |= optimize_inline_calls (current_function_decl); @@ -1975,7 +1975,7 @@ inline_transform (struct cgraph_node *node) static void inline_read_summary (void) { - if (flag_indirect_inlining) + if (flag_indirect_inlining && !flag_wpa) { ipa_register_cgraph_hooks (); if (!flag_ipa_cp) -- cgit v1.2.1 From 16fe1d8cfd8eb2f5b9812108e830c5e44a05a379 Mon Sep 17 00:00:00 2001 From: toon Date: Sat, 31 Oct 2009 13:51:48 +0000 Subject: 2009-10-31 Toon Moene * ipa-inline.c (cgraph_decide_inlining): Include reason for not inlining called-once functions in dump file. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153776 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 81c3379ca2e..bc7048f51c6 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1233,6 +1233,7 @@ cgraph_decide_inlining (void) && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl)) { + cgraph_inline_failed_t reason; old_size = overall_size; if (dump_file) { @@ -1246,7 +1247,7 @@ cgraph_decide_inlining (void) } if (cgraph_check_inline_limits (node->callers->caller, node, - NULL, false)) + &reason, false)) { cgraph_mark_inline (node->callers); if (dump_file) @@ -1261,7 +1262,8 @@ cgraph_decide_inlining (void) { if (dump_file) fprintf (dump_file, - " Inline limit reached, not inlined.\n"); + " Not inlining: %s.\n", + cgraph_inline_failed_string (reason)); } } } -- cgit v1.2.1 From 90464c8b80ce61e7f80340c404a8a1b3ffc41316 Mon Sep 17 00:00:00 2001 From: jamborm Date: Tue, 10 Nov 2009 14:43:20 +0000 Subject: 2009-11-10 Martin Jambor * tree-pass.h (struct ipa_opt_pass_d): Added stmt_fixup field. (execute_all_ipa_stmt_fixups): Declare. * ipa-cp.c (pass_ipa_cp): Added stmt_fixup value. * ipa-inline.c (pass_ipa_inline): Likewise. * ipa-pure-const.c (pass_ipa_pure_cons): Likewise. * ipa-reference.c (pass_ipa_reference): Likewise. * ipa.c (pass_ipa_whole_program_visibility): Likewise. * lto-streamer-out.c (pass_ipa_lto_gimple_out): Likewise. (pass_ipa_lto_finish_out): Likewise. * lto-wpa-fixup.c (pass_ipa_lto_wpa_fixup): Likewise. * passes.c (execute_ipa_stmt_fixups): New function. (execute_all_ipa_stmt_fixups): New function. * lto-streamer-in.c (input_function): Call execute_all_ipa_stmt_fixups. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154064 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index bc7048f51c6..08088dd3e79 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -2020,6 +2020,7 @@ struct ipa_opt_pass_d pass_ipa_inline = inline_write_summary, /* write_summary */ inline_read_summary, /* read_summary */ NULL, /* function_read_summary */ + NULL, /* stmt_fixup */ 0, /* TODOs */ inline_transform, /* function_transform */ NULL, /* variable_transform */ -- cgit v1.2.1 From e2d3f42272e712ce0bda8583066fdf858041ce77 Mon Sep 17 00:00:00 2001 From: hubicka Date: Mon, 16 Nov 2009 16:06:29 +0000 Subject: * cgraphbuild.c (compute_call_stmt_bb_frequency): Use proper ENTRY_BLOCK_PTR. * cgraph.c (cgraph_clone_edge): Avoid freq_scale 0 to completely zero out all callees. * cgraphunit.c (verify_cgraph_node): Verify cgraph nodes for frequency and count match. * ipa-inline.c (update_noncloned_frequencies): New function. (cgraph_clone_inlined_nodes): Use it. * tree-inline.c (copy_bb): Fix frequency scaling; output diagnostic on frequency mismatches to dump file. (initialize_cfun): Do not scale frequency; fix count scaling; initialize entry and exit block frequencies; copy profile info. (copy_cfg_body): Use frequency_scale as argument; fix count scaling. (copy_body): Use frequency_scale as argument. (expand_call_inline): Compute frequency scale and output diagnostic to dump file. (delete_unreachable_blocks_update_callgrah): Remove checking that has to be done after edge redirection. (tree_function_versioning): Update initialize_cfun and copy_body call. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154205 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 08088dd3e79..e9d831153fe 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -207,6 +207,29 @@ cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to, return size; } +/* Scale frequency of NODE edges by FREQ_SCALE and increase loop nest + by NEST. */ + +static void +update_noncloned_frequencies (struct cgraph_node *node, + int freq_scale, int nest) +{ + struct cgraph_edge *e; + + /* We do not want to ignore high loop nest after freq drops to 0. */ + if (!freq_scale) + freq_scale = 1; + for (e = node->callees; e; e = e->next_callee) + { + e->loop_nest += nest; + e->frequency = e->frequency * (gcov_type) freq_scale / CGRAPH_FREQ_BASE; + if (e->frequency > CGRAPH_FREQ_MAX) + e->frequency = CGRAPH_FREQ_MAX; + if (!e->inline_failed) + update_noncloned_frequencies (e->callee, freq_scale, nest); + } +} + /* E is expected to be an edge being inlined. Clone destination node of the edge and redirect it to the new clone. DUPLICATE is used for bookkeeping on whether we are actually creating new @@ -234,6 +257,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, } duplicate = false; e->callee->local.externally_visible = false; + update_noncloned_frequencies (e->callee, e->frequency, e->loop_nest); } else { -- cgit v1.2.1 From 00e1f01e202daa28722e658dcb573c1f10e53ea3 Mon Sep 17 00:00:00 2001 From: jamborm Date: Wed, 18 Nov 2009 14:10:02 +0000 Subject: 2009-11-18 Martin Jambor * ipa-prop.h (struct ipa_param_call_note): New field lto_stmt_uid. (lto_ipa_fixup_call_notes): Declare. * ipa-prop.c (ipa_note_param_call): Store gimple uid. (update_call_notes_after_inlining): Copy call stmt uid to the new edge. (ipa_write_param_call_note): New function. (ipa_read_param_call_note): New function (ipa_write_node_info): Write also param call notes. Removed a bogus comment, reformatted to fit 80 columns. (ipa_read_node_info): Read also param call notes. Removed a bogus comment. Remove ipa_edge_args_vector growth. (lto_ipa_fixup_call_notes): New function. * ipa-cp.c (pass_ipa_cp): Add stmt_fixup hook. * ipa-inline.c (cgraph_mark_inline_edge): Perform indirect inlining regardless of flag_wpa. (cgraph_decide_inlining_of_small_functions): Likewise. (cgraph_decide_inlining): Likewise. (inline_read_summary): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154293 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index e9d831153fe..786c21c0ca3 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -334,7 +334,7 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, overall_size -= orig_size; ncalls_inlined++; - if (flag_indirect_inlining && !flag_wpa) + if (flag_indirect_inlining) return ipa_propagate_indirect_call_infos (curr, new_edges); else return false; @@ -900,7 +900,7 @@ cgraph_decide_inlining_of_small_functions (void) int min_size, max_size; VEC (cgraph_edge_p, heap) *new_indirect_edges = NULL; - if (flag_indirect_inlining && !flag_wpa) + if (flag_indirect_inlining) new_indirect_edges = VEC_alloc (cgraph_edge_p, heap, 8); if (dump_file) @@ -1047,10 +1047,10 @@ cgraph_decide_inlining_of_small_functions (void) if (where->global.inlined_to) where = where->global.inlined_to; if (!cgraph_decide_recursive_inlining (where, - flag_indirect_inlining && !flag_wpa + flag_indirect_inlining ? &new_indirect_edges : NULL)) continue; - if (flag_indirect_inlining && !flag_wpa) + if (flag_indirect_inlining) add_new_edges_to_heap (heap, new_indirect_edges); update_callee_keys (heap, where, updated_nodes); } @@ -1069,7 +1069,7 @@ cgraph_decide_inlining_of_small_functions (void) } callee = edge->callee; cgraph_mark_inline_edge (edge, true, &new_indirect_edges); - if (flag_indirect_inlining && !flag_wpa) + if (flag_indirect_inlining) add_new_edges_to_heap (heap, new_indirect_edges); update_callee_keys (heap, callee, updated_nodes); @@ -1138,7 +1138,7 @@ cgraph_decide_inlining (void) int initial_size = 0; cgraph_remove_function_insertion_hook (function_insertion_hook_holder); - if (in_lto_p && flag_indirect_inlining && !flag_wpa) + if (in_lto_p && flag_indirect_inlining) ipa_update_after_lto_read (); max_count = 0; @@ -1294,7 +1294,7 @@ cgraph_decide_inlining (void) } /* Free ipa-prop structures if they are no longer needed. */ - if (flag_indirect_inlining && !flag_wpa) + if (flag_indirect_inlining) free_all_ipa_structures_after_iinln (); if (dump_file) @@ -2001,7 +2001,7 @@ inline_transform (struct cgraph_node *node) static void inline_read_summary (void) { - if (flag_indirect_inlining && !flag_wpa) + if (flag_indirect_inlining) { ipa_register_cgraph_hooks (); if (!flag_ipa_cp) @@ -2044,7 +2044,7 @@ struct ipa_opt_pass_d pass_ipa_inline = inline_write_summary, /* write_summary */ inline_read_summary, /* read_summary */ NULL, /* function_read_summary */ - NULL, /* stmt_fixup */ + lto_ipa_fixup_call_notes, /* stmt_fixup */ 0, /* TODOs */ inline_transform, /* function_transform */ NULL, /* variable_transform */ -- cgit v1.2.1 From 2511f7808247c921b32ff73dbf82527b77f92215 Mon Sep 17 00:00:00 2001 From: hubicka Date: Mon, 23 Nov 2009 22:27:15 +0000 Subject: PR middle-end/42151 * ipa-inline.c (inline_transform): Avoid ICE when transform is called twice. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154475 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 786c21c0ca3..495d8851247 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1974,6 +1974,11 @@ inline_transform (struct cgraph_node *node) unsigned int todo = 0; struct cgraph_edge *e; + /* FIXME: Currently the passmanager is adding inline transform more than once to some + clones. This needs revisiting after WPA cleanups. */ + if (cfun->after_inlining) + return 0; + /* We might need the body of this function so that we can expand it inline somewhere else. */ if (cgraph_preserve_function_body_p (node->decl)) -- cgit v1.2.1 From 48e1416a24d50cacbb2a5e06a9ee61dd8cbee313 Mon Sep 17 00:00:00 2001 From: hjl Date: Wed, 25 Nov 2009 10:55:54 +0000 Subject: Remove trailing white spaces. 2009-11-25 H.J. Lu * alias.c: Remove trailing white spaces. * alloc-pool.c: Likewise. * alloc-pool.h: Likewise. * attribs.c: Likewise. * auto-inc-dec.c: Likewise. * basic-block.h: Likewise. * bb-reorder.c: Likewise. * bt-load.c: Likewise. * builtins.c: Likewise. * builtins.def: Likewise. * c-common.c: Likewise. * c-common.h: Likewise. * c-cppbuiltin.c: Likewise. * c-decl.c: Likewise. * c-format.c: Likewise. * c-lex.c: Likewise. * c-omp.c: Likewise. * c-opts.c: Likewise. * c-parser.c: Likewise. * c-pretty-print.c: Likewise. * c-tree.h: Likewise. * c-typeck.c: Likewise. * caller-save.c: Likewise. * calls.c: Likewise. * cfg.c: Likewise. * cfganal.c: Likewise. * cfgexpand.c: Likewise. * cfghooks.c: Likewise. * cfghooks.h: Likewise. * cfglayout.c: Likewise. * cfgloop.c: Likewise. * cfgloop.h: Likewise. * cfgloopmanip.c: Likewise. * cfgrtl.c: Likewise. * cgraph.c: Likewise. * cgraph.h: Likewise. * cgraphbuild.c: Likewise. * cgraphunit.c: Likewise. * cif-code.def: Likewise. * collect2.c: Likewise. * combine.c: Likewise. * convert.c: Likewise. * coverage.c: Likewise. * crtstuff.c: Likewise. * cse.c: Likewise. * cselib.c: Likewise. * dbgcnt.c: Likewise. * dbgcnt.def: Likewise. * dbgcnt.h: Likewise. * dbxout.c: Likewise. * dce.c: Likewise. * ddg.c: Likewise. * ddg.h: Likewise. * defaults.h: Likewise. * df-byte-scan.c: Likewise. * df-core.c: Likewise. * df-problems.c: Likewise. * df-scan.c: Likewise. * df.h: Likewise. * dfp.c: Likewise. * diagnostic.c: Likewise. * diagnostic.h: Likewise. * dominance.c: Likewise. * domwalk.c: Likewise. * double-int.c: Likewise. * double-int.h: Likewise. * dse.c: Likewise. * dwarf2asm.c: Likewise. * dwarf2asm.h: Likewise. * dwarf2out.c: Likewise. * ebitmap.c: Likewise. * ebitmap.h: Likewise. * emit-rtl.c: Likewise. * et-forest.c: Likewise. * except.c: Likewise. * except.h: Likewise. * expmed.c: Likewise. * expr.c: Likewise. * expr.h: Likewise. * final.c: Likewise. * flags.h: Likewise. * fold-const.c: Likewise. * function.c: Likewise. * function.h: Likewise. * fwprop.c: Likewise. * gcc.c: Likewise. * gcov-dump.c: Likewise. * gcov-io.c: Likewise. * gcov-io.h: Likewise. * gcov.c: Likewise. * gcse.c: Likewise. * genattr.c: Likewise. * genattrtab.c: Likewise. * genautomata.c: Likewise. * genchecksum.c: Likewise. * genconfig.c: Likewise. * genflags.c: Likewise. * gengtype-parse.c: Likewise. * gengtype.c: Likewise. * gengtype.h: Likewise. * genmddeps.c: Likewise. * genmodes.c: Likewise. * genopinit.c: Likewise. * genpreds.c: Likewise. * gensupport.c: Likewise. * ggc-common.c: Likewise. * ggc-page.c: Likewise. * ggc-zone.c: Likewise. * ggc.h: Likewise. * gimple-iterator.c: Likewise. * gimple-low.c: Likewise. * gimple-pretty-print.c: Likewise. * gimple.c: Likewise. * gimple.def: Likewise. * gimple.h: Likewise. * gimplify.c: Likewise. * graphds.c: Likewise. * graphite-clast-to-gimple.c: Likewise. * gthr-nks.h: Likewise. * gthr-posix.c: Likewise. * gthr-posix.h: Likewise. * gthr-posix95.h: Likewise. * gthr-single.h: Likewise. * gthr-tpf.h: Likewise. * gthr-vxworks.h: Likewise. * gthr.h: Likewise. * haifa-sched.c: Likewise. * hard-reg-set.h: Likewise. * hooks.c: Likewise. * hooks.h: Likewise. * hosthooks.h: Likewise. * hwint.h: Likewise. * ifcvt.c: Likewise. * incpath.c: Likewise. * init-regs.c: Likewise. * integrate.c: Likewise. * ipa-cp.c: Likewise. * ipa-inline.c: Likewise. * ipa-prop.c: Likewise. * ipa-pure-const.c: Likewise. * ipa-reference.c: Likewise. * ipa-struct-reorg.c: Likewise. * ipa-struct-reorg.h: Likewise. * ipa-type-escape.c: Likewise. * ipa-type-escape.h: Likewise. * ipa-utils.c: Likewise. * ipa-utils.h: Likewise. * ipa.c: Likewise. * ira-build.c: Likewise. * ira-color.c: Likewise. * ira-conflicts.c: Likewise. * ira-costs.c: Likewise. * ira-emit.c: Likewise. * ira-int.h: Likewise. * ira-lives.c: Likewise. * ira.c: Likewise. * jump.c: Likewise. * lambda-code.c: Likewise. * lambda-mat.c: Likewise. * lambda-trans.c: Likewise. * lambda.h: Likewise. * langhooks.c: Likewise. * lcm.c: Likewise. * libgcov.c: Likewise. * lists.c: Likewise. * loop-doloop.c: Likewise. * loop-init.c: Likewise. * loop-invariant.c: Likewise. * loop-iv.c: Likewise. * loop-unroll.c: Likewise. * lower-subreg.c: Likewise. * lto-cgraph.c: Likewise. * lto-compress.c: Likewise. * lto-opts.c: Likewise. * lto-section-in.c: Likewise. * lto-section-out.c: Likewise. * lto-streamer-in.c: Likewise. * lto-streamer-out.c: Likewise. * lto-streamer.c: Likewise. * lto-streamer.h: Likewise. * lto-symtab.c: Likewise. * lto-wpa-fixup.c: Likewise. * matrix-reorg.c: Likewise. * mcf.c: Likewise. * mode-switching.c: Likewise. * modulo-sched.c: Likewise. * omega.c: Likewise. * omega.h: Likewise. * omp-low.c: Likewise. * optabs.c: Likewise. * optabs.h: Likewise. * opts-common.c: Likewise. * opts.c: Likewise. * params.def: Likewise. * params.h: Likewise. * passes.c: Likewise. * plugin.c: Likewise. * postreload-gcse.c: Likewise. * postreload.c: Likewise. * predict.c: Likewise. * predict.def: Likewise. * pretty-print.c: Likewise. * pretty-print.h: Likewise. * print-rtl.c: Likewise. * print-tree.c: Likewise. * profile.c: Likewise. * read-rtl.c: Likewise. * real.c: Likewise. * recog.c: Likewise. * reg-stack.c: Likewise. * regcprop.c: Likewise. * reginfo.c: Likewise. * regmove.c: Likewise. * regrename.c: Likewise. * regs.h: Likewise. * regstat.c: Likewise. * reload.c: Likewise. * reload1.c: Likewise. * resource.c: Likewise. * rtl.c: Likewise. * rtl.def: Likewise. * rtl.h: Likewise. * rtlanal.c: Likewise. * sbitmap.c: Likewise. * sched-deps.c: Likewise. * sched-ebb.c: Likewise. * sched-int.h: Likewise. * sched-rgn.c: Likewise. * sched-vis.c: Likewise. * sdbout.c: Likewise. * sel-sched-dump.c: Likewise. * sel-sched-dump.h: Likewise. * sel-sched-ir.c: Likewise. * sel-sched-ir.h: Likewise. * sel-sched.c: Likewise. * sel-sched.h: Likewise. * sese.c: Likewise. * sese.h: Likewise. * simplify-rtx.c: Likewise. * stack-ptr-mod.c: Likewise. * stmt.c: Likewise. * stor-layout.c: Likewise. * store-motion.c: Likewise. * stringpool.c: Likewise. * stub-objc.c: Likewise. * sync-builtins.def: Likewise. * target-def.h: Likewise. * target.h: Likewise. * targhooks.c: Likewise. * targhooks.h: Likewise. * timevar.c: Likewise. * tlink.c: Likewise. * toplev.c: Likewise. * toplev.h: Likewise. * tracer.c: Likewise. * tree-affine.c: Likewise. * tree-affine.h: Likewise. * tree-browser.def: Likewise. * tree-call-cdce.c: Likewise. * tree-cfg.c: Likewise. * tree-cfgcleanup.c: Likewise. * tree-chrec.c: Likewise. * tree-chrec.h: Likewise. * tree-complex.c: Likewise. * tree-data-ref.c: Likewise. * tree-data-ref.h: Likewise. * tree-dfa.c: Likewise. * tree-dump.c: Likewise. * tree-dump.h: Likewise. * tree-eh.c: Likewise. * tree-flow-inline.h: Likewise. * tree-flow.h: Likewise. * tree-if-conv.c: Likewise. * tree-inline.c: Likewise. * tree-into-ssa.c: Likewise. * tree-loop-distribution.c: Likewise. * tree-loop-linear.c: Likewise. * tree-mudflap.c: Likewise. * tree-nested.c: Likewise. * tree-nomudflap.c: Likewise. * tree-nrv.c: Likewise. * tree-object-size.c: Likewise. * tree-optimize.c: Likewise. * tree-outof-ssa.c: Likewise. * tree-parloops.c: Likewise. * tree-pass.h: Likewise. * tree-phinodes.c: Likewise. * tree-predcom.c: Likewise. * tree-pretty-print.c: Likewise. * tree-profile.c: Likewise. * tree-scalar-evolution.c: Likewise. * tree-ssa-address.c: Likewise. * tree-ssa-alias.c: Likewise. * tree-ssa-ccp.c: Likewise. * tree-ssa-coalesce.c: Likewise. * tree-ssa-copy.c: Likewise. * tree-ssa-copyrename.c: Likewise. * tree-ssa-dce.c: Likewise. * tree-ssa-dom.c: Likewise. * tree-ssa-dse.c: Likewise. * tree-ssa-forwprop.c: Likewise. * tree-ssa-ifcombine.c: Likewise. * tree-ssa-live.c: Likewise. * tree-ssa-live.h: Likewise. * tree-ssa-loop-ch.c: Likewise. * tree-ssa-loop-im.c: Likewise. * tree-ssa-loop-ivcanon.c: Likewise. * tree-ssa-loop-ivopts.c: Likewise. * tree-ssa-loop-manip.c: Likewise. * tree-ssa-loop-niter.c: Likewise. * tree-ssa-loop-prefetch.c: Likewise. * tree-ssa-loop-unswitch.c: Likewise. * tree-ssa-loop.c: Likewise. * tree-ssa-math-opts.c: Likewise. * tree-ssa-operands.c: Likewise. * tree-ssa-operands.h: Likewise. * tree-ssa-phiopt.c: Likewise. * tree-ssa-phiprop.c: Likewise. * tree-ssa-pre.c: Likewise. * tree-ssa-propagate.c: Likewise. * tree-ssa-reassoc.c: Likewise. * tree-ssa-sccvn.c: Likewise. * tree-ssa-sink.c: Likewise. * tree-ssa-structalias.c: Likewise. * tree-ssa-ter.c: Likewise. * tree-ssa-threadedge.c: Likewise. * tree-ssa-threadupdate.c: Likewise. * tree-ssa-uncprop.c: Likewise. * tree-ssa.c: Likewise. * tree-ssanames.c: Likewise. * tree-switch-conversion.c: Likewise. * tree-tailcall.c: Likewise. * tree-vect-data-refs.c: Likewise. * tree-vect-generic.c: Likewise. * tree-vect-loop-manip.c: Likewise. * tree-vect-loop.c: Likewise. * tree-vect-patterns.c: Likewise. * tree-vect-slp.c: Likewise. * tree-vect-stmts.c: Likewise. * tree-vectorizer.c: Likewise. * tree-vectorizer.h: Likewise. * tree-vrp.c: Likewise. * tree.c: Likewise. * tree.def: Likewise. * tree.h: Likewise. * treestruct.def: Likewise. * unwind-compat.c: Likewise. * unwind-dw2-fde-glibc.c: Likewise. * unwind-dw2.c: Likewise. * value-prof.c: Likewise. * value-prof.h: Likewise. * var-tracking.c: Likewise. * varasm.c: Likewise. * varpool.c: Likewise. * vec.c: Likewise. * vec.h: Likewise. * vmsdbgout.c: Likewise. * web.c: Likewise. * xcoffout.c: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154645 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 495d8851247..120c234f89b 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -262,7 +262,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, else { struct cgraph_node *n; - n = cgraph_clone_node (e->callee, e->count, e->frequency, e->loop_nest, + n = cgraph_clone_node (e->callee, e->count, e->frequency, e->loop_nest, update_original, NULL); cgraph_redirect_edge_callee (e, n); } @@ -402,7 +402,7 @@ cgraph_estimate_growth (struct cgraph_node *node) } /* Return false when inlining WHAT into TO is not good idea - as it would cause too large growth of function bodies. + as it would cause too large growth of function bodies. When ONE_ONLY is true, assume that only one call site is going to be inlined, otherwise figure out how many call sites in TO calls WHAT and verify that all can be inlined. @@ -571,7 +571,7 @@ cgraph_edge_badness (struct cgraph_edge *edge) badness = growth * 10000; div *= MIN (100 * inline_summary (edge->callee)->time_inlining_benefit / (edge->callee->global.time + 1) + 1, 100); - + /* Decrease badness if call is nested. */ /* Compress the range so we don't overflow. */ @@ -595,7 +595,7 @@ cgraph_edge_badness (struct cgraph_edge *edge) badness = cgraph_estimate_growth (edge->callee) * 256; /* Decrease badness if call is nested. */ - if (badness > 0) + if (badness > 0) badness >>= nest; else { @@ -744,7 +744,7 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node, } if (dump_file) - fprintf (dump_file, + fprintf (dump_file, " Performing recursive inlining on %s\n", cgraph_node_name (node)); @@ -773,7 +773,7 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node, if (depth > max_depth) { if (dump_file) - fprintf (dump_file, + fprintf (dump_file, " maximal depth reached\n"); continue; } @@ -789,7 +789,7 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node, if (curr->count * 100 / node->count < probability) { if (dump_file) - fprintf (dump_file, + fprintf (dump_file, " Probability of edge is too small\n"); continue; } @@ -797,7 +797,7 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node, if (dump_file) { - fprintf (dump_file, + fprintf (dump_file, " Inlining call of depth %i", depth); if (node->count) { @@ -816,7 +816,7 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node, fibheap_delete (heap); if (dump_file) - fprintf (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); @@ -947,11 +947,11 @@ cgraph_decide_inlining_of_small_functions (void) if (dump_file) { - fprintf (dump_file, + fprintf (dump_file, "\nConsidering %s with %i size\n", cgraph_node_name (edge->callee), edge->callee->global.size); - fprintf (dump_file, + fprintf (dump_file, " to be inlined into %s in %s:%i\n" " Estimated growth after inlined into all callees is %+i insns.\n" " Estimated badness is %i, frequency %.2f.\n", @@ -1089,7 +1089,7 @@ cgraph_decide_inlining_of_small_functions (void) if (dump_file) { - fprintf (dump_file, + fprintf (dump_file, " Inlined into %s which now has size %i and self time %i," "net change of %+i.\n", cgraph_node_name (edge->caller), @@ -1228,7 +1228,7 @@ cgraph_decide_inlining (void) if (e->inline_failed) e->inline_failed = CIF_RECURSIVE_INLINING; if (dump_file) - fprintf (dump_file, + fprintf (dump_file, " Inlined for a net change of %+i size.\n", overall_size - old_size); } @@ -1360,7 +1360,7 @@ try_inline (struct cgraph_edge *e, enum inlining_mode mode, int depth) return false; } } - + callee->aux = (void *)(size_t) mode; if (dump_file) { @@ -1375,7 +1375,7 @@ try_inline (struct cgraph_edge *e, enum inlining_mode mode, int depth) /* In order to fully inline always_inline functions, we need to recurse here, since the inlined functions might not be processed by - incremental inlining at all yet. + incremental inlining at all yet. Also flattening needs to be done recursively. */ @@ -1402,7 +1402,7 @@ leaf_node_p (struct cgraph_node *n) } /* Decide on the inlining. We do so in the topological order to avoid - expenses on updating data structures. + expenses on updating data structures. DEPTH is depth of recursion, used only for debug output. */ static bool @@ -1638,7 +1638,7 @@ cgraph_gate_early_inlining (void) return flag_early_inlining; } -struct gimple_opt_pass pass_early_inline = +struct gimple_opt_pass pass_early_inline = { { GIMPLE_PASS, @@ -1669,7 +1669,7 @@ cgraph_gate_ipa_early_inlining (void) /* IPA pass wrapper for early inlining pass. We need to run early inlining before tree profiling so we have stand alone IPA pass for doing so. */ -struct simple_ipa_opt_pass pass_ipa_early_inline = +struct simple_ipa_opt_pass pass_ipa_early_inline = { { SIMPLE_IPA_PASS, @@ -1723,7 +1723,7 @@ likely_eliminated_by_inlining_p (gimple stmt) while (handled_component_p (inner_rhs) || TREE_CODE (inner_rhs) == ADDR_EXPR || TREE_CODE (inner_rhs) == INDIRECT_REF) inner_rhs = TREE_OPERAND (inner_rhs, 0); - + if (TREE_CODE (inner_rhs) == PARM_DECL || (TREE_CODE (inner_rhs) == SSA_NAME @@ -1875,7 +1875,7 @@ compute_inline_parameters_for_current (void) return 0; } -struct gimple_opt_pass pass_inline_parameters = +struct gimple_opt_pass pass_inline_parameters = { { GIMPLE_PASS, @@ -1963,7 +1963,7 @@ inline_generate_summary (void) for (node = cgraph_nodes; node; node = node->next) if (node->analyzed) analyze_function (node); - + return; } @@ -2003,7 +2003,7 @@ inline_transform (struct cgraph_node *node) and inliner, so when ipa-cp is active, we don't need to write them twice. */ -static void +static void inline_read_summary (void) { if (flag_indirect_inlining) @@ -2020,7 +2020,7 @@ inline_read_summary (void) Jump functions are shared among ipa-cp and inliner, so when ipa-cp is active, we don't need to write them twice. */ -static void +static void inline_write_summary (cgraph_node_set set) { if (flag_indirect_inlining && !flag_ipa_cp) -- cgit v1.2.1 From 61c2c7b1e5623d1add0d7281d218f0073dab1943 Mon Sep 17 00:00:00 2001 From: jakub Date: Thu, 10 Dec 2009 21:58:49 +0000 Subject: PR c++/42317 * cgraph.h (struct cgraph_node): Add same_comdat_group field. * cgraph.c (cgraph_remove_node): Unchain node from same_comdat_group circular list. (cgraph_node_can_be_local_p): Return false for DECL_COMDAT with node->same_comdat_group. * ipa.c (cgraph_remove_unreachable_nodes): For any reachable node mark all its same_comdat_group nodes as also reachable. (cgraph_externally_visible_p): Return true even if any of same_comdat_group nodes has address taken. * lto-cgraph.c (lto_output_node): Stream out same_comdat_group. (output_cgraph): Ensure other same_comdat_group nodes are also included. (input_node): Stream in same_comdat_group. (input_cgraph_1): Fix up same_comdat_group fields from references to pointers. * cgraphunit.c (cgraph_analyze_functions): Mark all other same_comdat_group nodes as reachable. (cgraph_mark_functions_to_output): For each node->process process also other same_comdat_group nodes. * ipa-inline.c (cgraph_clone_inlined_nodes): Don't reuse nodes with same_comdat_group non-NULL. (cgraph_mark_inline_edge): Likewise. * decl2.c (cp_write_global_declarations): Clear DECL_EXTERNAL also on all other functions in the same comdat group. * optimize.c (maybe_clone_body): Also optimize virtual implicit dtors. For virtual comdat dtors tell cgraph that base and deleting dtor are in the same comdat group. * config/abi/pre/gnu.ver: Don't export certain base dtors that weren't previously exported. * g++.dg/opt/dtor2.C: New test. * g++.dg/opt/dtor2.h: New file. * g++.dg/opt/dtor2-aux.cc: New file. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@155143 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 120c234f89b..b146d0b13e2 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -247,6 +247,10 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, In that case just go ahead and re-use it. */ if (!e->callee->callers->next_caller && cgraph_can_remove_if_no_direct_calls_p (e->callee) + /* Don't reuse if more than one function shares a comdat group. + If the other function(s) are needed, we need to emit even + this function out of line. */ + && !e->callee->same_comdat_group && !cgraph_new_nodes) { gcc_assert (!e->callee->global.inlined_to); @@ -311,7 +315,8 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, e->callee->global.inlined = true; if (e->callee->callers->next_caller - || !cgraph_can_remove_if_no_direct_calls_p (e->callee)) + || !cgraph_can_remove_if_no_direct_calls_p (e->callee) + || e->callee->same_comdat_group) duplicate = true; cgraph_clone_inlined_nodes (e, true, update_original); -- cgit v1.2.1 From 526a5cd92e7b088b069edc96f60eb9a8ba27b53c Mon Sep 17 00:00:00 2001 From: jamborm Date: Tue, 5 Jan 2010 19:42:32 +0000 Subject: 2010-01-05 Martin Jambor PR tree-optimization/42462 * ipa-inline.c (compute_inline_parameters): Pass node->decl instead of current_function_decl to helper functions and macros. * gcc/testsuite/g++.dg/torture/pr42462.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@155658 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index b146d0b13e2..7dbafb8f7c2 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1859,10 +1859,10 @@ compute_inline_parameters (struct cgraph_node *node) node->global.stack_frame_offset = 0; /* Can this function be inlined at all? */ - node->local.inlinable = tree_inlinable_function_p (current_function_decl); + node->local.inlinable = tree_inlinable_function_p (node->decl); if (node->local.inlinable && !node->local.disregard_inline_limits) node->local.disregard_inline_limits - = DECL_DISREGARD_INLINE_LIMITS (current_function_decl); + = DECL_DISREGARD_INLINE_LIMITS (node->decl); estimate_function_body_sizes (node); /* Inlining characteristics are maintained by the cgraph_mark_inline. */ node->global.time = inline_summary (node)->self_time; -- cgit v1.2.1 From 9bc627ae014fb4ffb8f20ad3b9be96f996500ae9 Mon Sep 17 00:00:00 2001 From: rguenth Date: Wed, 6 Jan 2010 17:52:09 +0000 Subject: 2010-01-06 Richard Guenther * ipa-inline.c (cgraph_decide_inlining_incrementally): Do not inline regular functions into always-inline functions. * gcc.c-torture/compile/pr42632.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@155679 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 7dbafb8f7c2..c6c84f99572 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1506,7 +1506,10 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, } /* Now do the automatic inlining. */ - if (mode != INLINE_ALL && mode != INLINE_ALWAYS_INLINE) + if (mode != INLINE_ALL && mode != INLINE_ALWAYS_INLINE + /* Never inline regular functions into always-inline functions + during incremental inlining. */ + && !node->local.disregard_inline_limits) for (e = node->callees; e; e = e->next_callee) { int allowed_growth = 0; -- cgit v1.2.1 From 00efe249ebef940120e0cf4573e7489cb9ffddb8 Mon Sep 17 00:00:00 2001 From: rguenth Date: Fri, 29 Jan 2010 11:26:27 +0000 Subject: 2010-01-29 Richard Guenther PR middle-end/37448 * ipa-inline.c (cgraph_decide_inlining_incrementally): Avoid quadratic behavior in most cases. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156343 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 185 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 97 insertions(+), 88 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index c6c84f99572..916c2a7afec 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1510,97 +1510,106 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, /* Never inline regular functions into always-inline functions during incremental inlining. */ && !node->local.disregard_inline_limits) - for (e = node->callees; e; e = e->next_callee) - { - int allowed_growth = 0; - if (!e->callee->local.inlinable - || !e->inline_failed - || e->callee->local.disregard_inline_limits) - continue; - if (dump_file) - fprintf (dump_file, "Considering inline candidate %s.\n", - cgraph_node_name (e->callee)); - if (cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)) - { - if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, "Not inlining: recursive call.\n"); - } + { + bitmap visited = BITMAP_ALLOC (NULL); + for (e = node->callees; e; e = e->next_callee) + { + int allowed_growth = 0; + if (!e->callee->local.inlinable + || !e->inline_failed + || e->callee->local.disregard_inline_limits) continue; - } - if (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl)) - != gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->callee->decl))) - { - if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, "Not inlining: SSA form does not match.\n"); - } + /* We are inlining a function to all call-sites in node + or to none. So visit each candidate only once. */ + if (!bitmap_set_bit (visited, e->callee->uid)) continue; - } - - if (cgraph_maybe_hot_edge_p (e) && leaf_node_p (e->callee) - && optimize_function_for_speed_p (cfun)) - allowed_growth = PARAM_VALUE (PARAM_EARLY_INLINING_INSNS); + if (dump_file) + fprintf (dump_file, "Considering inline candidate %s.\n", + cgraph_node_name (e->callee)); + if (cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)) + { + if (dump_file) + { + indent_to (dump_file, depth); + fprintf (dump_file, "Not inlining: recursive call.\n"); + } + continue; + } + if (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl)) + != gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->callee->decl))) + { + if (dump_file) + { + indent_to (dump_file, depth); + fprintf (dump_file, + "Not inlining: SSA form does not match.\n"); + } + continue; + } - /* When the function body would grow and inlining the function won't - eliminate the need for offline copy of the function, don't inline. - */ - if (((mode == INLINE_SIZE || mode == INLINE_SIZE_NORECURSIVE) - || (!flag_inline_functions - && !DECL_DECLARED_INLINE_P (e->callee->decl))) - && (cgraph_estimate_size_after_inlining (1, e->caller, e->callee) - > e->caller->global.size + allowed_growth) - && cgraph_estimate_growth (e->callee) > allowed_growth) - { - if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, - "Not inlining: code size would grow by %i.\n", - cgraph_estimate_size_after_inlining (1, e->caller, - e->callee) - - e->caller->global.size); - } - continue; - } - if (!cgraph_check_inline_limits (node, e->callee, &e->inline_failed, - false) - || e->call_stmt_cannot_inline_p) - { - if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, "Not inlining: %s.\n", - cgraph_inline_failed_string (e->inline_failed)); - } - continue; - } - if (!e->callee->analyzed) - { - if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, - "Not inlining: Function body no longer available.\n"); - } - continue; - } - if (!tree_can_inline_p (e)) - { - if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, - "Not inlining: %s.", - cgraph_inline_failed_string (e->inline_failed)); - } - continue; - } - if (cgraph_default_inline_p (e->callee, &failed_reason)) - inlined |= try_inline (e, mode, depth); - } + if (cgraph_maybe_hot_edge_p (e) && leaf_node_p (e->callee) + && optimize_function_for_speed_p (cfun)) + allowed_growth = PARAM_VALUE (PARAM_EARLY_INLINING_INSNS); + + /* When the function body would grow and inlining the function + won't eliminate the need for offline copy of the function, + don't inline. */ + if (((mode == INLINE_SIZE || mode == INLINE_SIZE_NORECURSIVE) + || (!flag_inline_functions + && !DECL_DECLARED_INLINE_P (e->callee->decl))) + && (cgraph_estimate_size_after_inlining (1, e->caller, e->callee) + > e->caller->global.size + allowed_growth) + && cgraph_estimate_growth (e->callee) > allowed_growth) + { + if (dump_file) + { + indent_to (dump_file, depth); + fprintf (dump_file, + "Not inlining: code size would grow by %i.\n", + cgraph_estimate_size_after_inlining (1, e->caller, + e->callee) + - e->caller->global.size); + } + continue; + } + if (!cgraph_check_inline_limits (node, e->callee, &e->inline_failed, + false) + || e->call_stmt_cannot_inline_p) + { + if (dump_file) + { + indent_to (dump_file, depth); + fprintf (dump_file, "Not inlining: %s.\n", + cgraph_inline_failed_string (e->inline_failed)); + } + continue; + } + if (!e->callee->analyzed) + { + if (dump_file) + { + indent_to (dump_file, depth); + fprintf (dump_file, + "Not inlining: Function body no longer available.\n"); + } + continue; + } + if (!tree_can_inline_p (e)) + { + if (dump_file) + { + indent_to (dump_file, depth); + fprintf (dump_file, + "Not inlining: %s.", + cgraph_inline_failed_string (e->inline_failed)); + } + continue; + } + if (cgraph_default_inline_p (e->callee, &failed_reason)) + inlined |= try_inline (e, mode, depth); + } + BITMAP_FREE (visited); + } node->aux = (void *)(size_t) old_mode; return inlined; } -- cgit v1.2.1 From 7cf0dbf3e5eee1286c76c26a836622c9c9974736 Mon Sep 17 00:00:00 2001 From: steven Date: Fri, 2 Apr 2010 19:54:46 +0000 Subject: * ada/gcc-interface/Make-lang.in, alias.c, attribs.c, auto-inc-dec.c, basic-block.h, bb-reorder.c, calls.c, c-common.c, cgraph.h, collect2.h, config/alpha/alpha.c, config/alpha/alpha.md, config/alpha/predicates.md, config/arm/arm.md, config/arm/lib1funcs.asm, config/arm/neon-schedgen.ml, config/avr/avr.c, config/avr/avr.md, config/bfin/bfin.c, config/darwin9.h, config/darwin.c, config/darwin.h, config/h8300/h8300.c, config/i386/cpuid.h, config/i386/cygming.h, config/i386/cygwin.h, config/i386/mingw32.h, config/i386/msformat-c.c, config/i386/sol2-10.h, config/i386/xopintrin.h, config/ia64/ia64.c, config/ia64/ia64.md, config/ia64/sync.md, config/mep/mep.c, config/mips/mips.md, config/mn10300/mn10300.c, config/mn10300/mn10300.h, config/pa/pa.c, config/pa/pa.md, config/rs6000/aix.h, config/rs6000/dfp.md, config/rs6000/rs6000-builtin.def, config/rs6000/rs6000-c.c, config/rs6000/vector.md, config/rtems.h, config/rx/rx.md, config/s390/s390.md, config/sol2-c.c, config/sparc/sol2-bi.h, config/sparc/sol2-gas.h, config/sparc/sparc.h, config/sparc/sparc.md, config/sparc/sparc-protos.h, config/spu/spu.c, config/spu/spu-c.c, config/t-darwin, convert.c, c.opt, c-opts.c, cp/Make-lang.in, c-pretty-print.c, c-typeck.c, df-core.c, df-scan.c, diagnostic.c, diagnostic.h, doc/cppopts.texi, doc/cpp.texi, doc/extend.texi, doc/gimple.texi, doc/languages.texi, doc/plugins.texi, doc/rtl.texi, doc/standards.texi, doc/tree-ssa.texi, doc/trouble.texi, dominance.c, fold-const.c, fortran/Make-lang.in, fwprop.c, gcc-plugin.h, gensupport.c, gimple.h, gimple-iterator.c, graphite.c, graphite-clast-to-gimple.c, graphite-clast-to-gimple.h, graphite-dependences.c, graphite-poly.c, graphite-poly.h, graphite-ppl.c, graphite-ppl.h, graphite-scop-detection.c, graphite-sese-to-poly.c, graphite-sese-to-poly.h, ifcvt.c, intl.c, intl.h, ipa.c, ipa-cp.c, ipa-inline.c, ipa-prop.c, ipa-prop.h, ipa-pure-const.c, ipa-reference.c, ipa-type-escape.c, ira-color.c, ira-conflicts.c, ira-lives.c, java/Make-lang.in, lambda-code.c, loop-invariant.c, lto/Make-lang.in, lto-streamer.h, lto-streamer-in.c, objc/Make-lang.in, objcp/Make-lang.in, omp-low.c, optc-gen.awk, opt-functions.awk, opth-gen.awk, params.def, passes.c, postreload-gcse.c, print-tree.c, recog.c, regrename.c, reload.h, rtl.def, sched-int.h, sched-rgn.c, sel-sched-dump.c, sese.c, sese.h, store-motion.c, stor-layout.c, tree-cfgcleanup.c, tree-chrec.c, tree-complex.c, tree-data-ref.c, tree.def, tree-eh.c, tree-flow.h, tree-flow-inline.h, tree.h, tree-loop-distribution.c, tree-outof-ssa.c, tree-parloops.c, tree-pass.h, tree-predcom.c, tree-profile.c, tree-scalar-evolution.c, tree-ssa-address.c, tree-ssa-alias.c, tree-ssa-coalesce.c, tree-ssa-copy.c, tree-ssa-dce.c, tree-ssa-dom.c, tree-ssa-dse.c, tree-ssa-loop-im.c, tree-ssa-loop-ivcanon.c, tree-ssa-loop-manip.c, tree-ssa-math-opts.c, tree-ssa-operands.c, tree-ssa-pre.c, tree-ssa-sccvn.c, tree-ssa-structalias.c, tree-ssa-uncprop.c, tree-tailcall.c, tree-vect-data-refs.c, tree-vect-loop.c, tree-vectorizer.h, tree-vect-slp.c, tree-vrp.c, unwind-dw2-fde-darwin.c, varpool.c: Update copyright years. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@157950 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 916c2a7afec..984250cb6c9 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1,5 +1,6 @@ /* Inlining decision heuristics. - Copyright (C) 2003, 2004, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. Contributed by Jan Hubicka This file is part of GCC. -- cgit v1.2.1 From d160af417cc4bcaec9f15e6a21e566cfe106f7c8 Mon Sep 17 00:00:00 2001 From: rguenth Date: Mon, 12 Apr 2010 13:37:32 +0000 Subject: 2010-04-12 Richard Guenther * ipa.c (cgraph_postorder): Adjust postorder to guarantee single-iteration always-inline inlining. * ipa-inline.c (cgraph_mark_inline): Do not return anything. (cgraph_decide_inlining): Do not handle always-inline specially. (try_inline): Remove always-inline cycle detection special case. Do not recurse on always-inlines. (cgraph_early_inlining): Do not iterate if not optimizing. (cgraph_gate_early_inlining): remove. (pass_early_inline): Run unconditionally. (gate_cgraph_decide_inlining): New function. (pass_ipa_inline): Use it. Do not run the IPA inliner if not inlining or optimizing. (cgraph_decide_inlining_of_small_functions): Also consider always-inline functions. (cgraph_default_inline_p): Return true for nodes which should disregard inline limits. (estimate_function_body_sizes): Assume zero size and time for nodes which are marked as disregarding inline limits. (cgraph_decide_recursive_inlining): Do not perform recursive inlining on always-inline nodes. * gcc.dg/torture/inline-2.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158225 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 450 +++++++++++++++++++++++++------------------------------ 1 file changed, 208 insertions(+), 242 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 984250cb6c9..e9ba04b371c 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -160,9 +160,10 @@ enum inlining_mode { INLINE_SIZE, INLINE_ALL }; + static bool -cgraph_decide_inlining_incrementally (struct cgraph_node *, enum inlining_mode, - int); +cgraph_decide_inlining_incrementally (struct cgraph_node *, enum inlining_mode); +static void cgraph_flatten (struct cgraph_node *node); /* Statistics we collect about inlining algorithm. */ @@ -346,11 +347,9 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, return false; } -/* Mark all calls of EDGE->CALLEE inlined into EDGE->CALLER. - Return following unredirected edge in the list of callers - of EDGE->CALLEE */ +/* Mark all calls of EDGE->CALLEE inlined into EDGE->CALLER. */ -static struct cgraph_edge * +static void cgraph_mark_inline (struct cgraph_edge *edge) { struct cgraph_node *to = edge->caller; @@ -370,8 +369,6 @@ cgraph_mark_inline (struct cgraph_edge *edge) edge = next; } } - - return edge; } /* Estimate the growth caused by inlining NODE into all callees. */ @@ -479,6 +476,9 @@ cgraph_default_inline_p (struct cgraph_node *n, cgraph_inline_failed_t *reason) { tree decl = n->decl; + if (n->local.disregard_inline_limits) + return true; + if (!flag_inline_small_functions && !DECL_DECLARED_INLINE_P (decl)) { if (reason) @@ -727,6 +727,12 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node, int depth = 0; int n = 0; + /* 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 + && lookup_attribute ("always_inline", DECL_ATTRIBUTES (node->decl))) + return false; + if (optimize_function_for_size_p (DECL_STRUCT_FUNCTION (node->decl)) || (!flag_inline_functions && !DECL_DECLARED_INLINE_P (node->decl))) return false; @@ -916,8 +922,7 @@ cgraph_decide_inlining_of_small_functions (void) for (node = cgraph_nodes; node; node = node->next) { - if (!node->local.inlinable || !node->callers - || node->local.disregard_inline_limits) + if (!node->local.inlinable || !node->callers) continue; if (dump_file) fprintf (dump_file, "Considering inline candidate %s.\n", cgraph_node_name (node)); @@ -1128,6 +1133,86 @@ cgraph_decide_inlining_of_small_functions (void) BITMAP_FREE (updated_nodes); } +/* Flatten NODE from the IPA inliner. */ + +static void +cgraph_flatten (struct cgraph_node *node) +{ + struct cgraph_edge *e; + + /* We shouldn't be called recursively when we are being processed. */ + gcc_assert (node->aux == NULL); + + node->aux = (void *)(size_t) INLINE_ALL; + + for (e = node->callees; e; e = e->next_callee) + { + struct cgraph_node *orig_callee; + + if (e->call_stmt_cannot_inline_p) + continue; + + if (!e->callee->analyzed) + { + if (dump_file) + fprintf (dump_file, + "Not inlining: Function body not available.\n"); + continue; + } + + /* We've hit cycle? It is time to give up. */ + if (e->callee->aux) + { + if (dump_file) + fprintf (dump_file, + "Not inlining %s into %s to avoid cycle.\n", + cgraph_node_name (e->callee), + cgraph_node_name (e->caller)); + e->inline_failed = CIF_RECURSIVE_INLINING; + continue; + } + + /* When the edge is already inlined, we just need to recurse into + it in order to fully flatten the leaves. */ + if (!e->inline_failed) + { + cgraph_flatten (e->callee); + continue; + } + + if (cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)) + { + if (dump_file) + fprintf (dump_file, "Not inlining: recursive call.\n"); + continue; + } + + if (!tree_can_inline_p (e)) + { + if (dump_file) + fprintf (dump_file, "Not inlining: %s", + cgraph_inline_failed_string (e->inline_failed)); + continue; + } + + /* Inline the edge and flatten the inline clone. Avoid + recursing through the original node if the node was cloned. */ + if (dump_file) + fprintf (dump_file, " Inlining %s into %s.\n", + cgraph_node_name (e->callee), + cgraph_node_name (e->caller)); + orig_callee = e->callee; + cgraph_mark_inline_edge (e, true, NULL); + if (e->callee != orig_callee) + orig_callee->aux = (void *)(size_t) INLINE_ALL; + cgraph_flatten (e->callee); + if (e->callee != orig_callee) + orig_callee->aux = NULL; + } + + node->aux = NULL; +} + /* Decide on the inlining. We do so in the topological order to avoid expenses on updating data structures. */ @@ -1140,7 +1225,6 @@ cgraph_decide_inlining (void) XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); int old_size = 0; int i; - bool redo_always_inline = true; int initial_size = 0; cgraph_remove_function_insertion_hook (function_insertion_hook_holder); @@ -1178,65 +1262,29 @@ cgraph_decide_inlining (void) node->aux = 0; if (dump_file) - fprintf (dump_file, "\nInlining always_inline functions:\n"); + fprintf (dump_file, "\nFlattening functions:\n"); - /* In the first pass mark all always_inline edges. Do this with a priority - so none of our later choices will make this impossible. */ - while (redo_always_inline) + /* In the first pass handle functions to be flattened. Do this with + a priority so none of our later choices will make this impossible. */ + for (i = nnodes - 1; i >= 0; i--) { - redo_always_inline = false; - for (i = nnodes - 1; i >= 0; i--) + node = order[i]; + + /* Handle nodes to be flattened, but don't update overall unit + size. Calling the incremental inliner here is lame, + a simple worklist should be enough. What should be left + here from the early inliner (if it runs) is cyclic cases. + Ideally when processing callees we stop inlining at the + entry of cycles, possibly cloning that entry point and + try to flatten itself turning it into a self-recursive + function. */ + if (lookup_attribute ("flatten", + DECL_ATTRIBUTES (node->decl)) != NULL) { - struct cgraph_edge *e, *next; - - node = order[i]; - - /* Handle nodes to be flattened, but don't update overall unit - size. */ - if (lookup_attribute ("flatten", - DECL_ATTRIBUTES (node->decl)) != NULL) - { - if (dump_file) - fprintf (dump_file, - "Flattening %s\n", cgraph_node_name (node)); - cgraph_decide_inlining_incrementally (node, INLINE_ALL, 0); - } - - if (!node->local.disregard_inline_limits) - continue; - if (dump_file) - fprintf (dump_file, - "\nConsidering %s size:%i (always inline)\n", - cgraph_node_name (node), node->global.size); - old_size = overall_size; - for (e = node->callers; e; e = next) - { - next = e->next_caller; - if (!e->inline_failed || e->call_stmt_cannot_inline_p) - continue; - if (cgraph_recursive_inlining_p (e->caller, e->callee, - &e->inline_failed)) - continue; - if (!tree_can_inline_p (e)) - continue; - if (cgraph_mark_inline_edge (e, true, NULL)) - redo_always_inline = true; - if (dump_file) - fprintf (dump_file, - " Inlined into %s which now has size %i.\n", - cgraph_node_name (e->caller), - e->caller->global.size); - } - /* Inlining self recursive function might introduce new calls to - themselves we didn't see in the loop above. Fill in the proper - reason why inline failed. */ - for (e = node->callers; e; e = e->next_caller) - if (e->inline_failed) - e->inline_failed = CIF_RECURSIVE_INLINING; if (dump_file) fprintf (dump_file, - " Inlined for a net change of %+i size.\n", - overall_size - old_size); + "Flattening %s\n", cgraph_node_name (node)); + cgraph_flatten (node); } } @@ -1313,86 +1361,6 @@ cgraph_decide_inlining (void) return 0; } -/* Try to inline edge E from incremental inliner. MODE specifies mode - of inliner. - - We are detecting cycles by storing mode of inliner into cgraph_node last - time we visited it in the recursion. In general when mode is set, we have - recursive inlining, but as an special case, we want to try harder inline - ALWAYS_INLINE functions: consider callgraph a->b->c->b, with a being - flatten, b being always inline. Flattening 'a' will collapse - a->b->c before hitting cycle. To accommodate always inline, we however - need to inline a->b->c->b. - - So after hitting cycle first time, we switch into ALWAYS_INLINE mode and - stop inlining only after hitting ALWAYS_INLINE in ALWAY_INLINE mode. */ -static bool -try_inline (struct cgraph_edge *e, enum inlining_mode mode, int depth) -{ - struct cgraph_node *callee = e->callee; - enum inlining_mode callee_mode = (enum inlining_mode) (size_t) callee->aux; - bool always_inline = e->callee->local.disregard_inline_limits; - bool inlined = false; - - /* We've hit cycle? */ - if (callee_mode) - { - /* It is first time we see it and we are not in ALWAY_INLINE only - mode yet. and the function in question is always_inline. */ - if (always_inline && mode != INLINE_ALWAYS_INLINE) - { - if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, - "Hit cycle in %s, switching to always inline only.\n", - cgraph_node_name (callee)); - } - mode = INLINE_ALWAYS_INLINE; - } - /* Otherwise it is time to give up. */ - else - { - if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, - "Not inlining %s into %s to avoid cycle.\n", - cgraph_node_name (callee), - cgraph_node_name (e->caller)); - } - e->inline_failed = (e->callee->local.disregard_inline_limits - ? CIF_RECURSIVE_INLINING : CIF_UNSPECIFIED); - return false; - } - } - - callee->aux = (void *)(size_t) mode; - if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, " Inlining %s into %s.\n", - cgraph_node_name (e->callee), - cgraph_node_name (e->caller)); - } - if (e->inline_failed) - { - cgraph_mark_inline (e); - - /* In order to fully inline always_inline functions, we need to - recurse here, since the inlined functions might not be processed by - incremental inlining at all yet. - - Also flattening needs to be done recursively. */ - - if (mode == INLINE_ALL || always_inline) - cgraph_decide_inlining_incrementally (e->callee, mode, depth + 1); - inlined = true; - } - callee->aux = (void *)(size_t) callee_mode; - return inlined; -} - /* Return true when N is leaf function. Accept cheap (pure&const) builtins in leaf functions. */ static bool @@ -1408,38 +1376,29 @@ leaf_node_p (struct cgraph_node *n) } /* Decide on the inlining. We do so in the topological order to avoid - expenses on updating data structures. - DEPTH is depth of recursion, used only for debug output. */ + expenses on updating data structures. */ static bool cgraph_decide_inlining_incrementally (struct cgraph_node *node, - enum inlining_mode mode, - int depth) + enum inlining_mode mode) { struct cgraph_edge *e; bool inlined = false; cgraph_inline_failed_t failed_reason; - enum inlining_mode old_mode; #ifdef ENABLE_CHECKING verify_cgraph_node (node); #endif - old_mode = (enum inlining_mode) (size_t)node->aux; - if (mode != INLINE_ALWAYS_INLINE && mode != INLINE_SIZE_NORECURSIVE && lookup_attribute ("flatten", DECL_ATTRIBUTES (node->decl)) != NULL) { if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, "Flattening %s\n", cgraph_node_name (node)); - } + fprintf (dump_file, "Incrementally flattening %s\n", + cgraph_node_name (node)); mode = INLINE_ALL; } - node->aux = (void *)(size_t) mode; - /* First of all look for always inline functions. */ if (mode != INLINE_SIZE_NORECURSIVE) for (e = node->callees; e; e = e->next_callee) @@ -1449,61 +1408,45 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, continue; if (e->call_stmt_cannot_inline_p) continue; - /* When the edge is already inlined, we just need to recurse into - it in order to fully flatten the leaves. */ - if (!e->inline_failed && mode == INLINE_ALL) - { - inlined |= try_inline (e, mode, depth); - continue; - } if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, - "Considering to always inline inline candidate %s.\n", - cgraph_node_name (e->callee)); - } + fprintf (dump_file, + "Considering to always inline inline candidate %s.\n", + cgraph_node_name (e->callee)); if (cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)) { if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, "Not inlining: recursive call.\n"); - } + fprintf (dump_file, "Not inlining: recursive call.\n"); continue; } if (!tree_can_inline_p (e)) { if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, - "Not inlining: %s", - cgraph_inline_failed_string (e->inline_failed)); - } + fprintf (dump_file, + "Not inlining: %s", + cgraph_inline_failed_string (e->inline_failed)); continue; } if (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl)) != gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->callee->decl))) { if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, "Not inlining: SSA form does not match.\n"); - } + fprintf (dump_file, "Not inlining: SSA form does not match.\n"); continue; } if (!e->callee->analyzed) { if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, - "Not inlining: Function body no longer available.\n"); - } + fprintf (dump_file, + "Not inlining: Function body no longer available.\n"); continue; } - inlined |= try_inline (e, mode, depth); + + if (dump_file) + fprintf (dump_file, " Inlining %s into %s.\n", + cgraph_node_name (e->callee), + cgraph_node_name (e->caller)); + cgraph_mark_inline (e); + inlined = true; } /* Now do the automatic inlining. */ @@ -1530,21 +1473,15 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, if (cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)) { if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, "Not inlining: recursive call.\n"); - } + fprintf (dump_file, "Not inlining: recursive call.\n"); continue; } if (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl)) != gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->callee->decl))) { if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, - "Not inlining: SSA form does not match.\n"); - } + fprintf (dump_file, + "Not inlining: SSA form does not match.\n"); continue; } @@ -1563,14 +1500,11 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, && cgraph_estimate_growth (e->callee) > allowed_growth) { if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, - "Not inlining: code size would grow by %i.\n", - cgraph_estimate_size_after_inlining (1, e->caller, - e->callee) - - e->caller->global.size); - } + fprintf (dump_file, + "Not inlining: code size would grow by %i.\n", + cgraph_estimate_size_after_inlining (1, e->caller, + e->callee) + - e->caller->global.size); continue; } if (!cgraph_check_inline_limits (node, e->callee, &e->inline_failed, @@ -1578,40 +1512,37 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, || e->call_stmt_cannot_inline_p) { if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, "Not inlining: %s.\n", - cgraph_inline_failed_string (e->inline_failed)); - } + fprintf (dump_file, "Not inlining: %s.\n", + cgraph_inline_failed_string (e->inline_failed)); continue; } if (!e->callee->analyzed) { if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, - "Not inlining: Function body no longer available.\n"); - } + fprintf (dump_file, + "Not inlining: Function body no longer available.\n"); continue; } if (!tree_can_inline_p (e)) { if (dump_file) - { - indent_to (dump_file, depth); - fprintf (dump_file, - "Not inlining: %s.", - cgraph_inline_failed_string (e->inline_failed)); - } + fprintf (dump_file, + "Not inlining: %s.", + cgraph_inline_failed_string (e->inline_failed)); continue; } if (cgraph_default_inline_p (e->callee, &failed_reason)) - inlined |= try_inline (e, mode, depth); + { + if (dump_file) + fprintf (dump_file, " Inlining %s into %s.\n", + cgraph_node_name (e->callee), + cgraph_node_name (e->caller)); + cgraph_mark_inline (e); + inlined = true; + } } BITMAP_FREE (visited); } - node->aux = (void *)(size_t) old_mode; return inlined; } @@ -1633,27 +1564,40 @@ cgraph_early_inlining (void) if (sorrycount || errorcount) return 0; - while (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) - && cgraph_decide_inlining_incrementally (node, - iterations - ? INLINE_SIZE_NORECURSIVE : INLINE_SIZE, 0)) + + if (!optimize + || flag_no_inline + || !flag_early_inlining) { + /* When not optimizing or not inlining inline only always-inline + functions. */ + cgraph_decide_inlining_incrementally (node, INLINE_ALWAYS_INLINE); timevar_push (TV_INTEGRATION); todo |= optimize_inline_calls (current_function_decl); - iterations++; timevar_pop (TV_INTEGRATION); } - if (dump_file) - fprintf (dump_file, "Iterations: %i\n", iterations); + else + { + /* We iterate incremental inlining to get trivial cases of indirect + inlining. */ + while (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) + && cgraph_decide_inlining_incrementally (node, + iterations + ? INLINE_SIZE_NORECURSIVE + : INLINE_SIZE)) + { + timevar_push (TV_INTEGRATION); + todo |= optimize_inline_calls (current_function_decl); + iterations++; + timevar_pop (TV_INTEGRATION); + } + if (dump_file) + fprintf (dump_file, "Iterations: %i\n", iterations); + } + cfun->always_inline_functions_inlined = true; - return todo; -} -/* When inlining shall be performed. */ -static bool -cgraph_gate_early_inlining (void) -{ - return flag_early_inlining; + return todo; } struct gimple_opt_pass pass_early_inline = @@ -1661,7 +1605,7 @@ struct gimple_opt_pass pass_early_inline = { GIMPLE_PASS, "einline", /* name */ - cgraph_gate_early_inlining, /* gate */ + NULL, /* gate */ cgraph_early_inlining, /* execute */ NULL, /* sub */ NULL, /* next */ @@ -1786,6 +1730,14 @@ estimate_function_body_sizes (struct cgraph_node *node) int freq; tree funtype = TREE_TYPE (node->decl); + if (node->local.disregard_inline_limits) + { + inline_summary (node)->self_time = 0; + inline_summary (node)->self_size = 0; + inline_summary (node)->time_inlining_benefit = 0; + inline_summary (node)->size_inlining_benefit = 0; + } + if (dump_file) fprintf (dump_file, "Analyzing function body size: %s\n", cgraph_node_name (node)); @@ -2045,12 +1997,26 @@ inline_write_summary (cgraph_node_set set) ipa_prop_write_jump_functions (set); } +/* When to run IPA inlining. Inlining of always-inline functions + happens during early inlining. */ + +static bool +gate_cgraph_decide_inlining (void) +{ + /* ??? We'd like to skip this if not optimizing or not inlining as + all always-inline functions have been processed by early + inlining already. But this at least breaks EH with C++ as + we need to unconditionally run fixup_cfg even at -O0. + So leave it on unconditionally for now. */ + return 1; +} + struct ipa_opt_pass_d pass_ipa_inline = { { IPA_PASS, "inline", /* name */ - NULL, /* gate */ + gate_cgraph_decide_inlining, /* gate */ cgraph_decide_inlining, /* execute */ NULL, /* sub */ NULL, /* next */ -- cgit v1.2.1 From 022b3380cc939bd06e310f17578c670e5365050c Mon Sep 17 00:00:00 2001 From: hubicka Date: Tue, 13 Apr 2010 18:22:35 +0000 Subject: * ipa-inline.c (cgraph_mark_inline_edge): Avoid double accounting of optimized out static functions. (cgraph_edge_badness): Add DUMP parameter and dump reasons for the cost computation. Also sanity check for overflows. (update_caller_keys): Update cgraph_edge_badness call; properly update fibheap and sanity check that it is up to date. (add_new_edges_to_heap): Update cgraph_edge_badness. (cgraph_decide_inlining_of_small_function): Likewise; add sanity checking that badness in heap is up to date; improve dumping of reason; Update badness of calls to the offline copy of function currently inlined; dump badness of functions not inlined because of unit growth limits. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158278 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 161 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 125 insertions(+), 36 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index e9ba04b371c..601695a3fda 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -306,8 +306,6 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, struct cgraph_node *to = NULL, *what; struct cgraph_edge *curr = e; int freq; - bool duplicate = false; - int orig_size = e->callee->global.size; gcc_assert (e->inline_failed); e->inline_failed = CIF_OK; @@ -316,10 +314,6 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, DECL_POSSIBLY_INLINED (e->callee->decl) = true; e->callee->global.inlined = true; - if (e->callee->callers->next_caller - || !cgraph_can_remove_if_no_direct_calls_p (e->callee) - || e->callee->same_comdat_group) - duplicate = true; cgraph_clone_inlined_nodes (e, true, update_original); what = e->callee; @@ -337,8 +331,6 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, gcc_assert (what->global.inlined_to == to); if (new_size > old_size) overall_size += new_size - old_size; - if (!duplicate) - overall_size -= orig_size; ncalls_inlined++; if (flag_indirect_inlining) @@ -544,23 +536,54 @@ cgraph_recursive_inlining_p (struct cgraph_node *to, of the function or function body size. */ static int -cgraph_edge_badness (struct cgraph_edge *edge) +cgraph_edge_badness (struct cgraph_edge *edge, bool dump) { gcov_type badness; int growth = - cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee); + (cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee) + - edge->caller->global.size); - growth -= edge->caller->global.size; + if (dump) + { + fprintf (dump_file, " Badness calculcation for %s -> %s\n", + cgraph_node_name (edge->caller), + 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, + edge->callee->global.size, + inline_summary (edge->callee)->size_inlining_benefit); + } /* Always prefer inlining saving code size. */ if (growth <= 0) - badness = INT_MIN - growth; + { + badness = INT_MIN - growth; + if (dump) + fprintf (dump_file, " %i: Growth %i < 0\n", (int) badness, + growth); + } /* When profiling is available, base priorities -(#calls / growth). So we optimize for overall number of "executed" inlined calls. */ else if (max_count) - badness = ((int)((double)edge->count * INT_MIN / max_count / (max_benefit + 1)) - * (inline_summary (edge->callee)->time_inlining_benefit + 1)) / growth; + { + badness = + ((int) + ((double) edge->count * INT_MIN / max_count / (max_benefit + 1)) * + (inline_summary (edge->callee)->time_inlining_benefit + 1)) / growth; + if (dump) + { + fprintf (dump_file, + " %i (relative %f): profile info. Relative count %f" + " * Relative benefit %f\n", + (int) badness, (double) badness / INT_MIN, + (double) edge->count / max_count, + (double) (inline_summary (edge->callee)-> + time_inlining_benefit + 1) / (max_benefit + 1)); + } + } /* When function local profile is available, base priorities on growth / frequency, so we optimize for overall frequency of inlined @@ -574,9 +597,13 @@ cgraph_edge_badness (struct cgraph_edge *edge) else if (flag_guess_branch_prob) { int div = edge->frequency * 100 / CGRAPH_FREQ_BASE + 1; + int benefitperc; + int growth_for_all; badness = growth * 10000; - div *= MIN (100 * inline_summary (edge->callee)->time_inlining_benefit - / (edge->callee->global.time + 1) + 1, 100); + benefitperc = + MIN (100 * inline_summary (edge->callee)->time_inlining_benefit / + (edge->callee->global.time + 1) +1, 100); + div *= benefitperc; /* Decrease badness if call is nested. */ @@ -587,9 +614,17 @@ cgraph_edge_badness (struct cgraph_edge *edge) div = 1; if (badness > 0) badness /= div; - badness += cgraph_estimate_growth (edge->callee); + growth_for_all = cgraph_estimate_growth (edge->callee); + badness += growth_for_all; if (badness > INT_MAX) - badness = INT_MAX; + badness = INT_MAX; + if (dump) + { + fprintf (dump_file, + " %i: guessed profile. frequency %i, overall growth %i," + " benefit %i%%, divisor %i\n", + (int) badness, edge->frequency, growth_for_all, benefitperc, div); + } } /* When function local profile is not available or it does not give useful information (ie frequency is zero), base the cost on @@ -604,10 +639,17 @@ cgraph_edge_badness (struct cgraph_edge *edge) if (badness > 0) badness >>= nest; else - { + { badness <<= nest; - } + } + if (dump) + fprintf (dump_file, " %i: no profile. nest %i\n", (int) badness, + nest); } + + /* Ensure that we did not overflow in all the fixed point math above. */ + gcc_assert (badness >= INT_MIN); + gcc_assert (badness <= INT_MAX - 1); /* Make recursive inlining happen always after other inlining is done. */ if (cgraph_recursive_inlining_p (edge->caller, edge->callee, NULL)) return badness + 1; @@ -651,7 +693,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, for (edge = node->callers; edge; edge = edge->next_caller) if (edge->inline_failed) { - int badness = cgraph_edge_badness (edge); + int badness = cgraph_edge_badness (edge, false); if (edge->aux) { fibnode_t n = (fibnode_t) edge->aux; @@ -660,8 +702,12 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, continue; /* fibheap_replace_key only increase the keys. */ - if (fibheap_replace_key (heap, n, badness)) - continue; + if (badness < n->key) + { + fibheap_replace_key (heap, n, badness); + gcc_assert (n->key == badness); + continue; + } fibheap_delete_node (heap, (fibnode_t) edge->aux); } edge->aux = fibheap_insert (heap, badness, edge); @@ -889,7 +935,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); - edge->aux = fibheap_insert (heap, cgraph_edge_badness (edge), edge); + edge->aux = fibheap_insert (heap, cgraph_edge_badness (edge, false), edge); } } @@ -938,7 +984,7 @@ cgraph_decide_inlining_of_small_functions (void) if (edge->inline_failed) { gcc_assert (!edge->aux); - edge->aux = fibheap_insert (heap, cgraph_edge_badness (edge), edge); + edge->aux = fibheap_insert (heap, cgraph_edge_badness (edge, false), edge); } } @@ -946,15 +992,26 @@ cgraph_decide_inlining_of_small_functions (void) min_size = overall_size; while (overall_size <= max_size - && (edge = (struct cgraph_edge *) fibheap_extract_min (heap))) + && !fibheap_empty (heap)) { int old_size = overall_size; - struct cgraph_node *where; - int growth = - cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee); + struct cgraph_node *where, *callee; + int badness = fibheap_min_key (heap); + int growth; cgraph_inline_failed_t not_good = CIF_OK; - growth -= edge->caller->global.size; + edge = (struct cgraph_edge *) fibheap_extract_min (heap); + gcc_assert (edge->aux); + edge->aux = NULL; + if (!edge->inline_failed) + continue; +#ifdef ENABLE_CHECKING + gcc_assert (cgraph_edge_badness (edge, false) == badness); +#endif + callee = edge->callee; + + growth = (cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee) + - edge->caller->global.size); if (dump_file) { @@ -970,15 +1027,13 @@ cgraph_decide_inlining_of_small_functions (void) gimple_filename ((const_gimple) edge->call_stmt), gimple_lineno ((const_gimple) edge->call_stmt), cgraph_estimate_growth (edge->callee), - cgraph_edge_badness (edge), + badness, edge->frequency / (double)CGRAPH_FREQ_BASE); if (edge->count) fprintf (dump_file," Called "HOST_WIDEST_INT_PRINT_DEC"x\n", edge->count); + if (dump_flags & TDF_DETAILS) + cgraph_edge_badness (edge, true); } - gcc_assert (edge->aux); - edge->aux = NULL; - if (!edge->inline_failed) - continue; /* When not having profile info ready we don't weight by any way the position of call in procedure itself. This means if call of @@ -1096,6 +1151,11 @@ cgraph_decide_inlining_of_small_functions (void) called by function we inlined (since number of it inlinable callers might change). */ update_caller_keys (heap, where, updated_nodes); + + /* We removed one call of the function we just inlined. If offline + copy is still needed, be sure to update the keys. */ + if (callee != where && !callee->global.inlined_to) + update_caller_keys (heap, callee, updated_nodes); bitmap_clear (updated_nodes); if (dump_file) @@ -1117,10 +1177,39 @@ cgraph_decide_inlining_of_small_functions (void) fprintf (dump_file, "New minimal size reached: %i\n", min_size); } } - while ((edge = (struct cgraph_edge *) fibheap_extract_min (heap)) != NULL) + while (!fibheap_empty (heap)) { + int badness = fibheap_min_key (heap); + + edge = (struct cgraph_edge *) fibheap_extract_min (heap); gcc_assert (edge->aux); edge->aux = NULL; + if (!edge->inline_failed) + continue; +#ifdef ENABLE_CHECKING + gcc_assert (cgraph_edge_badness (edge, false) == badness); +#endif + if (dump_file) + { + fprintf (dump_file, + "\nSkipping %s with %i size\n", + cgraph_node_name (edge->callee), + edge->callee->global.size); + fprintf (dump_file, + " called by %s in %s:%i\n" + " Estimated growth after inlined into all callees is %+i insns.\n" + " Estimated badness is %i, frequency %.2f.\n", + cgraph_node_name (edge->caller), + gimple_filename ((const_gimple) edge->call_stmt), + gimple_lineno ((const_gimple) edge->call_stmt), + cgraph_estimate_growth (edge->callee), + badness, + edge->frequency / (double)CGRAPH_FREQ_BASE); + if (edge->count) + fprintf (dump_file," Called "HOST_WIDEST_INT_PRINT_DEC"x\n", edge->count); + if (dump_flags & TDF_DETAILS) + cgraph_edge_badness (edge, true); + } if (!edge->callee->local.disregard_inline_limits && edge->inline_failed && !cgraph_recursive_inlining_p (edge->caller, edge->callee, &edge->inline_failed)) -- cgit v1.2.1 From 36595f6490217826e8834d94d0fbd86eb2ddcf89 Mon Sep 17 00:00:00 2001 From: hubicka Date: Sat, 17 Apr 2010 23:42:04 +0000 Subject: * ipa-inline.c (cgraph_early_inlining): Handle flattening too. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158477 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 601695a3fda..751966cefb2 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1667,6 +1667,17 @@ cgraph_early_inlining (void) } else { + if (lookup_attribute ("flatten", + DECL_ATTRIBUTES (node->decl)) != NULL) + { + if (dump_file) + fprintf (dump_file, + "Flattening %s\n", cgraph_node_name (node)); + cgraph_flatten (node); + timevar_push (TV_INTEGRATION); + todo |= optimize_inline_calls (current_function_decl); + timevar_pop (TV_INTEGRATION); + } /* We iterate incremental inlining to get trivial cases of indirect inlining. */ while (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) -- cgit v1.2.1 From 6d61f3f99adeb3765e55ba00a34bb6e66496995b Mon Sep 17 00:00:00 2001 From: hubicka Date: Wed, 21 Apr 2010 14:38:38 +0000 Subject: * cgraph.c (dump_cgraph_node): Dump also assembler name. * ipa-inline.c (cgraph_decide_inlining_of_small_functions): Do not ice at WPA dumping. (cgraph_decide_inlining): Do not expect callee to be removed in all cases. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158607 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 751966cefb2..8957990cae4 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1024,8 +1024,9 @@ cgraph_decide_inlining_of_small_functions (void) " Estimated growth after inlined into all callees is %+i insns.\n" " Estimated badness is %i, frequency %.2f.\n", cgraph_node_name (edge->caller), - gimple_filename ((const_gimple) edge->call_stmt), - gimple_lineno ((const_gimple) edge->call_stmt), + flag_wpa ? "unknown" + : gimple_filename ((const_gimple) edge->call_stmt), + flag_wpa ? -1 : gimple_lineno ((const_gimple) edge->call_stmt), cgraph_estimate_growth (edge->callee), badness, edge->frequency / (double)CGRAPH_FREQ_BASE); @@ -1200,8 +1201,9 @@ cgraph_decide_inlining_of_small_functions (void) " Estimated growth after inlined into all callees is %+i insns.\n" " Estimated badness is %i, frequency %.2f.\n", cgraph_node_name (edge->caller), - gimple_filename ((const_gimple) edge->call_stmt), - gimple_lineno ((const_gimple) edge->call_stmt), + flag_wpa ? "unknown" + : gimple_filename ((const_gimple) edge->call_stmt), + flag_wpa ? -1 : gimple_lineno ((const_gimple) edge->call_stmt), cgraph_estimate_growth (edge->callee), badness, edge->frequency / (double)CGRAPH_FREQ_BASE); @@ -1416,13 +1418,14 @@ cgraph_decide_inlining (void) if (cgraph_check_inline_limits (node->callers->caller, node, &reason, false)) { + struct cgraph_node *caller = node->callers->caller; cgraph_mark_inline (node->callers); if (dump_file) fprintf (dump_file, " Inlined into %s which now has %i size" " for a net change of %+i size.\n", - cgraph_node_name (node->callers->caller), - node->callers->caller->global.size, + cgraph_node_name (caller), + caller->global.size, overall_size - old_size); } else -- cgit v1.2.1 From ddc90d8846c96a8d60e5c145f71985dd9baa2fe7 Mon Sep 17 00:00:00 2001 From: hubicka Date: Wed, 21 Apr 2010 17:44:03 +0000 Subject: * tree-pass.h (ipa_opt_pass_d): Rename function_read_summary; add write_optimization_summary, read_optimization_summary. (ipa_write_summaries_of_cgraph_node_set): Remove. (ipa_write_optimization_summaries): Declare. (ipa_read_optimization_summaries): Declare. * ipa-cp.c (pass_ipa_cp): Update. * ipa-reference.c (pass_ipa_reference): Update. * ipa-pure-const.c (pass_ipa_pure_const): Update. * lto-streamer-out.c (pass_ipa_lto_gimple, pass_ipa_lto_finish): Update. * ipa-inline.c (pass_ipa_inline): Update. * ipa.c (pass_ipa_whole_program): Update. * lto-wpa-fixup.c (pass_ipa_lto_wpa_fixup): Update. * passes.c (ipa_write_summaries_1): Do not test wpa. (ipa_write_optimization_summaries_1): New. (ipa_write_optimization_summaries): New. (ipa_read_summaries): Do not test ltrans. (ipa_read_optimization_summaries_1): New. (ipa_read_optimization_summaries): New. * lto.c (lto_wpa_write_files): Update. (read_cgraph_and_symbols): Be more verbose. (materialize_cgraph): Likewise. (do_whole_program_analysis): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158616 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 8957990cae4..fbd695d129c 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -2135,7 +2135,8 @@ struct ipa_opt_pass_d pass_ipa_inline = inline_generate_summary, /* generate_summary */ inline_write_summary, /* write_summary */ inline_read_summary, /* read_summary */ - NULL, /* function_read_summary */ + NULL, /* write_optimization_summary */ + NULL, /* read_optimization_summary */ lto_ipa_fixup_call_notes, /* stmt_fixup */ 0, /* TODOs */ inline_transform, /* function_transform */ -- cgit v1.2.1 From 5ea601080eb8550f7226d3d9df4fa523f6161e51 Mon Sep 17 00:00:00 2001 From: hubicka Date: Tue, 27 Apr 2010 09:44:30 +0000 Subject: * cgraph.c (cgraph_propagate_frequency): New function. * cgraph.h (cgraph_propagate_frequency): Declare. * ipa-inline.c (cgraph_clone_inlined_nodes): Call cgraph_propagate_frequency. * testsuite/gcc.dg/ipa/iinline-1.c (main): Rename to... (test): ... this one. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158775 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index fbd695d129c..381942a5586 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -285,6 +285,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, + 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; + cgraph_propagate_frequency (e->callee); /* Recursively clone all bodies. */ for (e = e->callee->callees; e; e = e->next_callee) -- cgit v1.2.1 From 799c87118f9c74e999ba3f3390edc6a5346c8752 Mon Sep 17 00:00:00 2001 From: jamborm Date: Wed, 28 Apr 2010 14:05:54 +0000 Subject: 2010-04-28 Martin Jambor * cgraph.h (struct cgraph_node): New field indirect_calls. (struct cgraph_indirect_call_info): New type. (struct cgraph_edge): Removed field indirect_call. New fields indirect_info, indirect_inlining_edge and indirect_unknown_callee. (cgraph_create_indirect_edge): Declare. (cgraph_make_edge_direct): Likewise. (enum LTO_cgraph_tags): New item LTO_cgraph_indirect_edge. * ipa-prop.h (struct ipa_param_call_note): Removed. (struct ipa_node_params): Removed field param_calls. (ipa_create_all_structures_for_iinln): Declare. * cgraph.c: Described indirect edges and uids in initial comment. (cgraph_add_edge_to_call_site_hash): New function. (cgraph_edge): Search also among the indirect edges, use cgraph_add_edge_to_call_site_hash to add edges to the call site hash. (cgraph_set_call_stmt): Possibly turn an indirect edge into a direct one, use cgraph_add_edge_to_call_site_hash to add edges to the call site hash. (initialize_inline_failed): Assign a reason to indirect edges. (cgraph_create_edge_1): New function. (cgraph_create_edge): Moved some functionality to cgraph_create_edge_1. (cgraph_create_indirect_edge): New function. (cgraph_edge_remove_callee): Add an assert checking for non-indirectness. (cgraph_edge_remove_caller): Special-case indirect edges. (cgraph_remove_edge): Likewise. (cgraph_set_edge_callee): New function. (cgraph_redirect_edge_callee): Use cgraph_set_edge_callee. (cgraph_make_edge_direct): New function. (cgraph_update_edges_for_call_stmt_node): Do nothing only when also the declaration of the call statement matches. (cgraph_node_remove_callees): Special-case indirect edges. (cgraph_clone_edge): Likewise. (cgraph_clone_node): Clone also the indirect edges. (dump_cgraph_node): Dump indirect_inlining_edge flag instead of indirect_call, dump count of indirect_calls edges. * ipa-prop.c (iinlining_processed_edges): New variable. (ipa_note_param_call): Create indirect edges instead of creating notes. New parameter node. (ipa_analyze_call_uses): New parameter node, pass it on to ipa_note_param_call. (ipa_analyze_stmt_uses): Likewise. (ipa_analyze_params_uses): Pass node to ipa_analyze_stmt_uses. (print_edge_addition_message): Work on edges rather than on notes. (update_call_notes_after_inlining): Likewise, renamed to update_indirect_edges_after_inlining. (ipa_create_all_structures_for_iinln): New function. (ipa_free_node_params_substructures): Do not free notes. (ipa_edge_duplication_hook): Propagate bits within iinlining_processed_edges bitmap. (ipa_node_duplication_hook): Do not duplicate notes. (free_all_ipa_structures_after_ipa_cp): Renamed to ipa_free_all_structures_after_ipa_cp. (free_all_ipa_structures_after_iinln): Renamed to ipa_free_all_structures_after_iinln.g (ipa_write_param_call_note): Removed. (ipa_read_param_call_note): Removed. (ipa_write_indirect_edge_info): New function. (ipa_read_indirect_edge_info): Likewise. (ipa_write_node_info): Do not stream notes, do stream information in indirect edges. (ipa_read_node_info): Likewise. (lto_ipa_fixup_call_notes): Removed. * ipa-cp.c (pass_ipa_cp): Set stmt_fixup to NULL. * ipa-inline.c (pass_ipa_inline): Likewise. * cgraphunit.c (verify_cgraph_node): Check also indirect edges. * cif-code.def (INDIRECT_UNKNOWN_CALL): New reason. * tree-inline.c (copy_bb): Removed an unnecessary double check for is_gimple_call. * tree-inline.c (get_indirect_callee_fndecl): Do not consider indirect edges. * lto-cgraph.c (output_outgoing_cgraph_edges): New function. (output_cgraph): Stream also indirect edges. (lto_output_edge): Added capability to stream indirect edges. (input_edge): Likewise. (input_cgraph_1): Likewise. * testsuite/gcc.dg/lto/20091209-1_0.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158827 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 381942a5586..75adb011d15 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1322,6 +1322,8 @@ cgraph_decide_inlining (void) cgraph_remove_function_insertion_hook (function_insertion_hook_holder); if (in_lto_p && flag_indirect_inlining) ipa_update_after_lto_read (); + if (flag_indirect_inlining) + ipa_create_all_structures_for_iinln (); max_count = 0; max_benefit = 0; @@ -1442,7 +1444,7 @@ cgraph_decide_inlining (void) /* Free ipa-prop structures if they are no longer needed. */ if (flag_indirect_inlining) - free_all_ipa_structures_after_iinln (); + ipa_free_all_structures_after_iinln (); if (dump_file) fprintf (dump_file, @@ -2138,7 +2140,7 @@ struct ipa_opt_pass_d pass_ipa_inline = inline_read_summary, /* read_summary */ NULL, /* write_optimization_summary */ NULL, /* read_optimization_summary */ - lto_ipa_fixup_call_notes, /* stmt_fixup */ + NULL, /* stmt_fixup */ 0, /* TODOs */ inline_transform, /* function_transform */ NULL, /* variable_transform */ -- cgit v1.2.1 From 0cddb138341aafca38ae8d099c98750b5b34b8b2 Mon Sep 17 00:00:00 2001 From: hubicka Date: Thu, 29 Apr 2010 07:10:38 +0000 Subject: * lto-symtab.c (lto_symtab_entry_def) Add vnode. (lto_varpool_replace_node): New. (lto_symtab_resolve_symbols): Resolve varpool nodes. (lto_symtab_merge_decls_1): Prefer decls with varpool node. (lto_symtab_merge_cgraph_nodes_1): Merge varpools. * cgraph.h (varpool_node_ptr): New type. (varpool_node_ptr): New vector. (varpool_node_set_def): New structure. (varpool_node_set): New type. (varpool_node_set): New vector. (varpool_node_set_element_def): New structure. (varpool_node_set_element, const_varpool_node_set_element): New types. (varpool_node_set_iterator): New type. (varpool_node): Add prev pointers, add used_from_other_partition, in_other_partition. (varpool_node_set_new, varpool_node_set_find, varpool_node_set_add, varpool_node_set_remove, dump_varpool_node_set, debug_varpool_node_set, varpool_get_node, varpool_remove_node): Declare. (vsi_end_p, vsi_next, vsi_node, vsi_start, varpool_node_in_set_p, varpool_node_set_size): New inlines. * cgraph.c (dump_cgraph_node): Dump asm names of aliases. * tree-pass.h (varpool_node_set_def): Forward declare. (ipa_opt_pass_d): Summary writting takes vnode sets too. (ipa_write_optimization_summaries): Update prototype. * ipa-cp.c (ipcp_write_summary): Update. * ipa-reference.c (ipa_reference_write_summary): Update. * lto-cgraph.c (lto_output_varpool_node): New static function. (output_varpool): New function. (input_varpool_node): New static function. (input_varpool_1): New function. (input_cgraph): Input varpool. * ipa-pure-const.c (pure_const_write_summary): Update. * lto-streamer-out.c (lto_output): Update, output varpool too. (write_global_stream): Kill WPA hack. (produce_asm_for_decls): Update. (output_alias_pair_p): Handle variables. (output_unreferenced_globals): Output only needed partition of varpool. * ipa-inline.c (inline_write_summary): Update. * lto-streamer-in.c (lto_input_tree_ref, lto_input_tree): Do not build cgraph. * lto-section-in.c (lto_section_name): Add varpool and jump funcs. * ipa.c (hash_varpool_node_set_element, eq_varpool_node_set_element, varpool_node_set_new, varpool_node_set_add, varpool_node_set_remove, varpool_node_set_find, dump_varpool_node_set, debug_varpool_node_set): New functions. * passes.c (rest_of_decl_compilation): when in LTO do not finalize. (execute_one_pass): Process new decls too. (ipa_write_summaries_2): Pass around vsets. (ipa_write_summaries_1): Likewise. (ipa_write_summaries): Build vset; be more selective about cgraph nodes to add. (ipa_write_optimization_summaries_1): Pass around vsets. (ipa_write_optimization_summaries): Likewise. * varpool.c (varpool_get_node): New. (varpool_node): Update doubly linked lists. (varpool_remove_node): New. (dump_varpool_node): More dumping. (varpool_enqueue_needed_node): Update doubly linked lists. (decide_is_variable_needed): Kill ltrans hack. (varpool_finalize_decl): Kill lto hack. (varpool_assemble_decl): Skip decls in other partitions. (varpool_assemble_pending_decls): Update doubly linkes lists. (varpool_empty_needed_queue): Likewise. (varpool_extra_name_alias): Likewise. * lto-streamer.c (lto_get_section_name): Add vars section. * lto-streamer.h (lto_section_type): Update. (output_varpool, input_varpool): Declare. * lto.c (lto_varpool_node_sets): New. (lto_1_to_1_map): Partition varpool too. (globalize_context_t, globalize_cross_file_statics, lto_scan_statics_in_ref_table, lto_scan_statics_in_cgraph_node, lto_scan_statics_in_remaining_global_vars): Remove. (lto_promote_cross_file_statics): Rewrite. (get_filename_for_set): Take vset argument. (lto_wpa_write_files): Pass around vsets. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158854 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 75adb011d15..5146c3c3cad 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -2097,7 +2097,8 @@ inline_read_summary (void) active, we don't need to write them twice. */ static void -inline_write_summary (cgraph_node_set set) +inline_write_summary (cgraph_node_set set, + varpool_node_set vset ATTRIBUTE_UNUSED) { if (flag_indirect_inlining && !flag_ipa_cp) ipa_prop_write_jump_functions (set); -- cgit v1.2.1 From 5730594108b0d9f02924024c2bf86d8649d6e6ff Mon Sep 17 00:00:00 2001 From: hubicka Date: Thu, 29 Apr 2010 22:44:18 +0000 Subject: * gengtype.c (open_base_files): Add lto-streamer.h * cgraph.h (cgraph_local_info): lto_file_data is now in GGC. (pass_ipa_cp): GGC collect. * toplev. (compile_file): Do not output symbols. * ipa-inline.c (pass_ipa_inline): Add ggc collect. * timevar.def (TV_VARPOOL, TV_IPA_LTO_DECL_INIT_IO, TV_IPA_LTO_DECL_MERGE, TV_IPA_LTO_CGRAPH_MERGE, TV_VAROUT): New. * lto-section-in.c: Include ggc.h (lto_new_in_decl_state): Alloc in GGC. (lto_delete_in_decl_state): Likewise. * ipa.c (pass_ipa_function_visibility, pass_ipa_whole_program): Collect. * lto/lto.c (lto_read_in_decl_state): Use GGC. (lto_wpa_write_files): Announce what we are writting. (all_file_decl_data): New. (read_cgraph_and_symbols): Use GGC; correct timevars. (do_whole_program_analysis): Collect. * lto/Make-lang.in (lto.o): Fix dependency. * Makefile.in (GTFILES): Add lto-streamer.h. * varpool.c (varpool_analyze_pending_decls): Use TV_VARPOOL. (varpool_assemble_pending_decls): Use VAROUT. * lto-streamer.h (lto_tree_ref_table): Annotate. (lto_in_decl_state): Annotate. (lto_file_decl_data): Annotate. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158912 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 5146c3c3cad..3bab2059cf3 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -2134,7 +2134,7 @@ struct ipa_opt_pass_d pass_ipa_inline = 0, /* properties_destroyed */ TODO_remove_functions, /* todo_flags_finish */ TODO_dump_cgraph | TODO_dump_func - | TODO_remove_functions /* todo_flags_finish */ + | TODO_remove_functions | TODO_ggc_collect /* todo_flags_finish */ }, inline_generate_summary, /* generate_summary */ inline_write_summary, /* write_summary */ -- cgit v1.2.1 From b7e3aeb1d14c179214a5509ae0b031dd725c377d Mon Sep 17 00:00:00 2001 From: hubicka Date: Fri, 30 Apr 2010 09:29:44 +0000 Subject: * cgraph.h (cgraph_local_info): Remove for_functions_valid. (cgraph_global_info): Remove inlined. (LTO_cgraph_tag_names): Remove. (LTO_cgraph_tags, LCC_NOT_FOUND): Move to ... * lto-cgraph.c (LTO_cgraph_tags, LCC_NOT_FOUND): ... here; simplify cgraph tags and document. (lto_output_node): Use only LTO_cgraph_unavail_node and LTO_cgraph_analyzed_node; Do not save analzed, reachable, for_functions_valid, global info, process and output flags. (input_overwrite_node): Initialize estimated stack size and estimated growth. Do not read flags we no longer store. (input_node): Likewise do not read info no longer stored. * ipa-inline.c (cgraph_mark_inline_edge): Do not set global.inlined flag. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158926 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 3bab2059cf3..e18a0cd0ddd 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -310,10 +310,7 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, gcc_assert (e->inline_failed); e->inline_failed = CIF_OK; - - if (!e->callee->global.inlined) - DECL_POSSIBLY_INLINED (e->callee->decl) = true; - e->callee->global.inlined = true; + DECL_POSSIBLY_INLINED (e->callee->decl) = true; cgraph_clone_inlined_nodes (e, true, update_original); -- cgit v1.2.1 From 42edf1a349379974b3c0d63308d3b5469f0a1903 Mon Sep 17 00:00:00 2001 From: hubicka Date: Thu, 6 May 2010 14:15:22 +0000 Subject: PR tree-optimization/43791 * ipa-inline.c (update_caller_keys): Remove bogus disregard_inline_limits check. * gcc.c-torture/compile/pr43791.c: New file. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159108 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index e18a0cd0ddd..5f9fe102ba1 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -664,7 +664,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, struct cgraph_edge *edge; cgraph_inline_failed_t failed_reason; - if (!node->local.inlinable || node->local.disregard_inline_limits + if (!node->local.inlinable || node->global.inlined_to) return; if (bitmap_bit_p (updated_nodes, node->uid)) -- cgit v1.2.1 From 868357d3b0cfd84e11ca3b966294914b8a6b0664 Mon Sep 17 00:00:00 2001 From: rguenth Date: Sun, 9 May 2010 14:13:25 +0000 Subject: 2010-05-09 Richard Guenther PR middle-end/44043 * ipa-inline.c (estimate_function_body_sizes): Return after disregarding inline limits. * gcc.c-torture/compile/pr44043.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159200 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 5f9fe102ba1..8b73210c34d 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1835,10 +1835,13 @@ estimate_function_body_sizes (struct cgraph_node *node) if (node->local.disregard_inline_limits) { + if (dump_file) + fprintf (dump_file, "Disregarding inline limits.\n"); inline_summary (node)->self_time = 0; inline_summary (node)->self_size = 0; inline_summary (node)->time_inlining_benefit = 0; inline_summary (node)->size_inlining_benefit = 0; + return; } if (dump_file) -- cgit v1.2.1 From 960dff4ceb337fb4fe634c43a24261a015cffaaa Mon Sep 17 00:00:00 2001 From: hubicka Date: Tue, 11 May 2010 15:15:48 +0000 Subject: PR tree-optimize/44063 * ipa-inline.c (cgraph_edge_badness): Move always inlines to top of queue. (cgraph_decide_inlining_of_small_function): Skip check when disrgarding limits. (estimate_function_body_sizes): Compute sizes even when disregarding. * gcc.c-torture/compile/pr44063.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159273 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 8b73210c34d..6f189a6da2d 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -541,6 +541,9 @@ cgraph_edge_badness (struct cgraph_edge *edge, bool dump) (cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee) - edge->caller->global.size); + if (edge->callee->local.disregard_inline_limits) + return INT_MIN; + if (dump) { fprintf (dump_file, " Badness calculcation for %s -> %s\n", @@ -1068,12 +1071,14 @@ cgraph_decide_inlining_of_small_functions (void) } } - if (!cgraph_maybe_hot_edge_p (edge)) + if (edge->callee->local.disregard_inline_limits) + ; + else if (!cgraph_maybe_hot_edge_p (edge)) not_good = CIF_UNLIKELY_CALL; - if (!flag_inline_functions + else if (!flag_inline_functions && !DECL_DECLARED_INLINE_P (edge->callee->decl)) not_good = CIF_NOT_DECLARED_INLINED; - if (optimize_function_for_size_p (DECL_STRUCT_FUNCTION(edge->caller->decl))) + else if (optimize_function_for_size_p (DECL_STRUCT_FUNCTION(edge->caller->decl))) not_good = CIF_OPTIMIZING_FOR_SIZE; if (not_good && growth > 0 && cgraph_estimate_growth (edge->callee) > 0) { @@ -1833,17 +1838,6 @@ estimate_function_body_sizes (struct cgraph_node *node) int freq; tree funtype = TREE_TYPE (node->decl); - if (node->local.disregard_inline_limits) - { - if (dump_file) - fprintf (dump_file, "Disregarding inline limits.\n"); - inline_summary (node)->self_time = 0; - inline_summary (node)->self_size = 0; - inline_summary (node)->time_inlining_benefit = 0; - inline_summary (node)->size_inlining_benefit = 0; - return; - } - if (dump_file) fprintf (dump_file, "Analyzing function body size: %s\n", cgraph_node_name (node)); -- cgit v1.2.1 From 02b2818cfeffc3709b01ae5a2475d6f94eacb056 Mon Sep 17 00:00:00 2001 From: hubicka Date: Sun, 16 May 2010 21:49:36 +0000 Subject: * cgraph.c (cgraph_clone_node): Take decl argument and insert clone into hash when it is different from orig. (cgraph_create_virtual_clone): Update use of cgraph_clone_node. * cgraph.h (cgraph_clone_node): Update prototype. * lto-cgrpah.c (lto_cgraph_encoder_new): Create body map. (lto_cgraph_encoder_delete): Delete body map. (lto_cgraph_encoder_size): Move to header. (lto_cgraph_encoder_encode_body_p, lto_set_cgraph_encoder_encode_body): New. (lto_output_node): Do not take written_decls argument; output clone_of pointer. (add_node_to): Add include_body_argument; call lto_set_cgraph_encoder_encode_body on master of the clone. (add_references): Update use of add_node_to. (compute_ltrans_boundary): Likewise. (output_cgraph): Do not create written_decls bitmap. (input_node): Take nodes argument; stream in clone_of correctly. (input_cgraph_1): Update use of input_node. * lto-streamer-out.c (lto_output): Use encoder info to decide what bodies to output. * ipa-inline.c (cgraph_clone_inlined_nodes, cgraph_decide_recursive_inlining): Update call of cgraph_clone_node. * lto-streamer.h (lto_cgraph_encoder_d): Add body. (lto_cgraph_encoder_size): Define here. (lto_cgraph_encoder_encode_body_p, lto_varpool_encoder_encode_body_p): Declare. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159466 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 6f189a6da2d..e1de7ce25cc 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -268,7 +268,8 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, else { struct cgraph_node *n; - n = cgraph_clone_node (e->callee, e->count, e->frequency, e->loop_nest, + n = cgraph_clone_node (e->callee, e->callee->decl, + e->count, e->frequency, e->loop_nest, update_original, NULL); cgraph_redirect_edge_callee (e, n); } @@ -808,7 +809,8 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node, cgraph_node_name (node)); /* We need original clone to copy around. */ - master_clone = cgraph_clone_node (node, node->count, CGRAPH_FREQ_BASE, 1, + master_clone = cgraph_clone_node (node, node->decl, + node->count, CGRAPH_FREQ_BASE, 1, false, NULL); master_clone->needed = true; for (e = master_clone->callees; e; e = e->next_callee) -- cgit v1.2.1 From 7115ea0573bd294c444ed99fe7685b4646fa2dd6 Mon Sep 17 00:00:00 2001 From: jamborm Date: Wed, 19 May 2010 11:49:36 +0000 Subject: 2010-05-19 Martin Jambor * ipa-prop.c (ipa_print_node_jump_functions): Print jump functions also for indirect edges. Actual printing moved... (ipa_print_node_jump_functions_for_edge): ...here. (ipa_compute_jump_functions): Renamed to ipa_compute_jump_functions_for_edge and made static. (ipa_compute_jump_functions): New function. (make_edge_direct_to_target): Check if the number of arguments on the newly direct edge is the same as the number of parametrs of the callee. * ipa-cp.c (ipcp_init_stage): Most functionality moved to new ipa_compute_jump_functions. Call ipa_analyze_params_uses. * ipa-inline.c (inline_indirect_intraprocedural_analysis): Call analysis functions unconditionally, call the new ipa_analyze_params_uses on the node instead of every edge. * testsuite/g++.dg/ipa/ivinline-8.C: New test. * testsuite/gcc.dg/ipa/iinline-2.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159559 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index e1de7ce25cc..12757f7a2a3 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1971,21 +1971,10 @@ struct gimple_opt_pass pass_inline_parameters = static void inline_indirect_intraprocedural_analysis (struct cgraph_node *node) { - struct cgraph_edge *cs; - - if (!flag_ipa_cp) - { - ipa_initialize_node_params (node); - ipa_detect_param_modifications (node); - } + ipa_initialize_node_params (node); + ipa_detect_param_modifications (node); ipa_analyze_params_uses (node); - - if (!flag_ipa_cp) - for (cs = node->callees; cs; cs = cs->next_callee) - { - ipa_count_arguments (cs); - ipa_compute_jump_functions (cs); - } + ipa_compute_jump_functions (node); if (dump_file) { -- cgit v1.2.1 From ce084dfc1cd60d867d38dbed86a914d82fa908d1 Mon Sep 17 00:00:00 2001 From: jsm28 Date: Fri, 21 May 2010 22:34:26 +0000 Subject: * diagnostic.c: Don't include tm.h, tree.h, tm_p.h, langhooks.h or langhooks-def.h. (diagnostic_initialize): Initialize x_data not last_function. (diagnostic_report_current_function): Move to tree-diagnostic.c. (default_diagnostic_starter): Call diagnostic_report_current_module not diagnostic_report_current_function. (diagnostic_report_diagnostic): Initialize x_data not abstract_origin. (verbatim): Likewise. * diagnostic.h (struct diagnostic_info): Change abstract_origin to x_data. (struct diagnostic_context): Change last_function to x_data. (diagnostic_auxiliary_data): Replace with diagnostic_context_auxiliary_data and diagnostic_info_auxiliary_data. (diagnostic_last_function_changed, diagnostic_set_last_function, diagnostic_report_current_function): Move to tree-diagnostic.h. (print_declaration, dump_generic_node, print_generic_stmt, print_generic_stmt_indented, print_generic_expr, print_generic_decl, debug_c_tree, dump_omp_clauses, print_call_name, debug_generic_expr, debug_generic_stmt, debug_tree_chain, default_tree_printer): Move to tree-pretty-print.h. (debug_gimple_stmt, debug_gimple_seq, print_gimple_seq, print_gimple_stmt, print_gimple_expr, dump_gimple_stmt): Move to gimple-pretty-print.h. * pretty-print.c: Don't include tree.h (pp_base_format): Don't handle %K here. (pp_base_tree_identifier): Move to tree-pretty-print.c. * pretty-print.h (text_info): Change abstract_origin to x_data. (pp_tree_identifier, pp_unsupported_tree, pp_base_tree_identifier): Move to tree-pretty-print.h. * gimple-pretty-print.h, tree-diagnostic.c, tree-diagnostic.h, tree-pretty-print.h: New files. * tree-pretty-print.c: Include tree-pretty-print.h. (percent_K_format): New. Moved from pretty-print.c. (pp_base_tree_identifier): Move from pretty-print.c. * c-objc-common.c: Include tree-pretty-print.h. (c_tree_printer): Handle %K here. * langhooks.c: Include tree-diagnostic.h. (lhd_print_error_function): Use diagnostic_abstract_origin macro. * toplev.c: Include tree-diagnostic.h and tree-pretty-print.h. (default_tree_printer): Handle %K using percent_K_format. (general_init): Use default_tree_diagnostic_starter. * tree.c: Include tree-diagnostic.h and tree-pretty-print.h. (free_lang_data): Use default_tree_diagnostic_starter. * c-pretty-print.c: Include tree-pretty-print.h. * cfgexpand.c: Include tree-pretty-print.h and gimple-pretty-print.h. * cgraphunit.c: Include tree-pretty-print.h and gimple-pretty-print.h. * dwarf2out.c: Include tree-pretty-print.h. * except.c: Include tree-pretty-print.h. * gimple-pretty-print.c: Include tree-pretty-print.h and gimple-pretty-print.h. * gimplify.c: Include tree-pretty-print.h. * graphite-poly.c: Include tree-pretty-print.h and gimple-pretty-print.h. * ipa-cp.c: Include tree-pretty-print.h. * ipa-inline.c: Include gimple-pretty-print.h. * ipa-prop.c: Include tree-pretty-print.h and gimple-pretty-print.h. * ipa-pure-const.c: Include gimple-pretty-print.h. * ipa-struct-reorg.c: Include tree-pretty-print.h and gimple-pretty-print.h. * ipa-type-escape.c: Include tree-pretty-print.h. * print-rtl.c: Include tree-pretty-print.h. * print-tree.c: Include gimple-pretty-print.h. * sese.c: Include tree-pretty-print.h. * tree-affine.c: Include tree-pretty-print.h. * tree-browser.c: Include tree-pretty-print.h. * tree-call-cdce.c: Include gimple-pretty-print.h. * tree-cfg.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-chrec.c: Include tree-pretty-print.h. * tree-data-ref.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-dfa.c: Include tree-pretty-print.h. * tree-if-conv.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-inline.c: Include tree-pretty-print.h. * tree-into-ssa.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-nrv.c: Include tree-pretty-print.h. * tree-object-size.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-outof-ssa.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-parloops.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-predcom.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-scalar-evolution.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-sra.c: Include tree-pretty-print.h. * tree-ssa-address.c: Include tree-pretty-print.h. * tree-ssa-alias.c: Include tree-pretty-print.h. * tree-ssa-ccp.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-coalesce.c: Include tree-pretty-print.h. * tree-ssa-copy.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-copyrename.c: Include tree-pretty-print.h. * tree-ssa-dce.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-dom.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-dse.c: Include gimple-pretty-print.h. * tree-ssa-forwprop.c: Include tree-pretty-print.h. * tree-ssa-ifcombine.c: Include tree-pretty-print.h. * tree-ssa-live.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-loop-im.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-loop-ivcanon.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-loop-ivopts.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-loop-niter.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-loop-prefetch.c: Include tree-pretty-print.h. * tree-ssa-math-opts.c: Include gimple-pretty-print.h. * tree-ssa-operands.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-phiprop.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-pre.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-propagate.c: Include gimple-pretty-print.h. * tree-ssa-reassoc.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-sccvn.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-sink.c: Include gimple-pretty-print.h. * tree-ssa-ter.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-uninit.c: Include gimple-pretty-print.h. * tree-ssa.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-stdarg.c: Include gimple-pretty-print.h. * tree-switch-conversion.c: Include gimple-pretty-print.h. * tree-tailcall.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-vect-data-refs.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-vect-loop-manip.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-vect-loop.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-vect-patterns.c: Include gimple-pretty-print.h. * tree-vect-slp.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-vect-stmts.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-vectorizer.c: Include tree-pretty-print.h. * tree-vrp.c: Include tree-pretty-print.h and gimple-pretty-print.h. * value-prof.c: Include tree-pretty-print.h and gimple-pretty-print.h. * var-tracking.c: Include tree-pretty-print.h. * Makefile.in (OBJS-common): Add tree-diagnostic.o. (tree-diagnostic.o): New dependencies. (c-objc-common.o, c-pretty-print.o, langhooks.o, tree.o, tree-inline.o, print-tree.o, stor-layout.o, tree-ssa-uninit.o, tree-ssa.o, tree-into-ssa.o, tree-ssa-ter.o, tree-ssa-coalesce.o, tree-outof-ssa.o, tree-ssa-forwprop.o, tree-ssa-phiprop.o, tree-ssa-ifcombine.o, tree-nrv.o, tree-ssa-copy.o, tree-ssa-propagate.o, tree-ssa-dom.o, tree-ssa-uncprop.o, tree-ssa-live.o, tree-ssa-copyrename.o, tree-ssa-pre.o, tree-ssa-sccvn.o, tree-vrp.o, tree-cfg.o, tree-tailcall.o, tree-ssa-sink.o, tree-if-conv.o, tree-dfa.o, tree-ssa-operands.o, tree-ssa-address.o, tree-ssa-loop-niter.o, tree-ssa-loop-ivcanon.o, tree-ssa-loop-prefetch.o, tree-predcom.o, tree-ssa-loop-ivopts.o, tree-affine.o, tree-ssa-loop-im.o, tree-ssa-math-opts.o, tree-ssa-alias.o, tree-ssa-reassoc.o, gimplify.o, tree-browser.o, tree-chrec.o, tree-scalar-evolution.o, tree-data-ref.o, sese.o, graphite-poly.o, tree-vect-loop.o, tree-vect-loop-manip.o, tree-vect-patterns.o, tree-vect-slp.o, tree-vect-stmts.o, tree-vect-data-refs.o, tree-vectorizer.o, tree-parloops.o, tree-stdarg.o, tree-object-size.o, gimple-pretty-print.o, tree-pretty-print.o, diagnostic.o, toplev.o, print-rtl.o, except.o, dwarf2out.o, cgraphunit.o, ipa-prop.o, ipa-cp.o, ipa-inline.o, ipa-pure-const.o, ipa-type-escape.o, ipa-struct-reorg.o, tree-ssa-dce.o, tree-call-cdce.o, tree-ssa-ccp.o, tree-sra.o, tree-switch-conversion.o, var-tracking.o, value-prof.o, cfgexpand.o, pretty-print.o): Update dependencies. cp: * error.c: Include tree-diagnostic.h and tree-pretty-print.h. (cp_print_error_function): Use diagnostic_abstract_origin macro. (cp_printer): Handle %K here using percent_K_format. * cxx-pretty-print.c: Include tree-pretty-print.h. * Make-lang.in (cp/error.o, cp/cxx-pretty-print.o): Update dependencies. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159685 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 12757f7a2a3..38a9c56b282 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -128,6 +128,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "cgraph.h" #include "diagnostic.h" +#include "gimple-pretty-print.h" #include "timevar.h" #include "params.h" #include "fibheap.h" -- cgit v1.2.1 From e748b31d9ba52be4fa7e00e5e7a801b89343ec14 Mon Sep 17 00:00:00 2001 From: hubicka Date: Thu, 27 May 2010 02:07:01 +0000 Subject: * cgraphunit.c (verify_cgraph_node): Do checking that DECL match edge only when checking is enabled; check using former_clone_of; check inline clones too. (cgraph_materialize_clone): Record former_clone_of pointer. (cgraph_redirect_edge_call_stmt_to_callee): Assert that we are not combining redirections; dump args_to_skip bitmap (cgraph_materialize_all_clones): Do no redirection here. * ipa-inline.c (inline_transform): Do redirection here. * cgraph.h (struct cgraph_node): Add former_clone_of filed (enabled cheking only). git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159907 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 38a9c56b282..d5f48bdbc4c 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -2035,6 +2035,7 @@ inline_transform (struct cgraph_node *node) { unsigned int todo = 0; struct cgraph_edge *e; + bool inline_p = false; /* FIXME: Currently the passmanager is adding inline transform more than once to some clones. This needs revisiting after WPA cleanups. */ @@ -2047,10 +2048,13 @@ inline_transform (struct cgraph_node *node) save_inline_function_body (node); for (e = node->callees; e; e = e->next_callee) - if (!e->inline_failed || warn_inline) - break; + { + cgraph_redirect_edge_call_stmt_to_callee (e); + if (!e->inline_failed || warn_inline) + inline_p = true; + } - if (e) + if (inline_p) { timevar_push (TV_INTEGRATION); todo = optimize_inline_calls (current_function_decl); -- cgit v1.2.1 From 854efde4943d4fe89ba541e1edf222b11f1ab52b Mon Sep 17 00:00:00 2001 From: hubicka Date: Thu, 27 May 2010 17:07:21 +0000 Subject: * ipa-inline.c (cgraph_estimate_size_after_inlining): Make inline. (update_caller_keys): Return early if there are no callers; only update fibheap when decresing the key. (update_callee_keys): Avoid recursion. (decide_inlining_of_small_functions): When badness does not match; re-insert into fibheap. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159931 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 77 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 19 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index d5f48bdbc4c..aaae6393e15 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -201,11 +201,12 @@ cgraph_estimate_time_after_inlining (int frequency, struct cgraph_node *to, /* Estimate self time of the function after inlining WHAT into TO. */ -static int +static inline int cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to, struct cgraph_node *what) { - int size = (what->global.size - inline_summary (what)->size_inlining_benefit) * times + to->global.size; + int size = ((what->global.size - inline_summary (what)->size_inlining_benefit) + * times + to->global.size); gcc_assert (size >= 0); return size; } @@ -511,7 +512,7 @@ cgraph_default_inline_p (struct cgraph_node *n, cgraph_inline_failed_t *reason) We call recursive inlining all cases where same function appears more than once in the single recursion nest path in the inline graph. */ -static bool +static inline bool cgraph_recursive_inlining_p (struct cgraph_node *to, struct cgraph_node *what, cgraph_inline_failed_t *reason) @@ -679,10 +680,16 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, if (!node->local.inlinable) return; + /* See if there is something to do. */ + for (edge = node->callers; edge; edge = edge->next_caller) + if (edge->inline_failed) + break; + if (!edge) + return; /* Prune out edges we won't inline into anymore. */ if (!cgraph_default_inline_p (node, &failed_reason)) { - for (edge = node->callers; edge; edge = edge->next_caller) + for (; edge; edge = edge->next_caller) if (edge->aux) { fibheap_delete_node (heap, (fibnode_t) edge->aux); @@ -693,7 +700,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, return; } - for (edge = node->callers; edge; edge = edge->next_caller) + for (; edge; edge = edge->next_caller) if (edge->inline_failed) { int badness = cgraph_edge_badness (edge, false); @@ -704,33 +711,55 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, if (n->key == badness) continue; - /* fibheap_replace_key only increase the keys. */ + /* fibheap_replace_key only decrease the keys. + When we increase the key we do not update heap + and instead re-insert the element once it becomes + a minium of heap. */ if (badness < n->key) { fibheap_replace_key (heap, n, badness); gcc_assert (n->key == badness); continue; } - fibheap_delete_node (heap, (fibnode_t) edge->aux); } - edge->aux = fibheap_insert (heap, badness, edge); + else + edge->aux = fibheap_insert (heap, badness, edge); } } -/* Recompute heap nodes for each of caller edges of each of callees. */ +/* Recompute heap nodes for each of caller edges of each of callees. + Walk recursively into all inline clones. */ static void update_callee_keys (fibheap_t heap, struct cgraph_node *node, bitmap updated_nodes) { - struct cgraph_edge *e; + struct cgraph_edge *e = node->callees; node->global.estimated_growth = INT_MIN; - for (e = node->callees; e; e = e->next_callee) - if (e->inline_failed) - update_caller_keys (heap, e->callee, updated_nodes); - else if (!e->inline_failed) - update_callee_keys (heap, e->callee, updated_nodes); + if (!e) + return; + while (true) + if (!e->inline_failed && e->callee->callees) + e = e->callee->callees; + else + { + if (e->inline_failed) + update_caller_keys (heap, e->callee, updated_nodes); + if (e->next_callee) + e = e->next_callee; + else + { + do + { + if (e->caller == node) + return; + e = e->caller->callers; + } + while (!e->next_callee); + e = e->next_callee; + } + } } /* Enqueue all recursive calls from NODE into priority queue depending on @@ -1001,6 +1030,7 @@ cgraph_decide_inlining_of_small_functions (void) int old_size = overall_size; struct cgraph_node *where, *callee; int badness = fibheap_min_key (heap); + int current_badness; int growth; cgraph_inline_failed_t not_good = CIF_OK; @@ -1009,9 +1039,18 @@ cgraph_decide_inlining_of_small_functions (void) edge->aux = NULL; if (!edge->inline_failed) continue; -#ifdef ENABLE_CHECKING - gcc_assert (cgraph_edge_badness (edge, false) == badness); -#endif + + /* When updating the edge costs, we only decrease badness in the keys. + When the badness increase, we keep the heap as it is and re-insert + key now. */ + current_badness = cgraph_edge_badness (edge, false); + gcc_assert (current_badness >= badness); + if (current_badness != badness) + { + edge->aux = fibheap_insert (heap, current_badness, edge); + continue; + } + callee = edge->callee; growth = (cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee) @@ -1194,7 +1233,7 @@ cgraph_decide_inlining_of_small_functions (void) if (!edge->inline_failed) continue; #ifdef ENABLE_CHECKING - gcc_assert (cgraph_edge_badness (edge, false) == badness); + gcc_assert (cgraph_edge_badness (edge, false) >= badness); #endif if (dump_file) { -- cgit v1.2.1 From 852f689eb9b7f6d7aafc2f72007e96129ac9bd45 Mon Sep 17 00:00:00 2001 From: jsm28 Date: Thu, 27 May 2010 20:16:07 +0000 Subject: * diagnostic-core.h: New. Contents moved from diagnostic.h and toplev.h. * diagnostic.c: Don't include toplev.h. (progname): Define. Moved from toplev.c. (seen_error): New function. * diagnostic.h: Include diagnostic-core.h. (diagnostic_t, emit_diagnostic): Don't declare here. * toplev.c (progname): Move to toplev.c. (emit_debug_global_declarations, compile_file, finalize, do_compile, toplev_main): Use seen_error. * toplev.h: Include diagnostic-core.h. (trim_filename, GCC_DIAG_STYLE, ATTRIBUTE_GCC_DIAG, internal_error, warning, warning_at, error, error_n, error_at, fatal_error, pedwarn, permerror, sorry, inform, inform_n, verbatim, fnotice, progname): Move to diagnostic-core.h. * builtins.c: Include diagnostic-core.h instead of diagnostic.h. (expand_builtin_expect): Use seen_error. * c-decl.c: Include diagnostic-core.h instead of diagnostic.h. (c_make_fname_decl, c_write_global_declarations): Use seen_error. * c-format.c: Include diagnostic-core.h instead of diagnostic.h. * c-gimplify.c: Include diagnostic-core.h instead of diagnostic.h. * c-lang.c: Include diagnostic-core.h instead of diagnostic.h. * c-lex.c (c_lex_with_flags, interpret_float): Don't increment errorcount for errors. * c-opts.c (c_common_finish): Use seen_error. * cgraph.c: Include diagnostic-core.h instead of diagnostic.h. * cgraphunit.c (verify_cgraph_node, verify_cgraph, cgraph_output_pending_asms, cgraph_optimize): Use seen_error. * coverage.c: Include diagnostic-core.h instead of diagnostic.h. (get_coverage_counts): Use seen_error. * dwarf2out.c (dwarf2out_finish): Use seen_error. * gimplify.c (gimplify_var_or_parm_decl, gimple_push_cleanup, gimplify_body): Use seen_error. * ipa-inline.c (cgraph_early_inlining): Use seen_error. * ipa-pure-const.c (gate_pure_const): Use seen_error. * ipa-reference.c (gate_reference): Use seen_error. * jump.c: Include diagnostic-core.h instead of diagnostic.h. * lambda-code.c: Include diagnostic-core.h instead of diagnostic.h. * lto-cgraph.c: Include diagnostic-core.h instead of diagnostic.h. * lto-compress.c: Include diagnostic-core.h instead of diagnostic.h. * lto-section-in.c: Include diagnostic-core.h instead of diagnostic.h. * lto-streamer-out.c: Include diagnostic-core.h instead of diagnostic.h. * lto-streamer.c: Include diagnostic-core.h instead of diagnostic.h. (gate_lto_out): Use seen_error. * matrix-reorg.c: Include diagnostic-core.h instead of diagnostic.h. * omega.c: Include diagnostic-core.h instead of diagnostic.h. * omp-low.c: Include diagnostic-core.h instead of diagnostic.h. (gate_expand_omp, lower_omp_1): Use seen_error. * passes.c: Include diagnostic-core.h instead of diagnostic.h. (rest_of_decl_compilation, rest_of_type_compilation, gate_rest_of_compilation, ipa_write_summaries): Use seen_error. * tree-cfg.c (label_to_block_fn): Use seen_error. * tree-inline.c (optimize_inline_calls): Use seen_error. * tree-mudflap.c (mudflap_finish_file): Use seen_error. * tree-optimize.c (gate_all_optimizations, gate_all_early_local_passes, gate_all_early_optimizations): Use seen_error. * tree-ssa-structalias.c (gate_ipa_pta): Use seen_error. * varpool.c: Include diagnostic-core.h instead of diagnostic.h. (varpool_remove_unreferenced_decls, varpool_assemble_pending_decls): Use seen_error. * Makefile.in (DIAGNOSTIC_CORE_H): Define. (TOPLEV_H, DIAGNOSTIC_H): Update. (c-decl.o, c-lang.o, c-format.o, lto-compress.o, lto-cgraph.o, lto-streamer-out.o, lto-section-in.o, lto-streamer.o, c-gimplify.o, omp-low.o, omega.o, diagnostic.o, passes.o, builtins.o, jump.o, cgraph.o, varpool.o, matrix-reorg.o, coverage.o, lambda-code.o): Update dependencies. cp: * call.c: Include diagnostic-core.h instead of diagnostic.h. * cp-lang.c: Don't include diagnostic.h * name-lookup.c: Include diagnostic-core.h instead of diagnostic.h. (cp_emit_debug_info_for_using): Use seen_error. * optimize.c: Include diagnostic-core.h instead of diagnostic.h. * parser.c: Include diagnostic-core.h instead of diagnostic.h. * pt.c (iterative_hash_template_arg): Use seen_error. * repo.c: Include diagnostic-core.h instead of diagnostic.h. * typeck2.c: Include diagnostic-core.h instead of diagnostic.h. * Make-lang.in (cp/cp-lang.o, cp/typeck2.o, cp/call.o, cp/repo.o, cp/optimize.o, cp/parser.o, cp/name-lookup.o): Update dependencies. lto: * lto.c: Include diagnostic-core.h instead of diagnostic.h. (read_cgraph_and_symbols, lto_main): Use seen_error. * Make-lang.in (lto/lto.o): Update dependencies. objc: * objc-act.c: Include diagnostic-core.h instead of diagnostic.h. * Make-lang.in (objc/objc-act.o): Update dependencies. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159947 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index aaae6393e15..46bce87b16f 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1701,7 +1701,7 @@ cgraph_early_inlining (void) unsigned int todo = 0; int iterations = 0; - if (sorrycount || errorcount) + if (seen_error ()) return 0; if (!optimize -- cgit v1.2.1 From 8b68ef1b2beac3530e2048e5f397b9697887962f Mon Sep 17 00:00:00 2001 From: jamborm Date: Fri, 25 Jun 2010 14:27:47 +0000 Subject: 2010-06-25 Martin Jambor * ipa-prop.h (struct ipa_param_descriptor): Removed the modified flag. (struct ipa_node_params): Removed the modification_analysis_done flag. (ipa_is_param_modified): Removed. (ipa_analyze_node): Declare. (ipa_compute_jump_functions): Remove declaration. (ipa_count_arguments): Likewise. (ipa_detect_param_modifications): Likewise. (ipa_analyze_params_uses): Likewise. * ipa-prop.c (struct param_analysis_info): New type. (visit_store_addr_for_mod_analysis): Removed. (visit_load_for_mod_analysis): Renamed to visit_ref_for_mod_analysis, moved down in the file. (ipa_detect_param_modifications): Merged into ipa_analyze_params_uses. (ipa_count_arguments): Made static. (mark_modified): New function. (is_parm_modified_before_call): New function. (compute_pass_through_member_ptrs): New parameter parms_info, call is_parm_modified_before_call instead of ipa_is_param_modified. (ipa_compute_jump_functions_for_edge): New parameter parms_info, pass it to compute_pass_through_member_ptrs. (ipa_compute_jump_functions): New parameter parms_info, pass it to ipa_compute_jump_functions_for_edge. Call ipa_initialize_node_params on the callee if it is analyzed. Made static. (ipa_analyze_indirect_call_uses): New parameter parms_info, call is_parm_modified_before_call instead of ipa_is_param_modified. (ipa_analyze_call_uses): New parameter parms_info, pass it to ipa_analyze_indirect_call_uses. (ipa_analyze_stmt_uses): New parameter parms_info, pass it to ipa_analyze_call_uses. (ipa_analyze_params_uses): New parameter parms_info, pass it to ipa_analyze_stmt_uses. Also perform the used analysis. Made static. (ipa_analyze_node): New function. (ipa_print_node_params): Do not dump the modified flag. (ipa_write_node_info): Assert uses_analysis_done rather than streaming it. Do not stream the modified parameter flag. (ipa_read_node_info): Set uses_analysis_done to 1 instead of streaming it. Do not stream the modified parameter flag. * ipa-cp.c (ipcp_analyze_node): Removed. (ipcp_init_stage): Iterate only once over the nodes, analyze each one with only a call to ipa_analyze_node. * ipa-inline.c (inline_indirect_intraprocedural_analysis): Analyze the node with only a call to ipa_analyze_node. * testsuite/g++.dg/ipa/iinline-3.C: New test. * testsuite/gcc.dg/ipa/modif-1.c: Removed. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161384 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 46bce87b16f..266d481950f 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -2011,12 +2011,8 @@ struct gimple_opt_pass pass_inline_parameters = static void inline_indirect_intraprocedural_analysis (struct cgraph_node *node) { - ipa_initialize_node_params (node); - ipa_detect_param_modifications (node); - ipa_analyze_params_uses (node); - ipa_compute_jump_functions (node); - - if (dump_file) + ipa_analyze_node (node); + if (dump_file && (dump_flags & TDF_DETAILS)) { ipa_print_node_params (dump_file, node); ipa_print_node_jump_functions (dump_file, node); -- cgit v1.2.1 From 1e93351e71235b9edf26b1dc95d882f30dc60b17 Mon Sep 17 00:00:00 2001 From: hubicka Date: Mon, 28 Jun 2010 15:12:11 +0000 Subject: PR tree-optimization/44357 * ipa-inline.c (add_new_edges_to_heap): Do not add edges to uninlinable functions. PR tree-optimization/44357 * g++.dg/torture/pr44357.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161495 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 266d481950f..f9e4cf3cfa7 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -968,7 +968,9 @@ 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); - edge->aux = fibheap_insert (heap, cgraph_edge_badness (edge, false), edge); + if (edge->callee->local.inlinable + && cgraph_default_inline_p (edge->callee, &edge->inline_failed)) + edge->aux = fibheap_insert (heap, cgraph_edge_badness (edge, false), edge); } } -- cgit v1.2.1 From 182cf5a9a415f31df0f9a10e46faed1221484a35 Mon Sep 17 00:00:00 2001 From: rguenth Date: Thu, 1 Jul 2010 08:49:19 +0000 Subject: 2010-07-01 Richard Guenther PR middle-end/42834 PR middle-end/44468 * doc/gimple.texi (is_gimple_mem_ref_addr): Document. * doc/generic.texi (References to storage): Document MEM_REF. * tree-pretty-print.c (dump_generic_node): Handle MEM_REF. (print_call_name): Likewise. * tree.c (recompute_tree_invariant_for_addr_expr): Handle MEM_REF. (build_simple_mem_ref_loc): New function. (mem_ref_offset): Likewise. * tree.h (build_simple_mem_ref_loc): Declare. (build_simple_mem_ref): Define. (mem_ref_offset): Declare. * fold-const.c: Include tree-flow.h. (operand_equal_p): Handle MEM_REF. (build_fold_addr_expr_with_type_loc): Likewise. (fold_comparison): Likewise. (fold_unary_loc): Fold VIEW_CONVERT_EXPR > to MEM_REF . (fold_binary_loc): Fold MEM[&MEM[p, CST1], CST2] to MEM[p, CST1 + CST2], fold MEM[&a.b, CST2] to MEM[&a, offsetof (a, b) + CST2]. * tree-ssa-alias.c (ptr_deref_may_alias_decl_p): Handle MEM_REF. (ptr_deref_may_alias_ref_p_1): Likewise. (ao_ref_base_alias_set): Properly differentiate base object for offset and TBAA. (ao_ref_init_from_ptr_and_size): Use MEM_REF. (indirect_ref_may_alias_decl_p): Handle MEM_REFs properly. (indirect_refs_may_alias_p): Likewise. (refs_may_alias_p_1): Likewise. Remove pointer SSA name def chasing code. (ref_maybe_used_by_call_p_1): Handle MEM_REF. (call_may_clobber_ref_p_1): Likewise. * dwarf2out.c (loc_list_from_tree): Handle MEM_REF. * expr.c (expand_assignment): Handle MEM_REF. (store_expr): Handle MEM_REFs from STRING_CSTs. (store_field): If expanding a MEM_REF of a non-addressable decl use bitfield operations. (get_inner_reference): Handle MEM_REF. (expand_expr_addr_expr_1): Likewise. (expand_expr_real_1): Likewise. * tree-eh.c (tree_could_trap_p): Handle MEM_REF. * alias.c (ao_ref_from_mem): Handle MEM_REF. (get_alias_set): Likewise. Properly handle VIEW_CONVERT_EXPRs. * tree-data-ref.c (dr_analyze_innermost): Handle MEM_REF. (dr_analyze_indices): Likewise. (dr_analyze_alias): Likewise. (object_address_invariant_in_loop_p): Likewise. * gimplify.c (mark_addressable): Handle MEM_REF. (gimplify_cond_expr): Build MEM_REFs. (gimplify_modify_expr_to_memcpy): Likewise. (gimplify_init_ctor_preeval_1): Handle MEM_REF. (gimple_fold_indirect_ref): Adjust. (gimplify_expr): Handle MEM_REF. Gimplify INDIRECT_REF to MEM_REF. * tree.def (MEM_REF): New tree code. * tree-dfa.c: Include toplev.h. (get_ref_base_and_extent): Handle MEM_REF. (get_addr_base_and_unit_offset): New function. * emit-rtl.c (set_mem_attributes_minus_bitpos): Handle MEM_REF. * gimple-fold.c (may_propagate_address_into_dereference): Handle MEM_REF. (maybe_fold_offset_to_array_ref): Allow possibly out-of bounds accesses if the array has just one dimension. Remove always true parameter. Do not require type compatibility here. (maybe_fold_offset_to_component_ref): Remove. (maybe_fold_stmt_indirect): Remove. (maybe_fold_reference): Remove INDIRECT_REF handling. Fold back to non-MEM_REF. (maybe_fold_offset_to_address): Simplify. Deal with type mismatches here. (maybe_fold_reference): Likewise. (maybe_fold_stmt_addition): Likewise. Also handle &ARRAY + I in addition to &ARRAY[0] + I. (fold_gimple_assign): Handle ADDR_EXPR of MEM_REFs. (gimple_get_relevant_ref_binfo): Handle MEM_REF. * cfgexpand.c (expand_debug_expr): Handle MEM_REF. * tree-ssa.c (useless_type_conversion_p): Make most pointer conversions useless. (warn_uninitialized_var): Handle MEM_REF. (maybe_rewrite_mem_ref_base): New function. (execute_update_addresses_taken): Implement re-writing of MEM_REFs to SSA form. * tree-inline.c (remap_gimple_op_r): Handle MEM_REF, remove INDIRECT_REF handling. (copy_tree_body_r): Handle MEM_REF. * gimple.c (is_gimple_addressable): Adjust. (is_gimple_address): Likewise. (is_gimple_invariant_address): ADDR_EXPRs of MEM_REFs with invariant base are invariant. (is_gimple_min_lval): Adjust. (is_gimple_mem_ref_addr): New function. (get_base_address): Handle MEM_REF. (count_ptr_derefs): Likewise. (get_base_loadstore): Likewise. * gimple.h (is_gimple_mem_ref_addr): Declare. (gimple_call_fndecl): Handle invariant MEM_REF addresses. * tree-cfg.c (verify_address): New function, split out from ... (verify_expr): ... here. Use for verifying ADDR_EXPRs and the address operand of MEM_REFs. Verify MEM_REFs. Reject INDIRECT_REFs. (verify_types_in_gimple_min_lval): Handle MEM_REF. Disallow INDIRECT_REF. Allow conversions. (verify_types_in_gimple_reference): Verify VIEW_CONVERT_EXPR of a register does not change its size. (verify_types_in_gimple_reference): Verify MEM_REF. (verify_gimple_assign_single): Disallow INDIRECT_REF. Handle MEM_REF. * tree-ssa-operands.c (opf_non_addressable, opf_not_non_addressable): New. (mark_address_taken): Handle MEM_REF. (get_indirect_ref_operands): Pass through opf_not_non_addressable. (get_asm_expr_operands): Pass opf_not_non_addressable. (get_expr_operands): Handle opf_[not_]non_addressable. Handle MEM_REF. Remove INDIRECT_REF handling. * tree-vrp.c: (check_array_ref): Handle MEM_REF. (search_for_addr_array): Likewise. (check_array_bounds): Likewise. (vrp_stmt_computes_nonzero): Adjust for MEM_REF. * tree-ssa-loop-im.c (for_each_index): Handle MEM_REF. (ref_always_accessed_p): Likewise. (gen_lsm_tmp_name): Likewise. Handle ADDR_EXPR. * tree-complex.c (extract_component): Do not handle INDIRECT_REF. Handle MEM_REF. * cgraphbuild.c (mark_load): Properly check for NULL result from get_base_address. (mark_store): Likewise. * tree-ssa-loop-niter.c (array_at_struct_end_p): Handle MEM_REF. * tree-loop-distribution.c (generate_builtin): Exchange INDIRECT_REF handling for MEM_REF. * tree-scalar-evolution.c (follow_ssa_edge_expr): Handle &MEM[ptr + CST] similar to POINTER_PLUS_EXPR. * builtins.c (stabilize_va_list_loc): Use the function ABI valist type if we couldn't canonicalize the argument type. Always dereference with the canonical va-list type. (maybe_emit_free_warning): Handle MEM_REF. (fold_builtin_memory_op): Simplify and handle MEM_REFs in folding memmove to memcpy. * builtins.c (fold_builtin_memory_op): Use ref-all types for all memcpy foldings. * omp-low.c (build_receiver_ref): Adjust for MEM_REF. (build_outer_var_ref): Likewise. (scan_omp_1_op): Likewise. (lower_rec_input_clauses): Likewise. (lower_lastprivate_clauses): Likewise. (lower_reduction_clauses): Likewise. (lower_copyprivate_clauses): Likewise. (expand_omp_atomic_pipeline): Likewise. (expand_omp_atomic_mutex): Likewise. (create_task_copyfn): Likewise. * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Handle MEM_REF. Remove old union trick. Initialize constant offsets. (ao_ref_init_from_vn_reference): Likewise. Do not handle INDIRECT_REF. Init base_alias_set properly. (vn_reference_lookup_3): Replace INDIRECT_REF handling with MEM_REF. (vn_reference_fold_indirect): Adjust for MEM_REFs. (valueize_refs): Fold MEM_REFs. Re-evaluate constant offset for ARRAY_REFs. (may_insert): Remove. (visit_reference_op_load): Do not test may_insert. (run_scc_vn): Remove parameter, do not fiddle with may_insert. * tree-ssa-sccvn.h (struct vn_reference_op_struct): Add a field to store the constant offset this op applies. (run_scc_vn): Adjust prototype. * cgraphunit.c (thunk_adjust): Adjust for MEM_REF. * tree-ssa-ccp.c (ccp_fold): Replace INDIRECT_REF folding with MEM_REF. Propagate &foo + CST as &MEM[&foo, CST]. Do not bother about volatile qualifiers on pointers. (fold_const_aggregate_ref): Handle MEM_REF, do not handle INDIRECT_REF. * tree-ssa-loop-ivopts.c * tree-ssa-loop-ivopts.c (determine_base_object): Adjust for MEM_REF. (strip_offset_1): Likewise. (find_interesting_uses_address): Replace INDIRECT_REF handling with MEM_REF handling. (get_computation_cost_at): Likewise. * ipa-pure-const.c (check_op): Handle MEM_REF. * tree-stdarg.c (check_all_va_list_escapes): Adjust for MEM_REF. * tree-ssa-sink.c (is_hidden_global_store): Handle MEM_REF and constants. * ipa-inline.c (likely_eliminated_by_inlining_p): Handle MEM_REF. * tree-parloops.c (take_address_of): Adjust for MEM_REF. (eliminate_local_variables_1): Likewise. (create_call_for_reduction_1): Likewise. (create_loads_for_reductions): Likewise. (create_loads_and_stores_for_name): Likewise. * matrix-reorg.c (may_flatten_matrices_1): Sanitize. (ssa_accessed_in_tree): Handle MEM_REF. (ssa_accessed_in_assign_rhs): Likewise. (update_type_size): Likewise. (analyze_accesses_for_call_stmt): Likewise. (analyze_accesses_for_assign_stmt): Likewise. (transform_access_sites): Likewise. (transform_allocation_sites): Likewise. * tree-affine.c (tree_to_aff_combination): Handle MEM_REF. * tree-vect-data-refs.c (vect_create_addr_base_for_vector_ref): Do not handle INDIRECT_REF. * tree-ssa-phiopt.c (add_or_mark_expr): Handle MEM_REF. (cond_store_replacement): Likewise. * tree-ssa-pre.c (create_component_ref_by_pieces_1): Handle MEM_REF, no not handle INDIRECT_REFs. (insert_into_preds_of_block): Properly initialize avail. (phi_translate_1): Fold MEM_REFs. Re-evaluate constant offset for ARRAY_REFs. Properly handle reference lookups that require a bit re-interpretation. (can_PRE_operation): Do not handle INDIRECT_REF. Handle MEM_REF. * tree-sra.c * tree-sra.c (build_access_from_expr_1): Handle MEM_REF. (build_ref_for_offset_1): Remove. (build_ref_for_offset): Build MEM_REFs. (gate_intra_sra): Disable for now. (sra_ipa_modify_expr): Handle MEM_REF. (ipa_early_sra_gate): Disable for now. * tree-sra.c (create_access): Swap INDIRECT_REF handling for MEM_REF handling. (disqualify_base_of_expr): Likewise. (ptr_parm_has_direct_uses): Swap INDIRECT_REF handling for MEM_REF handling. (sra_ipa_modify_expr): Remove INDIRECT_REF handling. Use mem_ref_offset. Remove bogus folding. (build_access_from_expr_1): Properly handle MEM_REF for non IPA-SRA. (make_fancy_name_1): Add support for MEM_REF. * tree-predcom.c (ref_at_iteration): Handle MEM_REFs. * tree-mudflap.c (mf_xform_derefs_1): Adjust for MEM_REF. * ipa-prop.c (compute_complex_assign_jump_func): Handle MEM_REF. (compute_complex_ancestor_jump_func): Likewise. (ipa_analyze_virtual_call_uses): Likewise. * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Replace INDIRECT_REF folding with more generalized MEM_REF folding. (tree_ssa_forward_propagate_single_use_vars): Adjust accordingly. (forward_propagate_addr_into_variable_array_index): Also handle &ARRAY + I in addition to &ARRAY[0] + I. * tree-ssa-dce.c (ref_may_be_aliased): Handle MEM_REF. * tree-ssa-ter.c (find_replaceable_in_bb): Avoid TER if that creates assignments with overlap. * tree-nested.c (get_static_chain): Adjust for MEM_REF. (get_frame_field): Likewise. (get_nonlocal_debug_decl): Likewise. (convert_nonlocal_reference_op): Likewise. (struct nesting_info): Add mem_refs pointer-set. (create_nesting_tree): Allocate it. (convert_local_reference_op): Insert to be folded mem-refs. (fold_mem_refs): New function. (finalize_nesting_tree_1): Perform defered folding of mem-refs (free_nesting_tree): Free the pointer-set. * tree-vect-stmts.c (vectorizable_store): Adjust for MEM_REF. (vectorizable_load): Likewise. * tree-ssa-phiprop.c (phiprop_insert_phi): Adjust for MEM_REF. (propagate_with_phi): Likewise. * tree-object-size.c (addr_object_size): Handle MEM_REFs instead of INDIRECT_REFs. (compute_object_offset): Handle MEM_REF. (plus_stmt_object_size): Handle MEM_REF. (collect_object_sizes_for): Dispatch to plus_stmt_object_size for &MEM_REF. * tree-flow.h (get_addr_base_and_unit_offset): Declare. (symbol_marked_for_renaming): Likewise. * Makefile.in (tree-dfa.o): Add $(TOPLEV_H). (fold-const.o): Add $(TREE_FLOW_H). * tree-ssa-structalias.c (get_constraint_for_1): Handle MEM_REF. (find_func_clobbers): Likewise. * ipa-struct-reorg.c (decompose_indirect_ref_acc): Handle MEM_REF. (decompose_access): Likewise. (replace_field_acc): Likewise. (replace_field_access_stmt): Likewise. (insert_new_var_in_stmt): Likewise. (get_stmt_accesses): Likewise. (reorg_structs_drive): Disable. * config/i386/i386.c (ix86_va_start): Adjust for MEM_REF. (ix86_canonical_va_list_type): Likewise. cp/ * cp-gimplify.c (cp_gimplify_expr): Open-code the rhs predicate we are looking for, allow non-gimplified INDIRECT_REFs. testsuite/ * gcc.c-torture/execute/20100316-1.c: New testcase. * gcc.c-torture/execute/pr44468.c: Likewise. * gcc.c-torture/compile/20100609-1.c: Likewise. * gcc.dg/volatile2.c: Adjust. * gcc.dg/plugin/selfassign.c: Likewise. * gcc.dg/pr36902.c: Likewise. * gcc.dg/tree-ssa/foldaddr-2.c: Remove. * gcc.dg/tree-ssa/foldaddr-3.c: Likewise. * gcc.dg/tree-ssa/forwprop-8.c: Adjust. * gcc.dg/tree-ssa/pr17141-1.c: Likewise. * gcc.dg/tree-ssa/ssa-fre-13.c: Likewise. * gcc.dg/tree-ssa/ssa-fre-14.c: Likewise. * gcc.dg/tree-ssa/ssa-ccp-21.c: Likewise. * gcc.dg/tree-ssa/pta-ptrarith-1.c: Likewise. * gcc.dg/tree-ssa/20030807-7.c: Likewise. * gcc.dg/tree-ssa/forwprop-10.c: Likewise. * gcc.dg/tree-ssa/ssa-fre-1.c: Likewise. * gcc.dg/tree-ssa/pta-ptrarith-2.c: Likewise. * gcc.dg/tree-ssa/ssa-ccp-23.c: Likewise. * gcc.dg/tree-ssa/forwprop-1.c: Likewise. * gcc.dg/tree-ssa/forwprop-2.c: Likewise. * gcc.dg/tree-ssa/struct-aliasing-1.c: Likewise. * gcc.dg/tree-ssa/ssa-ccp-25.c: Likewise. * gcc.dg/tree-ssa/ssa-pre-26.c: Likewise. * gcc.dg/tree-ssa/struct-aliasing-2.c: Likewise. * gcc.dg/tree-ssa/ssa-ccp-26.c: Likewise. * gcc.dg/tree-ssa/ssa-sccvn-4.c: Likewise. * gcc.dg/tree-ssa/ssa-pre-7.c: Likewise. * gcc.dg/tree-ssa/forwprop-5.c: Likewise. * gcc.dg/struct/w_prof_two_strs.c: XFAIL. * gcc.dg/struct/wo_prof_escape_arg_to_local.c: Likewise. * gcc.dg/struct/wo_prof_global_var.c: Likewise. * gcc.dg/struct/wo_prof_malloc_size_var.c: Likewise. * gcc.dg/struct/w_prof_local_array.c: Likewise. * gcc.dg/struct/w_prof_single_str_global.c: Likewise. * gcc.dg/struct/wo_prof_escape_str_init.c: Likewise. * gcc.dg/struct/wo_prof_array_through_pointer.c: Likewise. * gcc.dg/struct/w_prof_global_array.c: Likewise. * gcc.dg/struct/wo_prof_array_field.c: Likewise. * gcc.dg/struct/wo_prof_single_str_local.c: Likewise. * gcc.dg/struct/w_prof_local_var.c: Likewise. * gcc.dg/struct/wo_prof_two_strs.c: Likewise. * gcc.dg/struct/wo_prof_empty_str.c: Likewise. * gcc.dg/struct/wo_prof_local_array.c: Likewise. * gcc.dg/struct/w_prof_global_var.c: Likewise. * gcc.dg/struct/wo_prof_single_str_global.c: Likewise. * gcc.dg/struct/wo_prof_escape_substr_value.c: Likewise. * gcc.dg/struct/wo_prof_global_array.c: Likewise. * gcc.dg/struct/wo_prof_escape_return.c: Likewise. * gcc.dg/struct/wo_prof_escape_substr_array.c: Likewise. * gcc.dg/struct/wo_prof_double_malloc.c: Likewise. * gcc.dg/struct/w_ratio_cold_str.c: Likewise. * gcc.dg/struct/wo_prof_escape_substr_pointer.c: Likewise. * gcc.dg/struct/wo_prof_local_var.c: Likewise. * gcc.dg/tree-prof/stringop-1.c: Adjust. * g++.dg/tree-ssa/pr31146.C: Likewise. * g++.dg/tree-ssa/copyprop-1.C: Likewise. * g++.dg/tree-ssa/pr33604.C: Likewise. * g++.dg/plugin/selfassign.c: Likewise. * gfortran.dg/array_memcpy_3.f90: Likewise. * gfortran.dg/array_memcpy_4.f90: Likewise. * c-c++-common/torture/pr42834.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161655 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index f9e4cf3cfa7..691bf6ca771 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1832,10 +1832,12 @@ likely_eliminated_by_inlining_p (gimple stmt) bool rhs_free = false; bool lhs_free = false; - while (handled_component_p (inner_lhs) || TREE_CODE (inner_lhs) == INDIRECT_REF) + while (handled_component_p (inner_lhs) + || TREE_CODE (inner_lhs) == MEM_REF) inner_lhs = TREE_OPERAND (inner_lhs, 0); while (handled_component_p (inner_rhs) - || TREE_CODE (inner_rhs) == ADDR_EXPR || TREE_CODE (inner_rhs) == INDIRECT_REF) + || TREE_CODE (inner_rhs) == ADDR_EXPR + || TREE_CODE (inner_rhs) == MEM_REF) inner_rhs = TREE_OPERAND (inner_rhs, 0); @@ -1855,7 +1857,8 @@ likely_eliminated_by_inlining_p (gimple stmt) || (TREE_CODE (inner_lhs) == SSA_NAME && TREE_CODE (SSA_NAME_VAR (inner_lhs)) == RESULT_DECL)) lhs_free = true; - if (lhs_free && (is_gimple_reg (rhs) || is_gimple_min_invariant (rhs))) + if (lhs_free + && (is_gimple_reg (rhs) || is_gimple_min_invariant (rhs))) rhs_free = true; if (lhs_free && rhs_free) return true; -- cgit v1.2.1 From 9f3c2a90c1dc7b4d659a55c34ca6da56fa5781c8 Mon Sep 17 00:00:00 2001 From: hubicka Date: Sat, 3 Jul 2010 19:33:14 +0000 Subject: * ipa-inline.c (update_edge_key): Break out from ... update_callers_keys): ... here; (update_callee_keys): Update only the edges from caller to callee. (update_all_calle_keys): Do what update_calle_keys did. (decide_inlining_of_small_functions): Avoid recomputing of all callees when badness increase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161778 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 100 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 77 insertions(+), 23 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 691bf6ca771..08f2ac3607d 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -661,6 +661,30 @@ cgraph_edge_badness (struct cgraph_edge *edge, bool dump) return badness; } +/* Recompute badness of EDGE and update its key in HEAP if needed. */ +static void +update_edge_key (fibheap_t heap, struct cgraph_edge *edge) +{ + int badness = cgraph_edge_badness (edge, false); + if (edge->aux) + { + fibnode_t n = (fibnode_t) edge->aux; + gcc_checking_assert (n->data == edge); + + /* fibheap_replace_key only decrease the keys. + When we increase the key we do not update heap + and instead re-insert the element once it becomes + a minium of heap. */ + if (badness < n->key) + { + fibheap_replace_key (heap, n, badness); + gcc_checking_assert (n->key == badness); + } + } + else + edge->aux = fibheap_insert (heap, badness, edge); +} + /* Recompute heap nodes for each of caller edge. */ static void @@ -678,8 +702,6 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, bitmap_set_bit (updated_nodes, node->uid); node->global.estimated_growth = INT_MIN; - if (!node->local.inlinable) - return; /* See if there is something to do. */ for (edge = node->callers; edge; edge = edge->next_caller) if (edge->inline_failed) @@ -702,28 +724,53 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, for (; edge; edge = edge->next_caller) if (edge->inline_failed) + update_edge_key (heap, edge); +} + +/* Recompute heap nodes for each uninlined call. + This is used when we know that edge badnesses are going only to increase + (we introduced new call site) and thus all we need is to insert newly + created edges into heap. */ + +static void +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; + + if (!e) + return; + while (true) + if (!e->inline_failed && e->callee->callees) + e = e->callee->callees; + else { - int badness = cgraph_edge_badness (edge, false); - if (edge->aux) + if (e->inline_failed + && e->callee->local.inlinable + && !bitmap_bit_p (updated_nodes, e->callee->uid)) { - fibnode_t n = (fibnode_t) edge->aux; - gcc_assert (n->data == edge); - if (n->key == badness) - continue; - - /* fibheap_replace_key only decrease the keys. - When we increase the key we do not update heap - and instead re-insert the element once it becomes - a minium of heap. */ - if (badness < n->key) + node->global.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); + else + /* Otherwise update just edge E. */ + update_edge_key (heap, e); + } + if (e->next_callee) + e = e->next_callee; + else + { + do { - fibheap_replace_key (heap, n, badness); - gcc_assert (n->key == badness); - continue; + if (e->caller == node) + return; + e = e->caller->callers; } + while (!e->next_callee); + e = e->next_callee; } - else - edge->aux = fibheap_insert (heap, badness, edge); } } @@ -731,8 +778,8 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, Walk recursively into all inline clones. */ static void -update_callee_keys (fibheap_t heap, struct cgraph_node *node, - bitmap updated_nodes) +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; @@ -1166,7 +1213,7 @@ cgraph_decide_inlining_of_small_functions (void) continue; if (flag_indirect_inlining) add_new_edges_to_heap (heap, new_indirect_edges); - update_callee_keys (heap, where, updated_nodes); + update_all_callee_keys (heap, where, updated_nodes); } else { @@ -1182,11 +1229,18 @@ cgraph_decide_inlining_of_small_functions (void) continue; } callee = edge->callee; + gcc_checking_assert (!callee->global.inlined_to); cgraph_mark_inline_edge (edge, true, &new_indirect_edges); if (flag_indirect_inlining) add_new_edges_to_heap (heap, new_indirect_edges); - update_callee_keys (heap, callee, updated_nodes); + /* We inlined last offline copy to the body. This might lead + to callees of function having fewer call sites and thus they + may need updating. */ + if (callee->global.inlined_to) + update_all_callee_keys (heap, callee, updated_nodes); + else + update_callee_keys (heap, edge->callee, updated_nodes); } where = edge->caller; if (where->global.inlined_to) -- cgit v1.2.1 From 73b465171affe4b630e14d526b13143300057d91 Mon Sep 17 00:00:00 2001 From: ramana Date: Thu, 8 Jul 2010 09:29:43 +0000 Subject: Fix PR44768 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161947 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 08f2ac3607d..201e04af277 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -2019,7 +2019,7 @@ compute_inline_parameters (struct cgraph_node *node) /* Estimate the stack size for the function. But not at -O0 because estimated_stack_frame_size is a quadratic problem. */ - self_stack_size = optimize ? estimated_stack_frame_size () : 0; + self_stack_size = optimize ? estimated_stack_frame_size (node->decl) : 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; -- cgit v1.2.1 From 69b18a8b03bc8cb57e9489f77da45dcab39c415c Mon Sep 17 00:00:00 2001 From: hubicka Date: Thu, 8 Jul 2010 16:46:49 +0000 Subject: * cgraph.c (cgraph_will_be_removed_from_program_if_no_direct_calls): New function. * cgraph.h (cgraph_will_be_removed_from_program_if_no_direct_calls): Declare. * ipa-cp.c (ipcp_estimate_growth): Use it. * ipa-inline.c (cgraph_estimate_growth, cgraph_decide_inlining): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161966 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 201e04af277..e65c6968ab4 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -389,7 +389,7 @@ cgraph_estimate_growth (struct cgraph_node *node) we decide to not inline for different reasons, but it is not big deal as in that case we will keep the body around, but we will also avoid some inlining. */ - if (cgraph_only_called_directly_p (node) + if (cgraph_will_be_removed_from_program_if_no_direct_calls (node) && !DECL_EXTERNAL (node->decl) && !self_recursive) growth -= node->global.size; @@ -1496,14 +1496,13 @@ cgraph_decide_inlining (void) if (node->callers && !node->callers->next_caller - && cgraph_only_called_directly_p (node) + && cgraph_will_be_removed_from_program_if_no_direct_calls (node) && node->local.inlinable && node->callers->inline_failed && node->callers->caller != node && node->callers->caller->global.inlined_to != node && !node->callers->call_stmt_cannot_inline_p - && !DECL_EXTERNAL (node->decl) - && !DECL_COMDAT (node->decl)) + && !DECL_EXTERNAL (node->decl)) { cgraph_inline_failed_t reason; old_size = overall_size; -- cgit v1.2.1 From 1767a056f10a2ccbc900df04d01193da73a3d272 Mon Sep 17 00:00:00 2001 From: froydnj Date: Thu, 15 Jul 2010 14:31:28 +0000 Subject: gcc/ * tree.h (DECL_CHAIN): Define. * alias.c: Carefully replace TREE_CHAIN with DECL_CHAIN. * c-decl.c: Likewise. * c-parser.c: Likewise. * c-typeck.c: Likewise. * cfgexpand.c: Likewise. * cgraph.c: Likewise. * cgraphunit.c: Likewise. * combine.c: Likewise. * config/alpha/alpha.c: Likewise. * config/arm/arm.c: Likewise. * config/frv/frv.c: Likewise. * config/i386/i386.c: Likewise. * config/i386/winnt-cxx.c: Likewise. * config/ia64/ia64.c: Likewise. * config/iq2000/iq2000.c: Likewise. * config/mep/mep.c: Likewise. * config/mips/mips.c: Likewise. * config/pa/som.h: Likewise. * config/rs6000/rs6000.c: Likewise. * config/s390/s390.c: Likewise. * config/sh/sh.c: Likewise. * config/sh/symbian-cxx.c: Likewise. * config/sparc/sparc.c: Likewise. * config/spu/spu.c: Likewise. * config/stormy16/stormy16.c: Likewise. * config/vxworks.c: Likewise. * config/xtensa/xtensa.c: Likewise. * coverage.c: Likewise. * dbxout.c: Likewise. * dwarf2out.c: Likewise. * emit-rtl.c: Likewise. * expr.c: Likewise. * function.c: Likewise. * gimple-low.c: Likewise. * gimple-pretty-print.c: Likewise. * gimplify.c: Likewise. * integrate.c: Likewise. * ipa-inline.c: Likewise. * ipa-prop.c: Likewise. * ipa-split.c: Likewise. * ipa-struct-reorg.c: Likewise. * ipa-type-escape.c: Likewise. * langhooks.c: Likewise. * lto-cgraph.c: Likewise. * omp-low.c: Likewise. * stor-layout.c: Likewise. * tree-cfg.c: Likewise. * tree-complex.c: Likewise. * tree-dfa.c: Likewise. * tree-dump.c: Likewise. * tree-inline.c: Likewise. * tree-mudflap.c: Likewise. * tree-nested.c: Likewise. * tree-object-size.c: Likewise. * tree-pretty-print.c: Likewise. * tree-sra.c: Likewise. * tree-ssa-live.c: Likewise. * tree-ssa-loop-niter.c: Likewise. * tree-ssa-math-opts.c: Likewise. * tree-ssa-reassoc.c: Likewise. * tree-ssa-sccvn.c: Likewise. * tree-ssa-structalias.c: Likewise. * tree-tailcall.c: Likewise. * tree-vrp.c: Likewise. * tree.c: Likewise. * var-tracking.c: Likewise. * varasm.c: Likewise. gcc/ada/ * gcc-interface/decl.c: Carefully replace TREE_CHAIN with DECL_CHAIN. * gcc-interface/trans.c: Likewise. * gcc-interface/utils.c: Likewise. * gcc-interface/utils2.c: Likewise. gcc/c-family/ * c-common.c: Carefully replace TREE_CHAIN with DECL_CHAIN. * c-format.c: Likewise. gcc/cp/ * cp-tree.h: Carefully replace TREE_CHAIN with DECL_CHAIN. * call.c: Likewise. * class.c: Likewise. * cp-gimplify.c: Likewise. * decl.c: Likewise. * decl2.c: Likewise. * init.c: Likewise. * mangle.c: Likewise. * name-lookup.c: Likewise. * optimize.c: Likewise. * parser.c: Likewise. * pt.c: Likewise. * rtti.c: Likewise. * search.c: Likewise. * semantics.c: Likewise. * typeck.c: Likewise. * typeck2.c: Likewise. gcc/fortran/ * f95-lang.c: Carefully replace TREE_CHAIN with DECL_CHAIN. * trans-common.c: Likewise. * trans-decl.c: Likewise. * trans-types.c: Likewise. * trans.c: Likewise. gcc/java/ * java-tree.h: Carefully replace TREE_CHAIN with DECL_CHAIN. * boehm.c: Likewise. * class.c: Likewise. * decl.c: Likewise. * expr.c: Likewise. * jcf-parse.c: Likewise. * typeck.c: Likewise. * verify-glue.c: Likewise. gcc/objc/ * objc-act.c: Carefully replace TREE_CHAIN with DECL_CHAIN. gcc/testsuite/ * g++.dg/plugin/attribute_plugin.c: Carefully replace TREE_CHAIN with DECL_CHAIN. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162223 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index e65c6968ab4..b9e68448953 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1987,7 +1987,7 @@ estimate_function_body_sizes (struct cgraph_node *node) time_inlining_benefit += cost; size_inlining_benefit += cost; } - for (arg = DECL_ARGUMENTS (node->decl); arg; arg = TREE_CHAIN (arg)) + for (arg = DECL_ARGUMENTS (node->decl); arg; arg = DECL_CHAIN (arg)) if (!VOID_TYPE_P (TREE_TYPE (arg))) { int cost = estimate_move_cost (TREE_TYPE (arg)); -- cgit v1.2.1 From 39882af6212143fe31be29ca1ea3513f9e629c1c Mon Sep 17 00:00:00 2001 From: jamborm Date: Fri, 23 Jul 2010 16:35:52 +0000 Subject: 2010-07-23 Martin Jambor PR tree-optimization/44915 * ipa-cp.c (cgraph_gate_cp): Also check that optimize is true. * ipa-inline.c (cgraph_mark_inline_edge): Likewise. (analyze_function): Likewise. * testsuite/g++.dg/torture/pr44915.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162469 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ipa-inline.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index b9e68448953..b5063bf8c22 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -334,7 +334,9 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, overall_size += new_size - old_size; ncalls_inlined++; - if (flag_indirect_inlining) + /* FIXME: We should remove the optimize check after we ensure we never run + IPA passes when not optimizng. */ + if (flag_indirect_inlining && optimize) return ipa_propagate_indirect_call_infos (curr, new_edges); else return false; @@ -2085,7 +2087,9 @@ analyze_function (struct cgraph_node *node) current_function_decl = node->decl; compute_inline_parameters (node); - if (flag_indirect_inlining) + /* FIXME: We should remove the optimize check after we ensure we never run + IPA passes when not optimizng. */ + if (flag_indirect_inlining && optimize) inline_indirect_intraprocedural_analysis (node); current_function_decl = NULL; -- cgit v1.2.1