diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-01-29 11:26:27 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-01-29 11:26:27 +0000 |
commit | 00efe249ebef940120e0cf4573e7489cb9ffddb8 (patch) | |
tree | 61daeccfe3e92ea241e835e5a130482b57c2267a /gcc/ipa-inline.c | |
parent | 24ac819df2d38ed62695faf0dfb6c3c1ba347089 (diff) | |
download | gcc-00efe249ebef940120e0cf4573e7489cb9ffddb8.tar.gz |
2010-01-29 Richard Guenther <rguenther@suse.de>
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
Diffstat (limited to 'gcc/ipa-inline.c')
-rw-r--r-- | gcc/ipa-inline.c | 185 |
1 files changed, 97 insertions, 88 deletions
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; } |