aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2001-10-05 04:20:27 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2001-10-05 04:20:27 +0000
commit4838c5ee553f062d75d0a6288a025e98600de97c (patch)
tree8ce05ef7518fd1359d3ae5d044511179f1ea1c8f /gcc/tree-inline.c
parent8d5463d486fe257414a840e204531a8e4405a9a6 (diff)
downloadgcc-4838c5ee553f062d75d0a6288a025e98600de97c.zip
gcc-4838c5ee553f062d75d0a6288a025e98600de97c.tar.gz
gcc-4838c5ee553f062d75d0a6288a025e98600de97c.tar.bz2
Makefile.in (c-decl.o): Depend on tree-inline.h.
* Makefile.in (c-decl.o): Depend on tree-inline.h. (c-lang.o): Likewise, as well as insn-config.h and integrate.h. * c-decl.c: Include tree-inline.h. (c_expand_body): Call optimize_inline_calls. Determine whether a function is inlinable upfront, and only clear DECL_SAVED_TREE, DECL_INITIAL and DECL_ARGUMENTS if it isn't. * c-lang.c: Include tree-inline.h, insn-config.h and integrate.h. (c_disregard_inline_limits): New function. (inline_forbidden_p, c_cannot_inline_tree_fn): Likewise. (c_post_options): Enable tree inlining if inlining is enabled. Don't inline trees when instrumenting functions. (c_init): Initialize lang_disregard_inline_limits and lang_cannot_inline_tree_fn. * tree-inline.c (initialize_inlined_parameters): Handle calls with fewer arguments than declared parameters, and fewer parameters than passed arguments. Don't assume value is a DECL. (declare_return_variable): Convert return value back to the original type, if it was promoted. (tree_inlinable_function_p): New function. (inlinable_function_p): Don't look at DECL_INLINE if we're inlining all functions. Make it work with a NULL id. Re-check DECL_UNINLINABLE after language-specific checks. (varargs_function_p): Move back to cp/tree.c. * tree-inline.h (tree_inlinable_function_p): Declare it. (varargs_function_p): Removed declaration. * integrate.h (function_attribute_inlinable_p): Declare it. * integrate.c (function_attribute_inlinable_p): Export it. (save_for_inline): Don't bother to prepare argvec when not inlining. * cse.c (check_for_label_ref): Don't check deleted labels. From-SVN: r46025
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c70
1 files changed, 53 insertions, 17 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index e24d39b..310ff88 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -483,23 +483,25 @@ initialize_inlined_parameters (id, args, fn)
/* Loop through the parameter declarations, replacing each with an
equivalent VAR_DECL, appropriately initialized. */
- for (p = parms, a = args; p; a = TREE_CHAIN (a), p = TREE_CHAIN (p))
+ for (p = parms, a = args; p;
+ a = a ? TREE_CHAIN (a) : a, p = TREE_CHAIN (p))
{
tree init_stmt;
tree var;
tree value;
/* Find the initializer. */
- value = TREE_VALUE (a);
+ value = a ? TREE_VALUE (a) : NULL_TREE;
+
/* If the parameter is never assigned to, we may not need to
create a new variable here at all. Instead, we may be able
to just use the argument value. */
if (TREE_READONLY (p)
&& !TREE_ADDRESSABLE (p)
- && !TREE_SIDE_EFFECTS (value))
+ && value && !TREE_SIDE_EFFECTS (value))
{
/* Simplify the value, if possible. */
- value = fold (decl_constant_value (value));
+ value = fold (DECL_P (value) ? decl_constant_value (value) : value);
/* We can't risk substituting complex expressions. They
might contain variables that will be assigned to later.
@@ -567,6 +569,23 @@ initialize_inlined_parameters (id, args, fn)
}
}
+ /* Evaluate trailing arguments. */
+ for (; a; a = TREE_CHAIN (a))
+ {
+ tree init_stmt;
+ tree value;
+
+ /* Find the initializer. */
+ value = a ? TREE_VALUE (a) : NULL_TREE;
+
+ if (! value || ! TREE_SIDE_EFFECTS (value))
+ continue;
+
+ init_stmt = build_stmt (EXPR_STMT, value);
+ TREE_CHAIN (init_stmt) = init_stmts;
+ init_stmts = init_stmt;
+ }
+
/* The initialization statements have been built up in reverse
order. Straighten them out now. */
return nreverse (init_stmts);
@@ -606,9 +625,15 @@ declare_return_variable (id, use_stmt)
(splay_tree_key) result,
(splay_tree_value) var);
- /* Build the USE_STMT. */
- *use_stmt = build_stmt (EXPR_STMT, var);
-
+ /* Build the USE_STMT. If the return type of the function was
+ promoted, convert it back to the expected type. */
+ if (TREE_TYPE (var) == TREE_TYPE (TREE_TYPE (fn)))
+ *use_stmt = build_stmt (EXPR_STMT, var);
+ else
+ *use_stmt = build_stmt (EXPR_STMT,
+ build1 (NOP_EXPR, TREE_TYPE (TREE_TYPE (fn)),
+ var));
+
/* Build the declaration statement if FN does not return an
aggregate. */
if (need_return_decl)
@@ -619,7 +644,18 @@ declare_return_variable (id, use_stmt)
return NULL_TREE;
}
-/* Returns non-zero if FN is a function that can be inlined. */
+/* Returns non-zero if a function can be inlined as a tree. */
+
+int
+tree_inlinable_function_p (fn)
+ tree fn;
+{
+ return inlinable_function_p (fn, NULL);
+}
+
+/* Returns non-zero if FN is a function that can be inlined into the
+ inlining context ID_. If ID_ is NULL, check whether the function
+ can be inlined at all. */
static int
inlinable_function_p (fn, id)
@@ -637,11 +673,11 @@ inlinable_function_p (fn, id)
inlinable = 0;
/* If we're not inlining things, then nothing is inlinable. */
- if (!flag_inline_trees)
+ if (! flag_inline_trees)
;
- /* If the function was not declared `inline', then we don't inline
- it. */
- else if (!DECL_INLINE (fn))
+ /* If we're not inlining all functions and the function was not
+ declared `inline', we don't inline it. */
+ else if (flag_inline_trees < 2 && ! DECL_INLINE (fn))
;
/* We can't inline functions that are too big. Only allow a single
function to eat up half of our budget. Make special allowance
@@ -657,14 +693,14 @@ inlinable_function_p (fn, id)
inlinable = 1;
/* Squirrel away the result so that we don't have to check again. */
- DECL_UNINLINABLE (fn) = !inlinable;
+ DECL_UNINLINABLE (fn) = ! inlinable;
/* Even if this function is not itself too big to inline, it might
be that we've done so much inlining already that we don't want to
risk too much inlining any more and thus halve the acceptable
size. */
if (! LANG_DISREGARD_INLINE_LIMITS (fn)
- && ((DECL_NUM_STMTS (fn) + id->inlined_stmts) * INSNS_PER_STMT
+ && ((DECL_NUM_STMTS (fn) + (id ? id->inlined_stmts : 0)) * INSNS_PER_STMT
> MAX_INLINE_INSNS)
&& DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS / 4)
inlinable = 0;
@@ -674,7 +710,7 @@ inlinable_function_p (fn, id)
/* If we don't have the function body available, we can't inline
it. */
- if (!DECL_SAVED_TREE (fn))
+ if (! DECL_SAVED_TREE (fn))
inlinable = 0;
/* Check again, language hooks may have modified it. */
@@ -683,7 +719,7 @@ inlinable_function_p (fn, id)
/* Don't do recursive inlining, either. We don't record this in
DECL_UNINLINABLE; we may be able to inline this function later. */
- if (inlinable)
+ if (id)
{
size_t i;
@@ -691,7 +727,7 @@ inlinable_function_p (fn, id)
if (VARRAY_TREE (id->fns, i) == fn)
return 0;
- if (inlinable && DECL_INLINED_FNS (fn))
+ if (DECL_INLINED_FNS (fn))
{
int j;
tree inlined_fns = DECL_INLINED_FNS (fn);