aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-01-14 10:56:56 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-01-14 10:56:56 +0000
commit01b9bf0615e178e6c31f8d010cb8df9382b3c2d4 (patch)
tree1983359622b757b8b73b643d518e350d3ce588aa
parent61760b925ca4732c6eac2e1fe3582185aba826e7 (diff)
downloadgcc-01b9bf0615e178e6c31f8d010cb8df9382b3c2d4.zip
gcc-01b9bf0615e178e6c31f8d010cb8df9382b3c2d4.tar.gz
gcc-01b9bf0615e178e6c31f8d010cb8df9382b3c2d4.tar.bz2
inline_small_functions speedup
After inlining A into B, inline_small_functions updates the information for (most) callees and callers of the new B: update_callee_keys (&edge_heap, where, updated_nodes); [...] /* Our profitability metric can depend on local properties such as number of inlinable calls and size of the function body. After inlining these properties might change for the function we inlined into (since it's body size changed) and for the functions called by function we inlined (since number of it inlinable callers might change). */ update_caller_keys (&edge_heap, where, updated_nodes, NULL); These functions in turn call can_inline_edge_p for most of the associated edges: if (can_inline_edge_p (edge, false) && want_inline_small_function_p (edge, false)) update_edge_key (heap, edge); can_inline_edge_p indirectly calls estimate_calls_size_and_time on the caller node, which seems to recursively process all callee edges rooted at the node. It looks from this like the algorithm can be at least quadratic in the worst case. Maybe there's something we can do to make can_inline_edge_p cheaper, but since neither of these two calls is responsible for reporting an inline failure reason, it seems cheaper to test want_inline_small_function_p first, so that we don't calculate an estimate for something that we already know isn't a "small function". I think the only change needed to make that work is to check for CIF_FINAL_ERROR in want_inline_small_function_p; at the moment we rely on can_inline_edge_p to make that check. This cuts the time to build optabs.ii by over 4% with an --enable-checking=release compiler on x86_64-linux-gnu. I've seen more dramatic wins on aarch64-linux-gnu due to the NUM_POLY_INT_COEFFS==2 thing. The patch doesn't affect the output code. 2018-01-13 Richard Sandiford <richard.sandiford@linaro.org> gcc/ * ipa-inline.c (want_inline_small_function_p): Return false if inlining has already failed with CIF_FINAL_ERROR. (update_caller_keys): Call want_inline_small_function_p before can_inline_edge_p. (update_callee_keys): Likewise. From-SVN: r256658
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/ipa-inline.c14
2 files changed, 17 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dd1910d..abce2c8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2018-01-14 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * ipa-inline.c (want_inline_small_function_p): Return false if
+ inlining has already failed with CIF_FINAL_ERROR.
+ (update_caller_keys): Call want_inline_small_function_p before
+ can_inline_edge_p.
+ (update_callee_keys): Likewise.
+
2018-01-10 Kelvin Nilsen <kelvin@gcc.gnu.org>
* config/rs6000/rs6000-p8swap.c (rs6000_sum_of_two_registers_p):
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index eca8fe2..c3acfb29 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -706,7 +706,11 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
bool want_inline = true;
struct cgraph_node *callee = e->callee->ultimate_alias_target ();
- if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
+ /* Allow this function to be called before can_inline_edge_p,
+ since it's usually cheaper. */
+ if (cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
+ want_inline = false;
+ else if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
;
else if (!DECL_DECLARED_INLINE_P (callee->decl)
&& !opt_for_fn (e->caller->decl, flag_inline_small_functions))
@@ -1312,8 +1316,8 @@ update_caller_keys (edge_heap_t *heap, struct cgraph_node *node,
if (!check_inlinablity_for
|| check_inlinablity_for == edge)
{
- if (can_inline_edge_p (edge, false)
- && want_inline_small_function_p (edge, false))
+ if (want_inline_small_function_p (edge, false)
+ && can_inline_edge_p (edge, false))
update_edge_key (heap, edge);
else if (edge->aux)
{
@@ -1356,8 +1360,8 @@ update_callee_keys (edge_heap_t *heap, struct cgraph_node *node,
&& avail >= AVAIL_AVAILABLE
&& !bitmap_bit_p (updated_nodes, callee->uid))
{
- if (can_inline_edge_p (e, false)
- && want_inline_small_function_p (e, false))
+ if (want_inline_small_function_p (e, false)
+ && can_inline_edge_p (e, false))
update_edge_key (heap, e);
else if (e->aux)
{