aboutsummaryrefslogtreecommitdiff
path: root/gcc/cgraphunit.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2003-10-20 23:46:55 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2003-10-20 21:46:55 +0000
commitd4d1ebc191e5c1d00266d9c0207c5dde69f5e216 (patch)
treee0577f027de65a595f0d08d2ce877c7af9b5a347 /gcc/cgraphunit.c
parentce01559bb70b9d2af4bb3e91866167440c5a66f8 (diff)
downloadgcc-d4d1ebc191e5c1d00266d9c0207c5dde69f5e216.zip
gcc-d4d1ebc191e5c1d00266d9c0207c5dde69f5e216.tar.gz
gcc-d4d1ebc191e5c1d00266d9c0207c5dde69f5e216.tar.bz2
toplev.c (rest_of_compilation): Fix webizer pass ordering.
* toplev.c (rest_of_compilation): Fix webizer pass ordering. * cgraphunit.c (decide_is_function_needed): Fix test dealing with functions implicitly made inline. * cgraphunit.c (cgraph_decide_inlining_incrementally): New function. (cgraph_finalize_function): Use it. (cgraph_mark_inline): Allow incrmental decisions * invoke.texi (max-inline-slope, min-inline-insns): Kill. * params.def (PARAM_MAX_INLINE_SLOPE, PARAM_MIN_INLINE_INSNS): Kill. * tree-inline.c (limits_allow_inlining): Kill. (expand_call_inline): Always use unit-at-a-time path. * decl.c (start_cleanup_fn): Set DECL_DECLARED_INLINE_P to deffer the expansion. * testsuite/g++.dg/opt/inline4.C: Do not use min-inline-insns parameter. * testsuite/gcc.dg/inline-2.c: Likewise. From-SVN: r72721
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r--gcc/cgraphunit.c62
1 files changed, 60 insertions, 2 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 7b85e77..c20367d 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -49,6 +49,7 @@ 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);
+static void cgraph_decide_inlining_incrementally (struct cgraph_node *);
/* Statistics we collect about inlining algorithm. */
static int ncalls_inlined;
@@ -114,7 +115,7 @@ decide_is_function_needed (struct cgraph_node *node, tree decl)
/* When declared inline, defer even the uninlinable functions.
This allows them to be eliminated when unused. */
&& !DECL_DECLARED_INLINE_P (decl)
- && (node->local.inlinable || !cgraph_default_inline_p (node))))
+ && (!node->local.inlinable || !cgraph_default_inline_p (node))))
return true;
return false;
@@ -206,7 +207,10 @@ cgraph_finalize_function (tree decl, bool nested)
/* If not unit at a time, then we need to create the call graph
now, so that called functions can be queued and emitted now. */
if (!flag_unit_at_a_time)
- cgraph_analyze_function (node);
+ {
+ cgraph_analyze_function (node);
+ cgraph_decide_inlining_incrementally (node);
+ }
if (decide_is_function_needed (node, decl))
cgraph_mark_needed_node (node);
@@ -852,6 +856,7 @@ cgraph_mark_inline (struct cgraph_node *to, struct cgraph_node *what,
to->global.insns = new_insns;
if (!called && !what->needed && !what->origin
+ && flag_unit_at_a_time
&& !DECL_EXTERNAL (what->decl))
{
if (!what->global.will_be_output)
@@ -1221,6 +1226,59 @@ cgraph_decide_inlining (void)
free (inlined_callees);
}
+/* Decide on the inlining. We do so in the topological order to avoid
+ expenses on updating datastructures. */
+
+static void
+cgraph_decide_inlining_incrementally (struct cgraph_node *node)
+{
+ struct cgraph_edge *e;
+ struct cgraph_node **inlined =
+ xmalloc (sizeof (struct cgraph_node *) * cgraph_n_nodes);
+ struct cgraph_node **inlined_callees =
+ xmalloc (sizeof (struct cgraph_node *) * cgraph_n_nodes);
+ int ninlined;
+ int ninlined_callees;
+ int y;
+
+ ninlined = cgraph_inlined_into (node, inlined);
+
+ /* First of all look for always inline functions. */
+ for (e = node->callees; e; e = e->next_callee)
+ if (e->callee->local.disregard_inline_limits && !e->callee->output
+ && e->callee != node && !e->inline_call)
+ {
+ ninlined_callees = cgraph_inlined_callees (e->callee, inlined_callees);
+ cgraph_mark_inline (node, e->callee, inlined, ninlined,
+ inlined_callees, ninlined_callees);
+ for (y = 0; y < ninlined_callees; y++)
+ inlined_callees[y]->output = 0, node->aux = 0;
+ }
+
+ /* Now do the automatic inlining. */
+ for (e = node->callees; e; e = e->next_callee)
+ if (e->callee->local.inlinable && !e->callee->output
+ && e->callee != node && !e->inline_call
+ && cgraph_default_inline_p (e->callee)
+ && cgraph_check_inline_limits (node, e->callee, inlined,
+ ninlined))
+ {
+ ninlined_callees = cgraph_inlined_callees (e->callee, inlined_callees);
+ cgraph_mark_inline (node, e->callee, inlined, ninlined,
+ inlined_callees, ninlined_callees);
+ for (y = 0; y < ninlined_callees; y++)
+ inlined_callees[y]->output = 0, node->aux = 0;
+ }
+
+ /* Clear the flags set by cgraph_inlined_into. */
+ for (y = 0; y < ninlined; y++)
+ inlined[y]->output = 0, node->aux = 0;
+
+ free (inlined);
+ free (inlined_callees);
+}
+
+
/* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
bool