Commit b58b1157 by Jan Hubicka Committed by Jan Hubicka

cgraph.c (cgraph_max_uid): New global variable.


	* cgraph.c (cgraph_max_uid): New global variable.
	(cgraph_node): Set uid field.
	(create_edge): Keep inline flags consistent.
	(dump_cgraph): Dump more info.
	* cgraph.h (struct cgraph_local_info): Remove inline_many and
	can_inline_once; add inlinable, disgread_inline_limits, and self_insn
	(struct cgraph_global_info): Add insns, calls, cloned_times,
	will_be_output.
	(struct cgraph_node): Add uid.
	(struct cgraph_edge): Add inline_call.
	(cgraph_max_uid, cgraph_inline_p): Declare.
	* cgraph.c: Include params.h and fibheap.h
	(cgraph_mark_functions_to_inline_once): Kill.
	(INSNS_PER_CALL): New constant.
	(ncalls_inlined, nfunctions_inlined, initial_insns, overall_insns): New
	static variables.
	(cgraph_finalize_function): Do not analyze inlining.
	(cgraph_finalize_compilation_unit): Set inlining attributes.
	(cgraph_mark_functions_to_output): More consistency checks.
	(cgraph_optimize_function): Set current_function_decl to NULL.
	(cgraph_expand_function): Use new inline flags.
	(cgraph_postorder): Expand from cgraph_expand_functions.
	(INLINED_TIMES, SET_INLINED_TIMES): New macros.
	(cgraph_inlined_into, cgraph_inlined_callees,
	cgraph_estimate_size_after_inlining, cgraph_estimate_growth,
	cgraph_mark_inline, cgraph_check_inline_limits,
	cgraph_default_inline_p, cgraph_decide_inling_of_small_functions,
	cgraph_decide_inlining, cgraph_inline_p): New functions.
	* params.def (PARAM_LARGE_FUNCTION_INSNS, PARAM_LARGE_FUNCTION_GROWTH,
	PARAM_INLINE_UNIT_GROWTH): New parameters.
	* tree-inline.c (struct inline_data): New field current_decl.
	(expand_call_inline): Avoid forward declarations; use
	inlinable_function_p.
	(optimize_inline_calls): Set id.current_decl.

Co-Authored-By: Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>

From-SVN: r69262
parent 27b8e366
Sat Jul 12 03:06:01 CEST 2003 Jan Hubicka <jh@suse.cz>
Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
* cgraph.c (cgraph_max_uid): New global variable.
(cgraph_node): Set uid field.
(create_edge): Keep inline flags consistent.
(dump_cgraph): Dump more info.
* cgraph.h (struct cgraph_local_info): Remove inline_many and
can_inline_once; add inlinable, disgread_inline_limits, and self_insn
(struct cgraph_global_info): Add insns, calls, cloned_times,
will_be_output.
(struct cgraph_node): Add uid.
(struct cgraph_edge): Add inline_call.
(cgraph_max_uid, cgraph_inline_p): Declare.
* cgraph.c: Include params.h and fibheap.h
(cgraph_mark_functions_to_inline_once): Kill.
(INSNS_PER_CALL): New constant.
(ncalls_inlined, nfunctions_inlined, initial_insns, overall_insns): New
static variables.
(cgraph_finalize_function): Do not analyze inlining.
(cgraph_finalize_compilation_unit): Set inlining attributes.
(cgraph_mark_functions_to_output): More consistency checks.
(cgraph_optimize_function): Set current_function_decl to NULL.
(cgraph_expand_function): Use new inline flags.
(cgraph_postorder): Expand from cgraph_expand_functions.
(INLINED_TIMES, SET_INLINED_TIMES): New macros.
(cgraph_inlined_into, cgraph_inlined_callees,
cgraph_estimate_size_after_inlining, cgraph_estimate_growth,
cgraph_mark_inline, cgraph_check_inline_limits,
cgraph_default_inline_p, cgraph_decide_inling_of_small_functions,
cgraph_decide_inlining, cgraph_inline_p): New functions.
* params.def (PARAM_LARGE_FUNCTION_INSNS, PARAM_LARGE_FUNCTION_GROWTH,
PARAM_INLINE_UNIT_GROWTH): New parameters.
* tree-inline.c (struct inline_data): New field current_decl.
(expand_call_inline): Avoid forward declarations; use
inlinable_function_p.
(optimize_inline_calls): Set id.current_decl.
2003-07-11 Andrew Pinski <pinskia@physics.uc.edu>
* configure.in: Remove wrongly added definition of
......
......@@ -48,6 +48,9 @@ struct cgraph_node *cgraph_nodes_queue;
/* Number of nodes in existence. */
int cgraph_n_nodes;
/* Maximal uid used in cgraph nodes. */
int cgraph_max_uid;
/* Set when whole unit has been analyzed so we can access global info. */
bool cgraph_global_info_ready = false;
......@@ -114,6 +117,7 @@ cgraph_node (decl)
node = ggc_alloc_cleared (sizeof (*node));
node->decl = decl;
node->next = cgraph_nodes;
node->uid = cgraph_max_uid++;
if (cgraph_nodes)
cgraph_nodes->previous = node;
node->previous = NULL;
......@@ -157,6 +161,19 @@ create_edge (caller, callee)
struct cgraph_node *caller, *callee;
{
struct cgraph_edge *edge = ggc_alloc (sizeof (struct cgraph_edge));
struct cgraph_edge *edge2;
edge->inline_call = false;
/* At the moment we don't associate calls with specific CALL_EXPRs
as we probably ought to, so we must preserve inline_call flags to
be the same in all copies of the same edge. */
if (cgraph_global_info_ready)
for (edge2 = caller->callees; edge2; edge2 = edge2->next_caller)
if (edge2->callee == callee)
{
edge->inline_call = edge2->inline_call;
break;
}
edge->caller = caller;
edge->callee = callee;
......@@ -337,6 +354,8 @@ dump_cgraph (f)
{
struct cgraph_edge *edge;
fprintf (f, "%s", cgraph_node_name (node));
if (node->local.self_insns)
fprintf (f, " %i insns", node->local.self_insns);
if (node->origin)
fprintf (f, " nested in: %s", cgraph_node_name (node->origin));
if (node->needed)
......@@ -346,13 +365,32 @@ dump_cgraph (f)
if (DECL_SAVED_TREE (node->decl))
fprintf (f, " tree");
if (node->local.disgread_inline_limits)
fprintf (f, " always_inline");
else if (node->local.inlinable)
fprintf (f, " inlinable");
if (node->global.insns && node->global.insns != node->local.self_insns)
fprintf (f, " %i insns after inlining", node->global.insns);
if (node->global.cloned_times > 1)
fprintf (f, " cloned %ix", node->global.cloned_times);
if (node->global.calls)
fprintf (f, " %i calls", node->global.calls);
fprintf (f, "\n called by :");
for (edge = node->callers; edge; edge = edge->next_caller)
fprintf (f, "%s ", cgraph_node_name (edge->caller));
{
fprintf (f, "%s ", cgraph_node_name (edge->caller));
if (edge->inline_call)
fprintf(f, "(inlined) ");
}
fprintf (f, "\n calls: ");
for (edge = node->callees; edge; edge = edge->next_callee)
fprintf (f, "%s ", cgraph_node_name (edge->callee));
{
fprintf (f, "%s ", cgraph_node_name (edge->callee));
if (edge->inline_call)
fprintf(f, "(inlined) ");
}
fprintf (f, "\n");
}
}
......
......@@ -30,13 +30,15 @@ struct cgraph_local_info GTY(())
/* Set when function function is visible in current compilation unit only
and it's address is never taken. */
bool local;
/* Set when function is small enough to be inlinable many times. */
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;
/* Set once it has been finalized so we consider it to be output. */
bool finalized;
/* False when there is something making inlining impossible (such as va_arg) */
bool inlinable;
/* True when function should be inlined independently on it's size. */
bool disgread_inline_limits;
/* Size of the function before inlining. */
int self_insns;
};
/* Information about the function that needs to be computed globally
......@@ -46,6 +48,20 @@ struct cgraph_global_info GTY(())
{
/* Set when the function will be inlined exactly once. */
bool inline_once;
/* Estimated size of the function after inlining. */
int insns;
/* Number of direct calls not inlined into the function body. */
int calls;
/* Number of times given function will be cloned during output. */
int cloned_times;
/* Set to true for all reachable functions before inlining is decided.
Once we inline all calls to the function and the function is local,
it is set to false. */
bool will_be_output;
};
/* Information about the function that is propagated by the RTL backend.
......@@ -77,6 +93,8 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
struct cgraph_node *next_nested;
/* Pointer to the next function in cgraph_nodes_queue. */
struct cgraph_node *next_needed;
/* Unique id of the node. */
int uid;
PTR GTY ((skip (""))) aux;
/* Set when function must be output - it is externally visible
......@@ -102,6 +120,7 @@ struct cgraph_edge GTY(())
struct cgraph_node *callee;
struct cgraph_edge *next_caller;
struct cgraph_edge *next_callee;
bool inline_call;
};
/* The cgraph_varpool data strutcture.
......@@ -124,6 +143,7 @@ struct cgraph_varpool_node GTY(())
extern GTY(()) struct cgraph_node *cgraph_nodes;
extern GTY(()) int cgraph_n_nodes;
extern GTY(()) int cgraph_max_uid;
extern bool cgraph_global_info_ready;
extern GTY(()) struct cgraph_node *cgraph_nodes_queue;
extern FILE *cgraph_dump_file;
......@@ -157,5 +177,6 @@ void cgraph_finalize_compilation_unit PARAMS ((void));
void cgraph_create_edges PARAMS ((tree, tree));
void cgraph_optimize PARAMS ((void));
void cgraph_mark_needed_node PARAMS ((struct cgraph_node *, int));
bool cgraph_inline_p PARAMS ((tree, tree));
#endif /* GCC_CGRAPH_H */
......@@ -4572,6 +4572,7 @@ 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
......@@ -4579,8 +4580,27 @@ 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}.
This parameter is usefull primarily to avoid extreme compilation time caused by non-linear
algorithms used by the backend.
This parameter is ignored when @option{-funit-at-a-time} is not used.
The default value is 30000.
@item large-function-growth
Specifies maximal growth of large functtion caused by inlining in percents.
This parameter is ignored when @option{-funit-at-a-time} is not used.
The default value is 200.
@item inline-unit-growth
Specifies maximal overall growth of the compilation unit caused by inlining.
This parameter is ignored when @option{-funit-at-a-time} is not used.
The default value is 150.
@item max-inline-insns-rtl
For languages that use the RTL inliner (this happens at a later stage
than tree inlining), you can set the maximum allowable size (counted
......
......@@ -152,6 +152,19 @@ DEFPARAM(PARAM_MAX_PENDING_LIST_LENGTH,
"The maximum length of scheduling's pending operations list",
32)
DEFPARAM(PARAM_LARGE_FUNCTION_INSNS,
"large-function-insns",
"The size of function body to be considered large",
10000)
DEFPARAM(PARAM_LARGE_FUNCTION_GROWTH,
"large-function-growth",
"Maximal growth due to inlining of large function (in percents)",
100)
DEFPARAM(PARAM_INLINE_UNIT_GROWTH,
"inline-unit-growth",
"how much can given compilation unit grow because of the inlining (in percents)",
50)
/* The GCSE optimization will be disabled if it would require
significantly more memory than this value. */
DEFPARAM(PARAM_MAX_GCSE_MEMORY,
......
// { dg-options "-Winline -O2" }
// { dg-options "-Winline -O2 -fno-unit-at-a-time" }
static inline int foo(int x); // { dg-warning "" }
......
......@@ -106,6 +106,7 @@ typedef struct inline_data
htab_t tree_pruner;
/* Decl of function we are inlining into. */
tree decl;
tree current_decl;
} inline_data;
/* Prototypes. */
......@@ -1145,6 +1146,10 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
if (!fn)
return NULL_TREE;
/* Turn forward declarations into real ones. */
if (flag_unit_at_a_time)
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.
However, we can't blindly follow DECL_ABSTRACT_ORIGIN because the
......@@ -1159,9 +1164,9 @@ 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_global_info (fn)->inline_once)
&& !inlinable_function_p (fn, id, 0))
if (!DECL_SAVED_TREE (fn)
|| (flag_unit_at_a_time && !cgraph_inline_p (id->current_decl, fn))
|| (!flag_unit_at_a_time && !inlinable_function_p (fn, id, 0)))
{
if (warn_inline && DECL_INLINE (fn) && !DID_INLINE_FUNC (fn)
&& !DECL_IN_SYSTEM_HEADER (fn))
......@@ -1403,7 +1408,12 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
}
/* Recurse into the body of the just inlined function. */
expand_calls_inline (inlined_body, id);
{
tree old_decl = id->current_decl;
id->current_decl = fn;
expand_calls_inline (inlined_body, id);
id->current_decl = old_decl;
}
VARRAY_POP (id->fns);
/* If we've returned to the top level, clear out the record of how
......@@ -1446,6 +1456,7 @@ optimize_inline_calls (tree fn)
memset (&id, 0, sizeof (id));
id.decl = fn;
id.current_decl = fn;
/* Don't allow recursion into FN. */
VARRAY_TREE_INIT (id.fns, 32, "fns");
VARRAY_PUSH_TREE (id.fns, fn);
......
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