cgraph code cleanups and tweeks
Jan Hubicka
hubicka@ucw.cz
Fri Aug 15 13:43:00 GMT 2003
Hi,
this patch cleanups few places in cgraph code. More cleanups are badly needed
for inlining heuristics code but I guess I need to wait some time to figure out
how to do it.
The nodes queue is changed to contain only functions with bodies, inlining
heuristics now compute most of values needed during lowering process and I
dropped unused calls variable.
All these changes helps to implement inicremental (non-unit-at-a-time) top-down
inlining heuristics that can be used as a replacement of our current
tree-inline.c one in the case we won't be able to make inlining to imply
unit-at-a-time.
I have patch to remove all compilation controlling code from C frontend and
rely on cgraphunit to drive the compilation in non-unit-at-a-time mode too. I
would like to update other frontends similar way as current code duplication is
quite ugly. But this is somewhat work-in-progress and thus not included in
this cleanup patch :)
Honza
Fri Aug 15 15:35:59 CEST 2003 Jan Hubicka <jh@suse.cz>
* cgraph.c (cgraph_mark_needed_node): Do not mark functions without
body as reachable; mark nested functions as needed too.
(dump_cgraph): Do not output global.calls.
* cgraph.h (cgraph_global_info): Kill.
* cgraphunit.c (cgraph_finalize_function): Enqueue needed functions.
(record_call_1): Speedup.
(cgraph_analyze_function): Break out from ...; compute inlining
parameters.
(cgraph_finalize_compilation_unit): ... here.
(cgraph_mark_inline): Kill computation of calls.
(cgraph_decide_inlining): Do not compute most of initial values.
Index: cgraph.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.c,v
retrieving revision 1.23
diff -c -3 -p -r1.23 cgraph.c
*** cgraph.c 5 Aug 2003 14:11:42 -0000 1.23
--- cgraph.c 15 Aug 2003 13:35:44 -0000
*************** void
*** 240,256 ****
cgraph_mark_needed_node (struct cgraph_node *node, int needed)
{
if (needed)
! {
! node->needed = 1;
! }
! if (!node->reachable)
{
node->reachable = 1;
! if (DECL_SAVED_TREE (node->decl))
{
! node->next_needed = cgraph_nodes_queue;
! cgraph_nodes_queue = node;
! }
}
}
--- 240,263 ----
cgraph_mark_needed_node (struct cgraph_node *node, int needed)
{
if (needed)
! node->needed = 1;
!
! if (!node->reachable && DECL_SAVED_TREE (node->decl))
{
node->reachable = 1;
!
! node->next_needed = cgraph_nodes_queue;
! cgraph_nodes_queue = node;
!
! /* At the moment frontend automatically emits all nested functions. */
! if (node->nested)
{
! struct cgraph_node *node2;
!
! for (node2 = node->nested; node2; node2 = node2->next_nested)
! if (!node2->reachable)
! cgraph_mark_needed_node (node2, 0);
! }
}
}
*************** dump_cgraph (FILE *f)
*** 361,368 ****
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)
--- 368,373 ----
Index: cgraph.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.h,v
retrieving revision 1.15
diff -c -3 -p -r1.15 cgraph.h
*** cgraph.h 5 Aug 2003 14:11:42 -0000 1.15
--- cgraph.h 15 Aug 2003 13:35:44 -0000
*************** struct cgraph_global_info GTY(())
*** 52,60 ****
/* 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;
--- 52,57 ----
Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.18
diff -c -3 -p -r1.18 cgraphunit.c
*** cgraphunit.c 5 Aug 2003 14:11:42 -0000 1.18
--- cgraphunit.c 15 Aug 2003 13:35:45 -0000
*************** cgraph_finalize_function (tree decl, tre
*** 65,70 ****
--- 65,74 ----
node->decl = decl;
node->local.finalized = true;
+ /* Function now has DECL_SAVED_TREE set. Enqueue it into cgraph_nodes_queue
+ if needed. */
+ if (node->needed)
+ cgraph_mark_needed_node (node, 0);
if (/* Externally visible functions must be output. The exception are
COMDAT functions that must be output only when they are needed.
Similarly are handled deferred functions and
*************** record_call_1 (tree *tp, int *walk_subtr
*** 122,127 ****
--- 126,135 ----
*walk_subtrees = 0;
}
}
+ /* Save some cycles by not walking types and declaration as we won't find anything
+ usefull there anyway. */
+ if (DECL_P (*tp) || TYPE_P (*tp))
+ *walk_subtrees = 0;
return NULL;
}
*************** cgraph_create_edges (tree decl, tree bod
*** 135,147 ****
walk_tree_without_duplicates (&body, record_call_1, decl);
}
/* Analyze the whole compilation unit once it is parsed completely. */
void
cgraph_finalize_compilation_unit (void)
{
struct cgraph_node *node;
- struct cgraph_edge *edge;
cgraph_varpool_assemble_pending_decls ();
if (!quiet_flag)
--- 143,188 ----
walk_tree_without_duplicates (&body, record_call_1, decl);
}
+ /* Analyze the function scheduled to be output. */
+ static void
+ cgraph_analyze_function (struct cgraph_node *node)
+ {
+ tree decl = node->decl;
+
+ if (lang_hooks.callgraph.lower_function)
+ (*lang_hooks.callgraph.lower_function) (decl);
+
+ current_function_decl = node->decl;
+
+ /* First kill forward declaration so reverse inlining works properly. */
+ cgraph_create_edges (decl, DECL_SAVED_TREE (decl));
+
+ node->local.inlinable = tree_inlinable_function_p (decl);
+ if (!DECL_ESTIMATED_INSNS (decl))
+ DECL_ESTIMATED_INSNS (decl)
+ = (*lang_hooks.tree_inlining.estimate_num_insns) (decl);
+ node->local.self_insns = DECL_ESTIMATED_INSNS (decl);
+ if (node->local.inlinable)
+ node->local.disregard_inline_limits
+ = (*lang_hooks.tree_inlining.disregard_inline_limits) (decl);
+
+ /* Inlining characteristics are maintained by the cgraph_mark_inline. */
+ node->global.insns = node->local.self_insns;
+ if (!DECL_EXTERNAL (node->decl))
+ {
+ node->global.cloned_times = 1;
+ node->global.will_be_output = true;
+ }
+
+ node->lowered = true;
+ }
+
/* Analyze the whole compilation unit once it is parsed completely. */
void
cgraph_finalize_compilation_unit (void)
{
struct cgraph_node *node;
cgraph_varpool_assemble_pending_decls ();
if (!quiet_flag)
*************** cgraph_finalize_compilation_unit (void)
*** 171,208 ****
if (node->lowered || !node->reachable || !DECL_SAVED_TREE (decl))
abort ();
! if (lang_hooks.callgraph.lower_function)
! (*lang_hooks.callgraph.lower_function) (decl);
!
! current_function_decl = node->decl;
!
! /* At the moment frontend automatically emits all nested functions. */
! if (node->nested)
! {
! struct cgraph_node *node2;
!
! for (node2 = node->nested; node2; node2 = node2->next_nested)
! if (!node2->reachable)
! cgraph_mark_needed_node (node2, 0);
! }
!
! /* First kill forward declaration so reverse inlining works properly. */
! cgraph_create_edges (decl, DECL_SAVED_TREE (decl));
!
! node->local.inlinable = tree_inlinable_function_p (decl);
! DECL_ESTIMATED_INSNS (decl)
! = (*lang_hooks.tree_inlining.estimate_num_insns) (decl);
! node->local.self_insns = DECL_ESTIMATED_INSNS (decl);
! if (node->local.inlinable)
! node->local.disregard_inline_limits
! = (*lang_hooks.tree_inlining.disregard_inline_limits) (decl);
!
! for (edge = node->callees; edge; edge = edge->next_callee)
! {
! if (!edge->callee->reachable)
! cgraph_mark_needed_node (edge->callee, 0);
! }
! node->lowered = true;
cgraph_varpool_assemble_pending_decls ();
}
/* Collect entry points to the unit. */
--- 212,218 ----
if (node->lowered || !node->reachable || !DECL_SAVED_TREE (decl))
abort ();
! cgraph_analyze_function (node);
cgraph_varpool_assemble_pending_decls ();
}
/* Collect entry points to the unit. */
*************** cgraph_mark_inline (struct cgraph_node *
*** 650,656 ****
overall_insns += new_insns - to->global.insns;
to->global.insns = new_insns;
- to->global.calls += (what->global.calls - 1) *times;
if (!called && !what->needed && !what->origin
&& !DECL_EXTERNAL (what->decl))
{
--- 660,665 ----
*************** cgraph_mark_inline (struct cgraph_node *
*** 662,669 ****
overall_insns -= what->global.insns;
}
what->global.cloned_times += clones;
- if (to->global.calls < 0)
- abort ();
for (i = 0; i < ninlined; i++)
{
new_insns =
--- 671,676 ----
*************** cgraph_mark_inline (struct cgraph_node *
*** 672,681 ****
if (inlined[i]->global.will_be_output)
overall_insns += new_insns - inlined[i]->global.insns;
inlined[i]->global.insns = new_insns;
- inlined[i]->global.calls +=
- (what->global.calls - 1) *INLINED_TIMES (inlined[i]) * times;
- if (inlined[i]->global.calls < 0)
- abort ();
}
for (i = 0; i < ninlined_callees; i++)
{
--- 679,684 ----
*************** cgraph_decide_inlining (void)
*** 883,903 ****
int i, y;
for (node = cgraph_nodes; node; node = node->next)
! {
! int ncalls = 0;
! struct cgraph_edge *e;
!
! node->global.insns = node->local.self_insns;
! for (e = node->callees; e; e = e->next_callee)
! ncalls++;
! node->global.calls = ncalls;
! if (!DECL_EXTERNAL (node->decl))
! {
! node->global.cloned_times = 1;
! initial_insns += node->local.self_insns;
! node->global.will_be_output = true;
! }
! }
overall_insns = initial_insns;
nnodes = cgraph_postorder (order);
--- 886,892 ----
int i, y;
for (node = cgraph_nodes; node; node = node->next)
! initial_insns += node->local.self_insns;
overall_insns = initial_insns;
nnodes = cgraph_postorder (order);
More information about the Gcc-patches
mailing list