aboutsummaryrefslogtreecommitdiff
path: root/gcc/cgraphunit.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r--gcc/cgraphunit.c54
1 files changed, 46 insertions, 8 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 8fe98fb..05626cd 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -47,6 +47,8 @@ static void cgraph_expand_function (struct cgraph_node *);
static tree record_call_1 (tree *, int *, void *);
static void cgraph_mark_local_functions (void);
static void cgraph_optimize_function (struct cgraph_node *);
+static bool cgraph_default_inline_p (struct cgraph_node *n);
+static void cgraph_analyze_function (struct cgraph_node *node);
/* Statistics we collect about inlining algorithm. */
static int ncalls_inlined;
@@ -69,6 +71,8 @@ cgraph_finalize_function (tree decl, tree body ATTRIBUTE_UNUSED)
if needed. */
if (node->needed)
cgraph_mark_needed_node (node, 0);
+ if (!flag_unit_at_a_time)
+ cgraph_analyze_function (node);
if (/* Externally visible functions must be output. The exception are
COMDAT functions that must be output only when they are needed.
Similarly are handled deferred functions and
@@ -85,9 +89,28 @@ cgraph_finalize_function (tree decl, tree body ATTRIBUTE_UNUSED)
|| (DECL_ASSEMBLER_NAME_SET_P (decl)
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
|| lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
- {
- cgraph_mark_needed_node (node, 1);
- }
+ cgraph_mark_needed_node (node, 1);
+ /* When not doing unit-at-a-time deffer only inline functions. */
+ else if (!flag_unit_at_a_time
+ && !DECL_EXTERNAL (decl)
+ && !node->origin
+ && (!DECL_INLINE (decl)
+ || (!node->local.disregard_inline_limits
+ /* When declared inline, deffer even the uninlinable functions.
+ This allows them to be elliminated when unused. */
+ && !DECL_DECLARED_INLINE_P (decl)
+ && (node->local.inlinable
+ || !cgraph_default_inline_p (node)))))
+ cgraph_mark_needed_node (node, 1);
+
+ if (!flag_unit_at_a_time)
+ while (cgraph_nodes_queue)
+ {
+ struct cgraph_node *n = cgraph_nodes_queue;
+ cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
+ if (!n->origin)
+ cgraph_expand_function (n);
+ }
(*debug_hooks->deferred_inline_function) (decl);
}
@@ -185,6 +208,9 @@ cgraph_finalize_compilation_unit (void)
{
struct cgraph_node *node;
+ if (!flag_unit_at_a_time)
+ return;
+
cgraph_varpool_assemble_pending_decls ();
if (!quiet_flag)
fprintf (stderr, "\nAnalyzing compilation unit\n");
@@ -320,11 +346,21 @@ cgraph_expand_function (struct cgraph_node *node)
via lang_expand_decl_stmt. */
(*lang_hooks.callgraph.expand_function) (decl);
- for (e = node->callers; e; e = e->next_caller)
- if (e->inline_call)
- break;
- if (!e)
- DECL_SAVED_TREE (decl) = NULL;
+ if (!flag_unit_at_a_time)
+ {
+ if (!node->local.inlinable
+ || (!node->local.disregard_inline_limits
+ && !cgraph_default_inline_p (node)))
+ DECL_SAVED_TREE (node->decl) = NULL;
+ }
+ else
+ {
+ for (e = node->callers; e; e = e->next_caller)
+ if (e->inline_call)
+ break;
+ if (!e)
+ DECL_SAVED_TREE (decl) = NULL;
+ }
current_function_decl = NULL;
}
@@ -1090,6 +1126,8 @@ cgraph_mark_local_functions (void)
void
cgraph_optimize (void)
{
+ if (!flag_unit_at_a_time)
+ return;
timevar_push (TV_CGRAPHOPT);
if (!quiet_flag)
fprintf (stderr, "Performing intraprocedural optimizations\n");