summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/cgraphunit.c62
-rw-r--r--gcc/config/i386/i386.md2
-rw-r--r--gcc/coverage.h1
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/decl.c2
-rw-r--r--gcc/doc/invoke.texi16
-rw-r--r--gcc/flags.h4
-rw-r--r--gcc/opts.c7
-rw-r--r--gcc/params.def26
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/opt/inline4.C2
-rw-r--r--gcc/testsuite/gcc.dg/inline-2.c3
-rw-r--r--gcc/toplev.c6
-rw-r--r--gcc/tree-inline.c101
15 files changed, 103 insertions, 155 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1e0075cd680..2d59559816a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2003-10-20 Jan Hubicka <jh@suse.cz>
+
+ * 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.
+
2003-10-20 Zack Weinberg <zack@codesourcery.com>
* fixinc/inclhack.def (hpux11_snprintf): New edit.
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 7b85e77c226..c20367d1d00 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
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 863dce5a4db..835480d3a47 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -16045,7 +16045,7 @@
(unspec:SF [(match_dup 2)
(match_operand:SF 1 "register_operand" "")]
UNSPEC_FPATAN))
- (clobber (match_dup 1))])]
+ (clobber (match_scratch:SF 3 ""))])]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
diff --git a/gcc/coverage.h b/gcc/coverage.h
index 5ae27f805f2..9756bbaafa8 100644
--- a/gcc/coverage.h
+++ b/gcc/coverage.h
@@ -25,6 +25,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
extern void coverage_init (const char *);
extern void coverage_finish (void);
+extern void coverage_read_counts_file (void);
/* Complete the coverage information for the current function. Once
per function. */
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1acee5ff415..c2cb189b8b2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2003-10-20 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (start_cleanup_fn): Set DECL_DECLARED_INLINE_P to deffer
+ the expansion.
+
2003-10-20 Mark Mitchell <mark@codesourcery.com>
* Make-lang.in (c++.install-info): Remove.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 8ca69d13989..0f1170c842e 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5073,6 +5073,8 @@ start_cleanup_fn (void)
it is only called via a function pointer, but we avoid unnecessary
emissions this way. */
DECL_INLINE (fndecl) = 1;
+ DECL_DECLARED_INLINE_P (fndecl) = 1;
+ DECL_INTERFACE_KNOWN (fndecl) = 1;
/* Build the parameter. */
if (flag_use_cxa_atexit)
{
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4dbe1ee1c61..52bdd6d1362 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -4784,22 +4784,6 @@ larger binaries. Very high values are not advisable, as too large
binaries may adversely affect runtime performance.
The default value is 200.
-@item max-inline-slope
-After exceeding the maximum number of inlined instructions by repeated
-inlining, a linear function is used to decrease the allowable size
-for single functions. The slope of that function is the negative
-reciprocal of the number specified here.
-This parameter is ignored when @option{-funit-at-a-time} is used.
-The default value is 32.
-
-@item min-inline-insns
-The repeated inlining is throttled more and more by the linear function
-after exceeding the limit. To avoid too much throttling, a minimum for
-this function is specified here to allow repeated inlining for very small
-functions even when a lot of repeated inlining already has been done.
-This parameter is ignored when @option{-funit-at-a-time} is used.
-The default value is 10.
-
@item large-function-insns
The limit specifying really large functions. For functions greater than this
limit inlining is constrained by @option{--param large-function-growth}.
diff --git a/gcc/flags.h b/gcc/flags.h
index 5b6f7283b6c..c2b2fad8f17 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -719,6 +719,10 @@ extern int flag_unit_at_a_time;
extern int flag_web;
+/* Nonzero means that we defer emitting functions until they are actually
+ used. */
+extern int flag_remove_unreachable_functions;
+
/* A string that's used when a random name is required. NULL means
to make it really random. */
diff --git a/gcc/opts.c b/gcc/opts.c
index 6439e26670f..dafd37104b4 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1061,13 +1061,6 @@ common_handle_option (size_t scode, const char *arg,
set_param_value ("max-inline-insns-single", value / 2);
set_param_value ("max-inline-insns-auto", value / 2);
set_param_value ("max-inline-insns-rtl", value);
- if (value / 4 < MIN_INLINE_INSNS)
- {
- if (value / 4 > 10)
- set_param_value ("min-inline-insns", value / 4);
- else
- set_param_value ("min-inline-insns", 10);
- }
break;
case OPT_finstrument_functions:
diff --git a/gcc/params.def b/gcc/params.def
index c5dfca864d5..b08603b1f29 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -84,32 +84,6 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS,
"The maximum number of instructions by repeated inlining before gcc starts to throttle inlining",
200)
-/* After the repeated inline limit has been exceeded (see
- "max-inline-insns" parameter), a linear function is used to
- decrease the size of single functions eligible for inlining.
- The slope of this linear function is given the negative
- reciprocal value (-1/x) of this parameter.
- The default value is 32.
- This linear function is used until it falls below a minimum
- value specified by the "min-inline-insns" parameter. */
-DEFPARAM (PARAM_MAX_INLINE_SLOPE,
- "max-inline-slope",
- "The slope of the linear function throttling inlining after the recursive inlining limit has been reached is given by the negative reciprocal value of this parameter",
- 32)
-
-/* When gcc has inlined so many instructions (by repeated
- inlining) that the throttling limits the inlining very much,
- inlining for very small functions is still desirable to
- achieve good runtime performance. The size of single functions
- (measured in gcc instructions) which will still be eligible for
- inlining then is given by this parameter. It defaults to 130.
- Only much later (after exceeding 128 times the recursive limit)
- inlining is cut down completely. */
-DEFPARAM (PARAM_MIN_INLINE_INSNS,
- "min-inline-insns",
- "The number of instructions in a single functions still eligible to inlining after a lot recursive inlining",
- 10)
-
/* For languages that (still) use the RTL inliner, we can specify
limits for the RTL inliner separately.
The parameter here defines the maximum number of RTL instructions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0f005e8bffc..20bac3351bd 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2003-10-20 Jan Hubicka <jh@suse.cz>
+
+ * testsuite/g++.dg/opt/inline4.C: Do not use min-inline-insns
+ parameter.
+ * testsuite/gcc.dg/inline-2.c: Likewise.
+
2003-10-20 Phil Edwards <phil@codesourcery.com>
* gcc.dg/20021014-1.c: XFAIL for *-*-windiss targets.
diff --git a/gcc/testsuite/g++.dg/opt/inline4.C b/gcc/testsuite/g++.dg/opt/inline4.C
index 2d3eb379648..1db4fe1860b 100644
--- a/gcc/testsuite/g++.dg/opt/inline4.C
+++ b/gcc/testsuite/g++.dg/opt/inline4.C
@@ -1,4 +1,4 @@
-// { dg-options "-O2 -ftemplate-depth-20000 --param min-inline-insns=100 --param max-inline-insns=3" }
+// { dg-options "-O2 -ftemplate-depth-20000" }
template <int I>
inline void g() { g<I-1>(); return; }
diff --git a/gcc/testsuite/gcc.dg/inline-2.c b/gcc/testsuite/gcc.dg/inline-2.c
index 28991bccb9f..80e7848aca2 100644
--- a/gcc/testsuite/gcc.dg/inline-2.c
+++ b/gcc/testsuite/gcc.dg/inline-2.c
@@ -11,7 +11,8 @@ static int foo(void)
int bar(void)
{
- return foo() + 1;
+ /* Call twice to avoid bypassing the limit for functions called once. */
+ return foo() + foo() + 1;
}
/* { dg-final { scan-assembler-not "jsr" { target alpha*-*-* } } } */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 151f6c65280..a393c52003e 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -3364,9 +3364,6 @@ rest_of_compilation (tree decl)
rest_of_handle_cfg (decl, insns);
- if (flag_web)
- rest_of_handle_web (decl, insns);
-
if (optimize > 0
|| profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
@@ -3394,6 +3391,9 @@ rest_of_compilation (tree decl)
|| flag_unroll_loops))
rest_of_handle_loop2 (decl, insns);
+ if (flag_web)
+ rest_of_handle_web (decl, insns);
+
if (flag_rerun_cse_after_loop)
rest_of_handle_cse2 (decl, insns);
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 375a5702291..b827dfc1c29 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -119,7 +119,6 @@ static tree copy_body (inline_data *);
static tree expand_call_inline (tree *, int *, void *);
static void expand_calls_inline (tree *, inline_data *);
static bool inlinable_function_p (tree);
-static int limits_allow_inlining (tree, inline_data *);
static tree remap_decl (tree, inline_data *);
static tree remap_type (tree, inline_data *);
#ifndef INLINER_FOR_JAVA
@@ -1219,97 +1218,6 @@ inlinable_function_p (tree fn)
return inlinable;
}
-/* We can't inline functions that are too big. Only allow a single
- function to be of MAX_INLINE_INSNS_SINGLE size. Make special
- allowance for extern inline functions, though.
-
- Return nonzero if the function FN can be inlined into the inlining
- context ID. */
-
-static int
-limits_allow_inlining (tree fn, inline_data *id)
-{
- int estimated_insns = 0;
- size_t i;
-
- /* Don't even bother if the function is not inlinable. */
- if (!inlinable_function_p (fn))
- return 0;
-
- /* Investigate the size of the function. Return at once
- if the function body size is too large. */
- if (!(*lang_hooks.tree_inlining.disregard_inline_limits) (fn))
- {
- int currfn_max_inline_insns;
-
- /* If we haven't already done so, get an estimate of the number of
- instructions that will be produces when expanding this function. */
- if (!DECL_ESTIMATED_INSNS (fn))
- DECL_ESTIMATED_INSNS (fn)
- = (*lang_hooks.tree_inlining.estimate_num_insns) (fn);
- estimated_insns = DECL_ESTIMATED_INSNS (fn);
-
- /* We may be here either because fn is declared inline or because
- we use -finline-functions. For the second case, we are more
- restrictive.
-
- FIXME: -finline-functions should imply -funit-at-a-time, it's
- about equally expensive but unit-at-a-time produces
- better code. */
- currfn_max_inline_insns = DECL_DECLARED_INLINE_P (fn) ?
- MAX_INLINE_INSNS_SINGLE : MAX_INLINE_INSNS_AUTO;
-
- /* If the function is too big to be inlined, adieu. */
- if (estimated_insns > currfn_max_inline_insns)
- return 0;
-
- /* We now know that we don't disregard the inlining limits and that
- we basically should be able to inline this function.
- We always allow inlining functions if we estimate that they are
- smaller than MIN_INLINE_INSNS. Otherwise, investigate further. */
- if (estimated_insns > MIN_INLINE_INSNS)
- {
- int sum_insns = (id ? id->inlined_insns : 0) + estimated_insns;
-
- /* In the extreme case that we have exceeded the recursive inlining
- limit by a huge factor (128), we just say no.
-
- FIXME: Should not happen in real life, but people have reported
- that it actually does!? */
- if (sum_insns > MAX_INLINE_INSNS * 128)
- return 0;
-
- /* If we did not hit the extreme limit, we use a linear function
- with slope -1/MAX_INLINE_SLOPE to exceedingly decrease the
- allowable size. */
- else if (sum_insns > MAX_INLINE_INSNS)
- {
- if (estimated_insns > currfn_max_inline_insns
- - (sum_insns - MAX_INLINE_INSNS) / MAX_INLINE_SLOPE)
- return 0;
- }
- }
- }
-
- /* Don't allow recursive inlining. */
- for (i = 0; i < VARRAY_ACTIVE_SIZE (id->fns); ++i)
- if (VARRAY_TREE (id->fns, i) == fn)
- return 0;
-
- if (DECL_INLINED_FNS (fn))
- {
- int j;
- tree inlined_fns = DECL_INLINED_FNS (fn);
-
- for (j = 0; j < TREE_VEC_LENGTH (inlined_fns); ++j)
- if (TREE_VEC_ELT (inlined_fns, j) == VARRAY_TREE (id->fns, 0))
- return 0;
- }
-
- /* Go ahead, this function can be inlined. */
- return 1;
-}
-
/* If *TP is a CALL_EXPR, replace it with its inline expansion. */
static tree
@@ -1396,8 +1304,7 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE;
/* Turn forward declarations into real ones. */
- if (flag_unit_at_a_time)
- fn = cgraph_node (fn)->decl;
+ fn = cgraph_node (fn)->decl;
/* If fn is a declaration of a function in a nested scope that was
globally declared inline, we don't set its DECL_INITIAL.
@@ -1413,9 +1320,7 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
/* Don't try to inline functions that are not well-suited to
inlining. */
- if ((flag_unit_at_a_time
- && (!DECL_SAVED_TREE (fn) || !cgraph_inline_p (id->current_decl, fn)))
- || (!flag_unit_at_a_time && !limits_allow_inlining (fn, id)))
+ if (!DECL_SAVED_TREE (fn) || !cgraph_inline_p (id->current_decl, fn))
{
if (warn_inline && DECL_INLINE (fn) && DECL_DECLARED_INLINE_P (fn)
&& !DECL_IN_SYSTEM_HEADER (fn))
@@ -1653,7 +1558,7 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
id->inlined_insns += DECL_ESTIMATED_INSNS (fn) - 1;
/* Update callgraph if needed. */
- if (id->decl && flag_unit_at_a_time)
+ if (id->decl)
{
cgraph_remove_call (id->decl, fn);
cgraph_create_edges (id->decl, *inlined_body);