diff options
Diffstat (limited to 'gcc/ipa-inline.c')
-rw-r--r-- | gcc/ipa-inline.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 35fce6d4a1a..6eede0d35fc 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -253,7 +253,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report) gcc_assert (e->inline_failed); - if (!callee || !callee->analyzed) + if (!callee || !callee->symbol.definition) { e->inline_failed = CIF_BODY_NOT_AVAILABLE; inlinable = false; @@ -1100,8 +1100,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, int i; struct ipa_ref *ref; - if ((!node->alias && !inline_summary (node)->inlinable) - || cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE + if ((!node->symbol.alias && !inline_summary (node)->inlinable) || node->global.inlined_to) return; if (!bitmap_set_bit (updated_nodes, node->uid)) @@ -1162,7 +1161,7 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node, if (e->inline_failed && (callee = cgraph_function_or_thunk_node (e->callee, &avail)) && inline_summary (callee)->inlinable - && cgraph_function_body_availability (callee) >= AVAIL_AVAILABLE + && avail >= AVAIL_AVAILABLE && !bitmap_bit_p (updated_nodes, callee->uid)) { if (can_inline_edge_p (e, false) @@ -1315,7 +1314,7 @@ recursive_inlining (struct cgraph_edge *edge, /* We need original clone to copy around. */ master_clone = cgraph_clone_node (node, node->symbol.decl, node->count, CGRAPH_FREQ_BASE, - false, vNULL, true); + false, vNULL, true, NULL); for (e = master_clone->callees; e; e = e->next_callee) if (!e->inline_failed) clone_inlined_nodes (e, true, false, NULL); @@ -1795,6 +1794,9 @@ ipa_inline (void) } inline_small_functions (); + + /* Do first after-inlining removal. We want to remove all "stale" extern inline + functions and virtual functions so we really know what is called once. */ symtab_remove_unreachable_nodes (false, dump_file); free (order); @@ -1909,7 +1911,15 @@ inline_always_inline_functions (struct cgraph_node *node) } if (!can_early_inline_edge_p (e)) - continue; + { + /* Set inlined to true if the callee is marked "always_inline" but + is not inlinable. This will allow flagging an error later in + expand_call_inline in tree-inline.c. */ + if (lookup_attribute ("always_inline", + DECL_ATTRIBUTES (callee->symbol.decl)) != NULL) + inlined = true; + continue; + } if (dump_file) fprintf (dump_file, " Inlining %s into %s (always_inline).\n", @@ -2052,8 +2062,8 @@ early_inliner (void) es->call_stmt_time = estimate_num_insns (edge->call_stmt, &eni_time_weights); if (edge->callee->symbol.decl - && !gimple_check_call_matching_types (edge->call_stmt, - edge->callee->symbol.decl)) + && !gimple_check_call_matching_types ( + edge->call_stmt, edge->callee->symbol.decl, false)) edge->call_stmt_cannot_inline_p = true; } timevar_pop (TV_INTEGRATION); |