diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/ipa-inline.c | 77 |
2 files changed, 67 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a981b72..61b0432 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2010-05-27 Jan Hubicka <jh@suse.cz> + + * 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. + 2010-05-27 Steven Bosscher <steven@gcc.gnu.org> * Makefile.in (ALL_CFLAGS): Add file-specific CFLAGS. diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index d5f48bd..aaae639 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) { |