Commit 18d13f34 by Jan Hubicka Committed by Jan Hubicka

inline-3.c: New test.


	* gcc.dg/inline-3.c: New test.

	* c-decl.c: (finish_function): Update call of tree_inlinable_function_p.
	* cgraph.h: (cgraph_local_info): Add can_inline_once
	(cgraph_global_info): Add inline_once.
	(cgraph_node): Add previous.
	(cgraph_remove_node): New.
	* cgraphunit.c (cgraph_mark_functions_to_inline_once): New static
	function.
	(cgraph_optimize): Call it.
	(cgraph_finalize_function):  Set inlinable flags.
	(cgraph_finalize_compilation_unit):  Actually remove the reclaimed nodes.
	(cgraph_mark_functions_to_output):  Use new inlining heuristics flags.
	(cgraph_expand_function): Likewise.
	* cgraph.c
	(cgraph_node): Put nodes into doubly linked chain.
	(cgraph_remove_node): New function.
	* flags.h (flag_inline_functions_called_once): Declare.
	* tree-inline.c: Include cgraph.h
	(inlinable_functions_p): Add extra argument to bypass limits.
	(expand_call_inline):  Obey cgraph flag.
	* tree-inline.h (tree_inlinable_function_p): Update prototype.

From-SVN: r63983
parent 4a07c08a
Sat Mar 8 14:13:35 CET 2003 Jan Hubicka <jh@suse.cz>
* c-decl.c: (finish_function): Update call of tree_inlinable_function_p.
* cgraph.h: (cgraph_local_info): Add can_inline_once
(cgraph_global_info): Add inline_once.
(cgraph_node): Add previous.
(cgraph_remove_node): New.
* cgraphunit.c (cgraph_mark_functions_to_inline_once): New static
function.
(cgraph_optimize): Call it.
(cgraph_finalize_function): Set inlinable flags.
(cgraph_finalize_compilation_unit): Actually remove the reclaimed nodes.
(cgraph_mark_functions_to_output): Use new inlining heuristics flags.
(cgraph_expand_function): Likewise.
* cgraph.c
(cgraph_node): Put nodes into doubly linked chain.
(cgraph_remove_node): New function.
* flags.h (flag_inline_functions_called_once): Declare.
* tree-inline.c: Include cgraph.h
(inlinable_functions_p): Add extra argument to bypass limits.
(expand_call_inline): Obey cgraph flag.
* tree-inline.h (tree_inlinable_function_p): Update prototype.
2003-03-08 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz> 2003-03-08 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* gcse.c (bypass_block, bypass_conditional_jumps): Do not create * gcse.c (bypass_block, bypass_conditional_jumps): Do not create
......
...@@ -6444,7 +6444,7 @@ finish_function (nested, can_defer_p) ...@@ -6444,7 +6444,7 @@ finish_function (nested, can_defer_p)
predicates depend on cfun and current_function_decl to predicates depend on cfun and current_function_decl to
function completely. */ function completely. */
timevar_push (TV_INTEGRATION); timevar_push (TV_INTEGRATION);
uninlinable = ! tree_inlinable_function_p (fndecl); uninlinable = ! tree_inlinable_function_p (fndecl, 0);
if (! uninlinable && can_defer_p if (! uninlinable && can_defer_p
/* Save function tree for inlining. Should return 0 if the /* Save function tree for inlining. Should return 0 if the
......
...@@ -48,7 +48,7 @@ bool cgraph_global_info_ready = false; ...@@ -48,7 +48,7 @@ bool cgraph_global_info_ready = false;
static struct cgraph_edge *create_edge PARAMS ((struct cgraph_node *, static struct cgraph_edge *create_edge PARAMS ((struct cgraph_node *,
struct cgraph_node *)); struct cgraph_node *));
static void remove_edge PARAMS ((struct cgraph_node *, struct cgraph_node *)); static void cgraph_remove_edge PARAMS ((struct cgraph_node *, struct cgraph_node *));
static hashval_t hash_node PARAMS ((const PTR)); static hashval_t hash_node PARAMS ((const PTR));
static int eq_node PARAMS ((const PTR, const PTR)); static int eq_node PARAMS ((const PTR, const PTR));
...@@ -95,6 +95,9 @@ cgraph_node (decl) ...@@ -95,6 +95,9 @@ cgraph_node (decl)
node = xcalloc (sizeof (*node), 1); node = xcalloc (sizeof (*node), 1);
node->decl = decl; node->decl = decl;
node->next = cgraph_nodes; node->next = cgraph_nodes;
if (cgraph_nodes)
cgraph_nodes->previous = node;
node->previous = NULL;
cgraph_nodes = node; cgraph_nodes = node;
cgraph_n_nodes++; cgraph_n_nodes++;
*slot = node; *slot = node;
...@@ -127,7 +130,7 @@ create_edge (caller, callee) ...@@ -127,7 +130,7 @@ create_edge (caller, callee)
/* Remove the edge from CALLER to CALLEE in the cgraph. */ /* Remove the edge from CALLER to CALLEE in the cgraph. */
static void static void
remove_edge (caller, callee) cgraph_remove_edge (caller, callee)
struct cgraph_node *caller, *callee; struct cgraph_node *caller, *callee;
{ {
struct cgraph_edge **edge, **edge2; struct cgraph_edge **edge, **edge2;
...@@ -146,6 +149,37 @@ remove_edge (caller, callee) ...@@ -146,6 +149,37 @@ remove_edge (caller, callee)
*edge2 = (*edge2)->next_callee; *edge2 = (*edge2)->next_callee;
} }
/* Remove the node from cgraph. */
void
cgraph_remove_node (node)
struct cgraph_node *node;
{
while (node->callers)
cgraph_remove_edge (node->callers->caller, node);
while (node->callees)
cgraph_remove_edge (node, node->callees->callee);
while (node->nested)
cgraph_remove_node (node->nested);
if (node->origin)
{
struct cgraph_node **node2 = &node->origin->nested;
while (*node2 != node)
node2 = &(*node2)->next_nested;
*node2 = node->next_nested;
}
if (node->previous)
node->previous->next = node->next;
else
cgraph_nodes = node;
if (node->next)
node->next->previous = node->previous;
DECL_SAVED_TREE (node->decl) = NULL;
/* Do not free the structure itself so the walk over chain can continue. */
}
/* Record call from CALLER to CALLEE */ /* Record call from CALLER to CALLEE */
struct cgraph_edge * struct cgraph_edge *
...@@ -159,7 +193,7 @@ void ...@@ -159,7 +193,7 @@ void
cgraph_remove_call (caller, callee) cgraph_remove_call (caller, callee)
tree caller, callee; tree caller, callee;
{ {
remove_edge (cgraph_node (caller), cgraph_node (callee)); cgraph_remove_edge (cgraph_node (caller), cgraph_node (callee));
} }
/* Return true when CALLER_DECL calls CALLEE_DECL. */ /* Return true when CALLER_DECL calls CALLEE_DECL. */
......
...@@ -30,7 +30,11 @@ struct cgraph_local_info ...@@ -30,7 +30,11 @@ struct cgraph_local_info
/* Set when function function is visiable in current compilation unit only /* Set when function function is visiable in current compilation unit only
and it's address is never taken. */ and it's address is never taken. */
bool local; bool local;
/* Set when function is small enought to be inlinable many times. */
bool inline_many; bool inline_many;
/* Set when function can be inlined once (false only for functions calling
alloca, using varargs and so on). */
bool can_inline_once;
}; };
/* Information about the function that needs to be computed globally /* Information about the function that needs to be computed globally
...@@ -38,8 +42,8 @@ struct cgraph_local_info ...@@ -38,8 +42,8 @@ struct cgraph_local_info
struct cgraph_global_info struct cgraph_global_info
{ {
/* Empty for the moment. */ /* Set when the function will be inlined exactly once. */
int dummy; bool inline_once;
}; };
/* Information about the function that is propagated by the RTL backend. /* Information about the function that is propagated by the RTL backend.
...@@ -60,7 +64,7 @@ struct cgraph_node ...@@ -60,7 +64,7 @@ struct cgraph_node
tree decl; tree decl;
struct cgraph_edge *callees; struct cgraph_edge *callees;
struct cgraph_edge *callers; struct cgraph_edge *callers;
struct cgraph_node *next; struct cgraph_node *next, *previous;
/* For nested functions points to function the node is nested in. */ /* For nested functions points to function the node is nested in. */
struct cgraph_node *origin; struct cgraph_node *origin;
/* Points to first nested function, if any. */ /* Points to first nested function, if any. */
...@@ -100,6 +104,7 @@ extern bool cgraph_global_info_ready; ...@@ -100,6 +104,7 @@ extern bool cgraph_global_info_ready;
/* In cgraph.c */ /* In cgraph.c */
void dump_cgraph PARAMS ((FILE *)); void dump_cgraph PARAMS ((FILE *));
void cgraph_remove_call PARAMS ((tree, tree)); void cgraph_remove_call PARAMS ((tree, tree));
void cgraph_remove_node PARAMS ((struct cgraph_node *));
struct cgraph_edge *cgraph_record_call PARAMS ((tree, tree)); struct cgraph_edge *cgraph_record_call PARAMS ((tree, tree));
struct cgraph_node *cgraph_node PARAMS ((tree decl)); struct cgraph_node *cgraph_node PARAMS ((tree decl));
bool cgraph_calls_p PARAMS ((tree, tree)); bool cgraph_calls_p PARAMS ((tree, tree));
......
...@@ -40,6 +40,8 @@ static void cgraph_mark_functions_to_output PARAMS ((void)); ...@@ -40,6 +40,8 @@ static void cgraph_mark_functions_to_output PARAMS ((void));
static void cgraph_expand_function PARAMS ((struct cgraph_node *)); static void cgraph_expand_function PARAMS ((struct cgraph_node *));
static tree record_call_1 PARAMS ((tree *, int *, void *)); static tree record_call_1 PARAMS ((tree *, int *, void *));
static void cgraph_mark_local_functions PARAMS ((void)); static void cgraph_mark_local_functions PARAMS ((void));
static void cgraph_mark_functions_to_inline_once PARAMS ((void));
static void cgraph_optimize_function PARAMS ((struct cgraph_node *));
/* Analyze function once it is parsed. Set up the local information /* Analyze function once it is parsed. Set up the local information
available - create cgraph edges for function calles via BODY. */ available - create cgraph edges for function calles via BODY. */
...@@ -53,8 +55,9 @@ cgraph_finalize_function (decl, body) ...@@ -53,8 +55,9 @@ cgraph_finalize_function (decl, body)
node->decl = decl; node->decl = decl;
node->local.can_inline_once = tree_inlinable_function_p (decl, 1);
if (flag_inline_trees) if (flag_inline_trees)
node->local.inline_many = tree_inlinable_function_p (decl); node->local.inline_many = tree_inlinable_function_p (decl, 0);
else else
node->local.inline_many = 0; node->local.inline_many = 0;
...@@ -200,7 +203,7 @@ cgraph_finalize_compilation_unit () ...@@ -200,7 +203,7 @@ cgraph_finalize_compilation_unit ()
if (!node->reachable && DECL_SAVED_TREE (decl)) if (!node->reachable && DECL_SAVED_TREE (decl))
{ {
DECL_SAVED_TREE (decl) = NULL; cgraph_remove_node (node);
announce_function (decl); announce_function (decl);
} }
} }
...@@ -221,7 +224,8 @@ cgraph_mark_functions_to_output () ...@@ -221,7 +224,8 @@ cgraph_mark_functions_to_output ()
if (DECL_SAVED_TREE (decl) if (DECL_SAVED_TREE (decl)
&& (node->needed && (node->needed
|| (!node->local.inline_many && node->reachable) || (!node->local.inline_many && !node->global.inline_once
&& node->reachable)
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
&& !TREE_ASM_WRITTEN (decl) && !node->origin && !TREE_ASM_WRITTEN (decl) && !node->origin
&& !DECL_EXTERNAL (decl)) && !DECL_EXTERNAL (decl))
...@@ -229,6 +233,22 @@ cgraph_mark_functions_to_output () ...@@ -229,6 +233,22 @@ cgraph_mark_functions_to_output ()
} }
} }
/* Optimize the function before expansion. */
static void
cgraph_optimize_function (node)
struct cgraph_node *node;
{
tree decl = node->decl;
if (flag_inline_trees)
optimize_inline_calls (decl);
if (node->nested)
{
for (node = node->nested; node; node = node->next_nested)
cgraph_optimize_function (node);
}
}
/* Expand function specified by NODE. */ /* Expand function specified by NODE. */
static void static void
cgraph_expand_function (node) cgraph_expand_function (node)
...@@ -237,12 +257,18 @@ cgraph_expand_function (node) ...@@ -237,12 +257,18 @@ cgraph_expand_function (node)
tree decl = node->decl; tree decl = node->decl;
announce_function (decl); announce_function (decl);
if (flag_inline_trees)
optimize_inline_calls (decl); cgraph_optimize_function (node);
/* Avoid RTL inlining from taking place. */ /* Avoid RTL inlining from taking place. */
(*lang_hooks.callgraph.expand_function) (decl); (*lang_hooks.callgraph.expand_function) (decl);
if (DECL_UNINLINABLE (decl))
/* When we decided to inline the function once, we never ever should need to
output it separately. */
if (node->global.inline_once)
abort ();
if (!node->local.inline_many
|| !node->callers)
DECL_SAVED_TREE (decl) = NULL; DECL_SAVED_TREE (decl) = NULL;
current_function_decl = NULL; current_function_decl = NULL;
} }
...@@ -354,6 +380,43 @@ cgraph_mark_local_functions () ...@@ -354,6 +380,43 @@ cgraph_mark_local_functions ()
} }
} }
/* Decide what function should be inlined because they are invoked once
(so inlining won't result in duplication of the code). */
static void
cgraph_mark_functions_to_inline_once ()
{
struct cgraph_node *node, *node1;
if (!quiet_flag)
fprintf (stderr, "\n\nMarking functions to inline once:");
/* Now look for function called only once and mark them to inline. From this
point number of calls to given function won't grow. */
for (node = cgraph_nodes; node; node = node->next)
{
if (node->callers && !node->callers->next_caller && !node->needed
&& node->local.can_inline_once)
{
bool ok = true;
/* Verify that we won't duplicate the caller. */
for (node1 = node->callers->caller;
node1->local.inline_many
&& node1->callers
&& ok;
node1 = node1->callers->caller)
if (node1->callers->next_caller || node1->needed)
ok = false;
if (ok)
{
node->global.inline_once = true;
announce_function (node->decl);
}
}
}
}
/* Perform simple optimizations based on callgraph. */ /* Perform simple optimizations based on callgraph. */
...@@ -365,6 +428,8 @@ cgraph_optimize () ...@@ -365,6 +428,8 @@ cgraph_optimize ()
cgraph_mark_local_functions (); cgraph_mark_local_functions ();
cgraph_mark_functions_to_inline_once ();
cgraph_global_info_ready = true; cgraph_global_info_ready = true;
if (!quiet_flag) if (!quiet_flag)
fprintf (stderr, "\n\nAssembling functions:"); fprintf (stderr, "\n\nAssembling functions:");
......
...@@ -4519,6 +4519,16 @@ ...@@ -4519,6 +4519,16 @@
[(set_attr "type" "sseicvt") [(set_attr "type" "sseicvt")
(set_attr "athlon_decode" "double,vector")]) (set_attr "athlon_decode" "double,vector")])
;; Avoid vector decoded form of the instruction.
(define_peephole2
[(match_scratch:SF 2 "x")
(set (match_operand:DI 0 "register_operand" "")
(fix:DI (match_operand:SF 1 "nonimmediate_operand" "")))]
"TARGET_K8 && !optimize_size"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (fix:DI (match_dup 2)))]
"")
(define_insn "fix_truncdfdi_sse" (define_insn "fix_truncdfdi_sse"
[(set (match_operand:DI 0 "register_operand" "=r,r") [(set (match_operand:DI 0 "register_operand" "=r,r")
(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))] (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
...@@ -4527,6 +4537,16 @@ ...@@ -4527,6 +4537,16 @@
[(set_attr "type" "sseicvt,sseicvt") [(set_attr "type" "sseicvt,sseicvt")
(set_attr "athlon_decode" "double,vector")]) (set_attr "athlon_decode" "double,vector")])
;; Avoid vector decoded form of the instruction.
(define_peephole2
[(match_scratch:DF 2 "Y")
(set (match_operand:DI 0 "register_operand" "")
(fix:DI (match_operand:DF 1 "nonimmediate_operand" "")))]
"TARGET_K8 && !optimize_size"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (fix:DI (match_dup 2)))]
"")
;; Signed conversion to SImode. ;; Signed conversion to SImode.
(define_expand "fix_truncxfsi2" (define_expand "fix_truncxfsi2"
...@@ -4630,6 +4650,16 @@ ...@@ -4630,6 +4650,16 @@
[(set_attr "type" "sseicvt") [(set_attr "type" "sseicvt")
(set_attr "athlon_decode" "double,vector")]) (set_attr "athlon_decode" "double,vector")])
;; Avoid vector decoded form of the instruction.
(define_peephole2
[(match_scratch:SF 2 "x")
(set (match_operand:SI 0 "register_operand" "")
(fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))]
"TARGET_K8 && !optimize_size"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (fix:SI (match_dup 2)))]
"")
(define_insn "fix_truncdfsi_sse" (define_insn "fix_truncdfsi_sse"
[(set (match_operand:SI 0 "register_operand" "=r,r") [(set (match_operand:SI 0 "register_operand" "=r,r")
(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))] (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
...@@ -4638,6 +4668,16 @@ ...@@ -4638,6 +4668,16 @@
[(set_attr "type" "sseicvt") [(set_attr "type" "sseicvt")
(set_attr "athlon_decode" "double,vector")]) (set_attr "athlon_decode" "double,vector")])
;; Avoid vector decoded form of the instruction.
(define_peephole2
[(match_scratch:DF 2 "Y")
(set (match_operand:SI 0 "register_operand" "")
(fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))]
"TARGET_K8 && !optimize_size"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (fix:SI (match_dup 2)))]
"")
(define_split (define_split
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(fix:SI (match_operand 1 "register_operand" ""))) (fix:SI (match_operand 1 "register_operand" "")))
......
Sat Mar 8 14:18:15 CET 2003 Jan Hubicka <jh@suse.cz>
* gcc.dg/inline-3.c: New test.
2003-03-08 Mark Mitchell <mark@codesourcery.com> 2003-03-08 Mark Mitchell <mark@codesourcery.com>
PR c++/9809 PR c++/9809
...@@ -22,6 +26,7 @@ ...@@ -22,6 +26,7 @@
Fri Mar 7 17:41:07 CET 2003 Jan Hubicka <jh@suse.cz> Fri Mar 7 17:41:07 CET 2003 Jan Hubicka <jh@suse.cz>
* gcc.dg/i386-local2.c: Fix problems with certain versions of dejagnu. * gcc.dg/i386-local2.c: Fix problems with certain versions of dejagnu.
* gcc.dg/inline-3.c: New test.
2003-03-06 Mark Mitchell <mark@codesourcery.com> 2003-03-06 Mark Mitchell <mark@codesourcery.com>
......
/* { dg-options "-O2 -funit-at-a-time" } */
/* { dg-final { scan-assembler-not "big_function_2" } } */
static void
big_function_2(void);
void
big_function_1()
{
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
big_function_2();
}
static void
big_function_2()
{
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
while (t());
}
...@@ -115,7 +115,7 @@ static tree copy_body_r PARAMS ((tree *, int *, void *)); ...@@ -115,7 +115,7 @@ static tree copy_body_r PARAMS ((tree *, int *, void *));
static tree copy_body PARAMS ((inline_data *)); static tree copy_body PARAMS ((inline_data *));
static tree expand_call_inline PARAMS ((tree *, int *, void *)); static tree expand_call_inline PARAMS ((tree *, int *, void *));
static void expand_calls_inline PARAMS ((tree *, inline_data *)); static void expand_calls_inline PARAMS ((tree *, inline_data *));
static int inlinable_function_p PARAMS ((tree, inline_data *)); static int inlinable_function_p PARAMS ((tree, inline_data *, int));
static tree remap_decl PARAMS ((tree, inline_data *)); static tree remap_decl PARAMS ((tree, inline_data *));
#ifndef INLINER_FOR_JAVA #ifndef INLINER_FOR_JAVA
static tree initialize_inlined_parameters PARAMS ((inline_data *, tree, tree)); static tree initialize_inlined_parameters PARAMS ((inline_data *, tree, tree));
...@@ -872,10 +872,11 @@ declare_return_variable (id, return_slot_addr, var) ...@@ -872,10 +872,11 @@ declare_return_variable (id, return_slot_addr, var)
/* Returns nonzero if a function can be inlined as a tree. */ /* Returns nonzero if a function can be inlined as a tree. */
int int
tree_inlinable_function_p (fn) tree_inlinable_function_p (fn, nolimit)
tree fn; tree fn;
int nolimit;
{ {
return inlinable_function_p (fn, NULL); return inlinable_function_p (fn, NULL, nolimit);
} }
/* If *TP is possibly call to alloca, return nonzero. */ /* If *TP is possibly call to alloca, return nonzero. */
...@@ -939,9 +940,10 @@ find_builtin_longjmp_call (exp) ...@@ -939,9 +940,10 @@ find_builtin_longjmp_call (exp)
can be inlined at all. */ can be inlined at all. */
static int static int
inlinable_function_p (fn, id) inlinable_function_p (fn, id, nolimit)
tree fn; tree fn;
inline_data *id; inline_data *id;
int nolimit;
{ {
int inlinable; int inlinable;
int currfn_insns; int currfn_insns;
...@@ -973,12 +975,13 @@ inlinable_function_p (fn, id) ...@@ -973,12 +975,13 @@ inlinable_function_p (fn, id)
front-end that must set DECL_INLINE in this case, because front-end that must set DECL_INLINE in this case, because
dwarf2out loses if a function is inlined that doesn't have dwarf2out loses if a function is inlined that doesn't have
DECL_INLINE set. */ DECL_INLINE set. */
else if (! DECL_INLINE (fn)) else if (! DECL_INLINE (fn) && !nolimit)
; ;
/* We can't inline functions that are too big. Only allow a single /* We can't inline functions that are too big. Only allow a single
function to be of MAX_INLINE_INSNS_SINGLE size. Make special function to be of MAX_INLINE_INSNS_SINGLE size. Make special
allowance for extern inline functions, though. */ allowance for extern inline functions, though. */
else if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn) else if (!nolimit
&& ! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
&& currfn_insns > max_inline_insns_single) && currfn_insns > max_inline_insns_single)
; ;
/* We can't inline functions that call __builtin_longjmp at all. /* We can't inline functions that call __builtin_longjmp at all.
...@@ -1009,7 +1012,7 @@ inlinable_function_p (fn, id) ...@@ -1009,7 +1012,7 @@ inlinable_function_p (fn, id)
/* In case we don't disregard the inlining limits and we basically /* In case we don't disregard the inlining limits and we basically
can inline this function, investigate further. */ can inline this function, investigate further. */
if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn) if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
&& inlinable) && inlinable && !nolimit)
{ {
int sum_insns = (id ? id->inlined_stmts : 0) * INSNS_PER_STMT int sum_insns = (id ? id->inlined_stmts : 0) * INSNS_PER_STMT
+ currfn_insns; + currfn_insns;
...@@ -1158,7 +1161,9 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -1158,7 +1161,9 @@ expand_call_inline (tp, walk_subtrees, data)
/* Don't try to inline functions that are not well-suited to /* Don't try to inline functions that are not well-suited to
inlining. */ inlining. */
if (!inlinable_function_p (fn, id)) if ((!flag_unit_at_a_time || !DECL_SAVED_TREE (fn)
|| !cgraph_global_info (fn)->inline_once)
&& !inlinable_function_p (fn, id, 0))
return NULL_TREE; return NULL_TREE;
if (! (*lang_hooks.tree_inlining.start_inlining) (fn)) if (! (*lang_hooks.tree_inlining.start_inlining) (fn))
......
...@@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA. */
/* Function prototypes. */ /* Function prototypes. */
void optimize_inline_calls PARAMS ((tree)); void optimize_inline_calls PARAMS ((tree));
int tree_inlinable_function_p PARAMS ((tree)); int tree_inlinable_function_p PARAMS ((tree, int));
tree walk_tree PARAMS ((tree*, walk_tree_fn, void*, void*)); tree walk_tree PARAMS ((tree*, walk_tree_fn, void*, void*));
tree walk_tree_without_duplicates PARAMS ((tree*, walk_tree_fn, void*)); tree walk_tree_without_duplicates PARAMS ((tree*, walk_tree_fn, void*));
tree copy_tree_r PARAMS ((tree*, int*, void*)); tree copy_tree_r PARAMS ((tree*, int*, void*));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment