2004-10-04 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
[official-gcc.git] / gcc / cgraphunit.c
blob5d0a32faad6e375e2222e1918a3137d6936c4349
1 /* Callgraph based intraprocedural optimizations.
2 Copyright (C) 2003, 2004 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 /* This module implements main driver of compilation process as well as
23 few basic intraprocedural optimizers.
25 The main scope of this file is to act as an interface in between
26 tree based frontends and the backend (and middle end)
28 The front-end is supposed to use following functionality:
30 - cgraph_finalize_function
32 This function is called once front-end has parsed whole body of function
33 and it is certain that the function body nor the declaration will change.
35 (There is one exception needed for implementing GCC extern inline function.)
37 - cgraph_varpool_finalize_variable
39 This function has same behavior as the above but is used for static
40 variables.
42 - cgraph_finalize_compilation_unit
44 This function is called once compilation unit is finalized and it will
45 no longer change.
47 In the unit-at-a-time the call-graph construction and local function
48 analysis takes place here. Bodies of unreachable functions are released
49 to conserve memory usage.
51 ??? The compilation unit in this point of view should be compilation
52 unit as defined by the language - for instance C frontend allows multiple
53 compilation units to be parsed at once and it should call function each
54 time parsing is done so we save memory.
56 - cgraph_optimize
58 In this unit-at-a-time compilation the intra procedural analysis takes
59 place here. In particular the static functions whose address is never
60 taken are marked as local. Backend can then use this information to
61 modify calling conventions, do better inlining or similar optimizations.
63 - cgraph_assemble_pending_functions
64 - cgraph_varpool_assemble_pending_variables
66 In non-unit-at-a-time mode these functions can be used to force compilation
67 of functions or variables that are known to be needed at given stage
68 of compilation
70 - cgraph_mark_needed_node
71 - cgraph_varpool_mark_needed_node
73 When function or variable is referenced by some hidden way (for instance
74 via assembly code and marked by attribute "used"), the call-graph data structure
75 must be updated accordingly by this function.
77 - analyze_expr callback
79 This function is responsible for lowering tree nodes not understood by
80 generic code into understandable ones or alternatively marking
81 callgraph and varpool nodes referenced by the as needed.
83 ??? On the tree-ssa genericizing should take place here and we will avoid
84 need for these hooks (replacing them by genericizing hook)
86 - expand_function callback
88 This function is used to expand function and pass it into RTL back-end.
89 Front-end should not make any assumptions about when this function can be
90 called. In particular cgraph_assemble_pending_functions,
91 cgraph_varpool_assemble_pending_variables, cgraph_finalize_function,
92 cgraph_varpool_finalize_function, cgraph_optimize can cause arbitrarily
93 previously finalized functions to be expanded.
95 We implement two compilation modes.
97 - unit-at-a-time: In this mode analyzing of all functions is deferred
98 to cgraph_finalize_compilation_unit and expansion into cgraph_optimize.
100 In cgraph_finalize_compilation_unit the reachable functions are
101 analyzed. During analysis the call-graph edges from reachable
102 functions are constructed and their destinations are marked as
103 reachable. References to functions and variables are discovered too
104 and variables found to be needed output to the assembly file. Via
105 mark_referenced call in assemble_variable functions referenced by
106 static variables are noticed too.
108 The intra-procedural information is produced and it's existence
109 indicated by global_info_ready. Once this flag is set it is impossible
110 to change function from !reachable to reachable and thus
111 assemble_variable no longer call mark_referenced.
113 Finally the call-graph is topologically sorted and all reachable functions
114 that has not been completely inlined or are not external are output.
116 ??? It is possible that reference to function or variable is optimized
117 out. We can not deal with this nicely because topological order is not
118 suitable for it. For tree-ssa we may consider another pass doing
119 optimization and re-discovering reachable functions.
121 ??? Reorganize code so variables are output very last and only if they
122 really has been referenced by produced code, so we catch more cases
123 where reference has been optimized out.
125 - non-unit-at-a-time
127 All functions are variables are output as early as possible to conserve
128 memory consumption. This may or may not result in less memory used but
129 it is still needed for some legacy code that rely on particular ordering
130 of things output from the compiler.
132 Varpool data structures are not used and variables are output directly.
134 Functions are output early using call of
135 cgraph_assemble_pending_function from cgraph_finalize_function. The
136 decision on whether function is needed is made more conservative so
137 uninlininable static functions are needed too. During the call-graph
138 construction the edge destinations are not marked as reachable and it
139 is completely relied upn assemble_variable to mark them.
141 Inlining decision heuristics
142 ??? Move this to separate file after tree-ssa merge.
144 We separate inlining decisions from the inliner itself and store it
145 inside callgraph as so called inline plan. Refer to cgraph.c
146 documentation about particular representation of inline plans in the
147 callgraph
149 The implementation of particular heuristics is separated from
150 the rest of code to make it easier to replace it with more complicated
151 implementation in the future. The rest of inlining code acts as a
152 library aimed to modify the callgraph and verify that the parameters
153 on code size growth fits.
155 To mark given call inline, use cgraph_mark_inline function, the
156 verification is performed by cgraph_default_inline_p and
157 cgraph_check_inline_limits.
159 The heuristics implements simple knapsack style algorithm ordering
160 all functions by their "profitability" (estimated by code size growth)
161 and inlining them in priority order.
163 cgraph_decide_inlining implements heuristics taking whole callgraph
164 into account, while cgraph_decide_inlining_incrementally considers
165 only one function at a time and is used in non-unit-at-a-time mode. */
168 /* Additionally this file gathers information about how local statics
169 are used. This is done in cgraph_characterize_statics. After the
170 call graph has been built, each function is analyzed to determine
171 which local static variables are either read or written or have
172 their address taken. Any local static that has its address taken
173 is removed from consideration. Once the local read and writes
174 are determined, a transitive closure of this information is
175 performed over the call graph to determine the worst case set of
176 side effects of each call. In a later part of the compiler, these
177 local and global sets are examined to make the call clobbering less
178 traumatic both with respect to aliasing and to code generation. */
180 #include "config.h"
181 #include "system.h"
182 #include "coretypes.h"
183 #include "tm.h"
184 #include "tree.h"
185 #include "rtl.h"
186 #include "tree-flow.h"
187 #include "tree-inline.h"
188 #include "langhooks.h"
189 #include "hashtab.h"
190 #include "toplev.h"
191 #include "flags.h"
192 #include "ggc.h"
193 #include "debug.h"
194 #include "target.h"
195 #include "cgraph.h"
196 #include "diagnostic.h"
197 #include "timevar.h"
198 #include "params.h"
199 #include "fibheap.h"
200 #include "c-common.h"
201 #include "intl.h"
202 #include "function.h"
203 #include "tree-gimple.h"
205 #define INSNS_PER_CALL 10
207 static void cgraph_expand_all_functions (void);
208 static void cgraph_mark_functions_to_output (void);
209 static void cgraph_expand_function (struct cgraph_node *);
210 static tree record_call_1 (tree *, int *, void *);
211 static void cgraph_mark_local_and_external_functions (void);
212 static bool cgraph_default_inline_p (struct cgraph_node *n);
213 static void cgraph_analyze_function (struct cgraph_node *node);
214 static void cgraph_decide_inlining_incrementally (struct cgraph_node *);
216 /* Statistics we collect about inlining algorithm. */
217 static int ncalls_inlined;
218 static int nfunctions_inlined;
219 static int initial_insns;
220 static int overall_insns;
222 /* Records tree nodes seen in cgraph_create_edges. Simply using
223 walk_tree_without_duplicates doesn't guarantee each node is visited
224 once because it gets a new htab upon each recursive call from
225 record_calls_1. */
226 static htab_t visited_nodes;
228 static FILE *cgraph_dump_file;
230 /* These splay trees contain all of the static variables that are
231 being considered by the compilation level alias analysis. For
232 module_at_a_time compilation, this is the set of static but not
233 public variables. Any variables that either have their address
234 taken or participate in otherwise unsavory operations are deleted
235 from this list. */
236 static GTY((param1_is(tree), param2_is(tree)))
237 splay_tree static_vars_to_consider_by_tree;
239 /* FIXME -- PROFILE-RESTRUCTURE: change comment from DECL_UID to var-ann. */
240 /* same as above but indexed by DECL_UID */
241 static GTY((param1_is(int), param2_is(tree)))
242 splay_tree static_vars_to_consider_by_uid;
244 /* This bitmap is used to knock out the module static variables whose
245 addresses have been taken and passed around. This is indexed by
246 uid. */
247 static bitmap module_statics_escape;
249 /* FIXME -- PROFILE-RESTRUCTURE: change comment from DECL_UID to var-ann. */
250 /* A bit is set for every module static we are considering and is
251 indexed by DECL_UID. This is ored into the local info when asm
252 code is found that clobbers all memory. */
253 static GTY(()) bitmap all_module_statics;
255 /* Holds the value of "memory". */
256 static tree memory_identifier;
258 /* Determine if function DECL is needed. That is, visible to something
259 either outside this translation unit, something magic in the system
260 configury, or (if not doing unit-at-a-time) to something we havn't
261 seen yet. */
263 static bool
264 decide_is_function_needed (struct cgraph_node *node, tree decl)
266 tree origin;
268 /* If we decided it was needed before, but at the time we didn't have
269 the body of the function available, then it's still needed. We have
270 to go back and re-check its dependencies now. */
271 if (node->needed)
272 return true;
274 /* Externally visible functions must be output. The exception is
275 COMDAT functions that must be output only when they are needed. */
276 if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
277 return true;
279 /* Constructors and destructors are reachable from the runtime by
280 some mechanism. */
281 if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))
282 return true;
284 /* If the user told us it is used, then it must be so. */
285 if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
286 return true;
288 /* ??? If the assembler name is set by hand, it is possible to assemble
289 the name later after finalizing the function and the fact is noticed
290 in assemble_name then. This is arguably a bug. */
291 if (DECL_ASSEMBLER_NAME_SET_P (decl)
292 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
293 return true;
295 if (flag_unit_at_a_time)
296 return false;
298 /* If not doing unit at a time, then we'll only defer this function
299 if its marked for inlining. Otherwise we want to emit it now. */
301 /* "extern inline" functions are never output locally. */
302 if (DECL_EXTERNAL (decl))
303 return false;
304 /* Nested functions of extern inline function shall not be emit unless
305 we inlined the origin. */
306 for (origin = decl_function_context (decl); origin;
307 origin = decl_function_context (origin))
308 if (DECL_EXTERNAL (origin))
309 return false;
310 /* We want to emit COMDAT functions only when absolutely necessary. */
311 if (DECL_COMDAT (decl))
312 return false;
313 if (!DECL_INLINE (decl)
314 || (!node->local.disregard_inline_limits
315 /* When declared inline, defer even the uninlinable functions.
316 This allows them to be eliminated when unused. */
317 && !DECL_DECLARED_INLINE_P (decl)
318 && (!node->local.inlinable || !cgraph_default_inline_p (node))))
319 return true;
321 return false;
324 /* Debugging function for postorder and inorder code. NOTE is a string
325 that is printed before the nodes are printed. ORDER is an array of
326 cgraph_nodes that has COUNT useful nodes in it. */
328 static void
329 print_order (const char * note, struct cgraph_node** order, int count)
331 int i;
332 fprintf (cgraph_dump_file, "\n\n ordered call graph: %s\n", note);
334 for (i = count - 1; i >= 0; i--)
336 struct cgraph_edge *edge;
338 fprintf (cgraph_dump_file, "\n %s<-(", cgraph_node_name (order[i]));
340 for (edge = order[i]->callers; edge; edge = edge->next_caller)
341 fprintf (cgraph_dump_file, " %s", cgraph_node_name (edge->caller));
342 fprintf (cgraph_dump_file, ")");
344 fprintf (cgraph_dump_file, "\n");
347 /* FIXME -- PROFILE-RESTRUCTURE: Remove this function, it becomes a nop. */
348 /* Convert IN_DECL bitmap which is indexed by DECL_UID to IN_ANN, a
349 bitmap indexed by var_ann (VAR_DECL)->uid. */
351 static void
352 convert_UIDs_in_bitmap (bitmap in_ann, bitmap in_decl)
354 int index;
355 bitmap_iterator bi;
357 EXECUTE_IF_SET_IN_BITMAP(in_decl, 0, index, bi)
359 splay_tree_node n =
360 splay_tree_lookup (static_vars_to_consider_by_uid, index);
361 if (n != NULL)
363 tree t = (tree)n->value;
364 var_ann_t va = var_ann (t);
365 if (va)
366 bitmap_set_bit(in_ann, va->uid);
371 /* FIXME -- PROFILE-RESTRUCTURE: Delete all stmts initing *_decl_uid
372 variables. Add code to create a var_ann for tree node within the
373 cgraph_node and have it point to the newly created
374 static_vars_info. */
375 /* Create a new static_vars_info structure and place it into
376 cgraph_node, NODE. INIT_GLOBAL causes the global part of the
377 structure to be initialized. */
378 static static_vars_info_t
379 new_static_vars_info(struct cgraph_node* node,
380 bool init_global)
382 static_vars_info_t info = ggc_calloc (1, sizeof (struct static_vars_info_d));
383 local_static_vars_info_t l
384 = ggc_calloc (1, sizeof (struct local_static_vars_info_d));
386 /* Add the info to the tree's annotation. */
387 var_ann_t var_ann = get_var_ann(node->decl);
388 node->static_vars_info = info;
389 var_ann->static_vars_info = info;
391 info->local = l;
392 l->statics_read_by_decl_uid = BITMAP_GGC_ALLOC ();
393 l->statics_written_by_decl_uid = BITMAP_GGC_ALLOC ();
395 if (init_global)
397 global_static_vars_info_t g
398 = ggc_calloc (1, sizeof (struct global_static_vars_info_d));
399 info->global = g;
400 g->statics_read_by_decl_uid = BITMAP_GGC_ALLOC ();
401 g->statics_written_by_decl_uid = BITMAP_GGC_ALLOC ();
402 g->statics_read_by_ann_uid = BITMAP_GGC_ALLOC ();
403 g->statics_written_by_ann_uid = BITMAP_GGC_ALLOC ();
404 g->statics_not_read_by_decl_uid = BITMAP_GGC_ALLOC ();
405 g->statics_not_written_by_decl_uid = BITMAP_GGC_ALLOC ();
406 g->statics_not_read_by_ann_uid = BITMAP_GGC_ALLOC ();
407 g->statics_not_written_by_ann_uid = BITMAP_GGC_ALLOC ();
409 return info;
413 /* FIXME -- PROFILE-RESTRUCTURE: Remove this function, it becomes a
414 nop. */
415 /* The bitmaps used to represent the static global variables are
416 indexed by DECL_UID however, this is not used inside of functions
417 to index the ssa variables. The denser var_ann (VAR_DECL)->uid is
418 used there. This function is called from
419 tree_dfa:find_referenced_vars after the denser representation is
420 built. This function invalidates any cached indexes. */
422 void
423 cgraph_reset_static_var_maps (void)
425 struct cgraph_node *node;
427 for (node = cgraph_nodes; node; node = node->next)
429 static_vars_info_t info = node->static_vars_info;
430 if (info)
432 global_static_vars_info_t g = info->global;
433 if (g->var_anns_valid)
435 bitmap_clear (g->statics_read_by_ann_uid);
436 bitmap_clear (g->statics_written_by_ann_uid);
437 bitmap_clear (g->statics_not_read_by_ann_uid);
438 bitmap_clear (g->statics_not_written_by_ann_uid);
439 g->var_anns_valid = false;
442 else
443 /* Handle the case where a cgraph node has been inserted
444 after the analysis. We know nothing. */
445 new_static_vars_info(node, true);
449 /* Get the global static_vars_info structure for the function FN and
450 make sure the ann_uid's bitmaps are properly converted. */
452 static global_static_vars_info_t
453 get_global_static_vars_info (tree fn)
455 global_static_vars_info_t g;
457 /* Was not compiled -O2 or higher. */
458 static_vars_info_t info = get_var_ann(fn)->static_vars_info;
459 if (!info)
460 return NULL;
462 g = info->global;
463 if (!g->var_anns_valid)
465 convert_UIDs_in_bitmap (g->statics_read_by_ann_uid,
466 g->statics_read_by_decl_uid);
467 convert_UIDs_in_bitmap (g->statics_written_by_ann_uid,
468 g->statics_written_by_decl_uid);
469 convert_UIDs_in_bitmap (g->statics_not_read_by_ann_uid,
470 g->statics_not_read_by_decl_uid);
471 convert_UIDs_in_bitmap (g->statics_not_written_by_ann_uid,
472 g->statics_not_written_by_decl_uid);
473 g->var_anns_valid = true;
475 return g;
478 /* Return a bitmap indexed by var_ann (VAR_DECL)->uid for the static
479 variables that are not read during the execution of the function
480 FN. Returns NULL if no data is available, such as it was not
481 compiled with -O2 or higher. */
483 bitmap
484 get_global_statics_not_read (tree fn)
486 global_static_vars_info_t g = get_global_static_vars_info (fn);
487 if (g)
488 return g->statics_not_read_by_ann_uid;
489 else
490 return NULL;
493 /* Return a bitmap indexed by var_ann (VAR_DECL)->uid for the static
494 variables that are not written during the execution of the function
495 FN. Note that variables written may or may not be read during the
496 function call. Returns NULL if no data is available, such as it
497 was not compiled with -O2 or higher. */
499 bitmap
500 get_global_statics_not_written (tree fn)
502 global_static_vars_info_t g = get_global_static_vars_info (fn);
503 if (g)
504 return g->statics_not_written_by_ann_uid;
505 else
506 return NULL;
509 /* When not doing unit-at-a-time, output all functions enqueued.
510 Return true when such a functions were found. */
512 bool
513 cgraph_assemble_pending_functions (void)
515 bool output = false;
517 if (flag_unit_at_a_time)
518 return false;
520 while (cgraph_nodes_queue)
522 struct cgraph_node *n = cgraph_nodes_queue;
524 cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
525 n->next_needed = NULL;
526 if (!n->global.inlined_to && !DECL_EXTERNAL (n->decl))
528 cgraph_expand_function (n);
529 output = true;
533 return output;
536 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
537 logic in effect. If NESTED is true, then our caller cannot stand to have
538 the garbage collector run at the moment. We would need to either create
539 a new GC context, or just not compile right now. */
541 void
542 cgraph_finalize_function (tree decl, bool nested)
544 struct cgraph_node *node = cgraph_node (decl);
546 if (node->local.finalized)
548 /* As an GCC extension we allow redefinition of the function. The
549 semantics when both copies of bodies differ is not well defined.
550 We replace the old body with new body so in unit at a time mode
551 we always use new body, while in normal mode we may end up with
552 old body inlined into some functions and new body expanded and
553 inlined in others.
555 ??? It may make more sense to use one body for inlining and other
556 body for expanding the function but this is difficult to do. */
558 /* If node->output is set, then this is a unit-at-a-time compilation
559 and we have already begun whole-unit analysis. This is *not*
560 testing for whether we've already emitted the function. That
561 case can be sort-of legitimately seen with real function
562 redefinition errors. I would argue that the front end should
563 never present us with such a case, but don't enforce that for now. */
564 gcc_assert (!node->output);
566 /* Reset our data structures so we can analyze the function again. */
567 memset (&node->local, 0, sizeof (node->local));
568 memset (&node->global, 0, sizeof (node->global));
569 memset (&node->rtl, 0, sizeof (node->rtl));
570 node->analyzed = false;
571 node->local.redefined_extern_inline = true;
572 while (node->callees)
573 cgraph_remove_edge (node->callees);
575 /* We may need to re-queue the node for assembling in case
576 we already proceeded it and ignored as not needed. */
577 if (node->reachable && !flag_unit_at_a_time)
579 struct cgraph_node *n;
581 for (n = cgraph_nodes_queue; n; n = n->next_needed)
582 if (n == node)
583 break;
584 if (!n)
585 node->reachable = 0;
589 notice_global_symbol (decl);
590 node->decl = decl;
591 node->local.finalized = true;
592 if (node->nested)
593 lower_nested_functions (decl);
594 gcc_assert (!node->nested);
596 /* If not unit at a time, then we need to create the call graph
597 now, so that called functions can be queued and emitted now. */
598 if (!flag_unit_at_a_time)
600 cgraph_analyze_function (node);
601 cgraph_decide_inlining_incrementally (node);
604 if (decide_is_function_needed (node, decl))
605 cgraph_mark_needed_node (node);
607 /* If not unit at a time, go ahead and emit everything we've found
608 to be reachable at this time. */
609 if (!nested)
611 if (!cgraph_assemble_pending_functions ())
612 ggc_collect ();
615 /* If we've not yet emitted decl, tell the debug info about it. */
616 if (!TREE_ASM_WRITTEN (decl))
617 (*debug_hooks->deferred_inline_function) (decl);
619 /* Possibly warn about unused parameters. */
620 if (warn_unused_parameter)
621 do_warn_unused_parameter (decl);
624 /* Walk tree and record all calls. Called via walk_tree. */
625 static tree
626 record_call_1 (tree *tp, int *walk_subtrees, void *data)
628 tree t = *tp;
630 switch (TREE_CODE (t))
632 case VAR_DECL:
633 /* ??? Really, we should mark this decl as *potentially* referenced
634 by this function and re-examine whether the decl is actually used
635 after rtl has been generated. */
636 if (TREE_STATIC (t))
638 cgraph_varpool_mark_needed_node (cgraph_varpool_node (t));
639 if (lang_hooks.callgraph.analyze_expr)
640 return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees,
641 data);
643 break;
645 case ADDR_EXPR:
646 if (flag_unit_at_a_time)
648 /* Record dereferences to the functions. This makes the
649 functions reachable unconditionally. */
650 tree decl = TREE_OPERAND (*tp, 0);
651 if (TREE_CODE (decl) == FUNCTION_DECL)
652 cgraph_mark_needed_node (cgraph_node (decl));
654 break;
656 case CALL_EXPR:
658 tree decl = get_callee_fndecl (*tp);
659 if (decl && TREE_CODE (decl) == FUNCTION_DECL)
661 cgraph_create_edge (data, cgraph_node (decl), *tp);
663 /* When we see a function call, we don't want to look at the
664 function reference in the ADDR_EXPR that is hanging from
665 the CALL_EXPR we're examining here, because we would
666 conclude incorrectly that the function's address could be
667 taken by something that is not a function call. So only
668 walk the function parameter list, skip the other subtrees. */
670 walk_tree (&TREE_OPERAND (*tp, 1), record_call_1, data,
671 visited_nodes);
672 *walk_subtrees = 0;
674 break;
677 default:
678 /* Save some cycles by not walking types and declaration as we
679 won't find anything useful there anyway. */
680 if (IS_TYPE_OR_DECL_P (*tp))
682 *walk_subtrees = 0;
683 break;
686 if ((unsigned int) TREE_CODE (t) >= LAST_AND_UNUSED_TREE_CODE)
687 return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees, data);
688 break;
691 return NULL;
694 /* Create cgraph edges for function calls inside BODY from NODE. */
696 void
697 cgraph_create_edges (struct cgraph_node *node, tree body)
699 /* The nodes we're interested in are never shared, so walk
700 the tree ignoring duplicates. */
701 visited_nodes = htab_create (37, htab_hash_pointer,
702 htab_eq_pointer, NULL);
703 walk_tree (&body, record_call_1, node, visited_nodes);
704 htab_delete (visited_nodes);
705 visited_nodes = NULL;
708 static bool error_found;
710 /* Callbrack of verify_cgraph_node. Check that all call_exprs have cgraph
711 nodes. */
713 static tree
714 verify_cgraph_node_1 (tree *tp, int *walk_subtrees, void *data)
716 tree t = *tp;
717 tree decl;
719 if (TREE_CODE (t) == CALL_EXPR && (decl = get_callee_fndecl (t)))
721 struct cgraph_edge *e = cgraph_edge (data, t);
722 if (e)
724 if (e->aux)
726 error ("Shared call_expr:");
727 debug_tree (t);
728 error_found = true;
730 if (e->callee->decl != cgraph_node (decl)->decl)
732 error ("Edge points to wrong declaration:");
733 debug_tree (e->callee->decl);
734 fprintf (stderr," Instead of:");
735 debug_tree (decl);
737 e->aux = (void *)1;
739 else
741 error ("Missing callgraph edge for call expr:");
742 debug_tree (t);
743 error_found = true;
747 /* Save some cycles by not walking types and declaration as we
748 won't find anything useful there anyway. */
749 if (IS_TYPE_OR_DECL_P (*tp))
750 *walk_subtrees = 0;
752 return NULL_TREE;
755 /* Verify cgraph nodes of given cgraph node. */
756 void
757 verify_cgraph_node (struct cgraph_node *node)
759 struct cgraph_edge *e;
760 struct cgraph_node *main_clone;
762 timevar_push (TV_CGRAPH_VERIFY);
763 error_found = false;
764 for (e = node->callees; e; e = e->next_callee)
765 if (e->aux)
767 error ("Aux field set for edge %s->%s",
768 cgraph_node_name (e->caller), cgraph_node_name (e->callee));
769 error_found = true;
771 for (e = node->callers; e; e = e->next_caller)
773 if (!e->inline_failed)
775 if (node->global.inlined_to
776 != (e->caller->global.inlined_to
777 ? e->caller->global.inlined_to : e->caller))
779 error ("Inlined_to pointer is wrong");
780 error_found = true;
782 if (node->callers->next_caller)
784 error ("Multiple inline callers");
785 error_found = true;
788 else
789 if (node->global.inlined_to)
791 error ("Inlined_to pointer set for noninline callers");
792 error_found = true;
795 if (!node->callers && node->global.inlined_to)
797 error ("Inlined_to pointer is set but no predecesors found");
798 error_found = true;
800 if (node->global.inlined_to == node)
802 error ("Inlined_to pointer reffers to itself");
803 error_found = true;
806 for (main_clone = cgraph_node (node->decl); main_clone;
807 main_clone = main_clone->next_clone)
808 if (main_clone == node)
809 break;
810 if (!node)
812 error ("Node not found in DECL_ASSEMBLER_NAME hash");
813 error_found = true;
816 if (node->analyzed
817 && DECL_SAVED_TREE (node->decl) && !TREE_ASM_WRITTEN (node->decl)
818 && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to))
820 walk_tree_without_duplicates (&DECL_SAVED_TREE (node->decl),
821 verify_cgraph_node_1, node);
822 for (e = node->callees; e; e = e->next_callee)
824 if (!e->aux)
826 error ("Edge %s->%s has no corresponding call_expr",
827 cgraph_node_name (e->caller),
828 cgraph_node_name (e->callee));
829 error_found = true;
831 e->aux = 0;
834 if (error_found)
836 dump_cgraph_node (stderr, node);
837 internal_error ("verify_cgraph_node failed.");
839 timevar_pop (TV_CGRAPH_VERIFY);
842 /* Verify whole cgraph structure. */
843 void
844 verify_cgraph (void)
846 struct cgraph_node *node;
848 if (sorrycount || errorcount)
849 return;
851 for (node = cgraph_nodes; node; node = node->next)
852 verify_cgraph_node (node);
855 /* Analyze the function scheduled to be output. */
856 static void
857 cgraph_analyze_function (struct cgraph_node *node)
859 tree decl = node->decl;
860 struct cgraph_edge *e;
862 current_function_decl = decl;
864 /* First kill forward declaration so reverse inlining works properly. */
865 cgraph_create_edges (node, DECL_SAVED_TREE (decl));
867 node->local.inlinable = tree_inlinable_function_p (decl);
868 node->local.self_insns = estimate_num_insns (DECL_SAVED_TREE (decl));
869 if (node->local.inlinable)
870 node->local.disregard_inline_limits
871 = lang_hooks.tree_inlining.disregard_inline_limits (decl);
872 for (e = node->callers; e; e = e->next_caller)
874 if (node->local.redefined_extern_inline)
875 e->inline_failed = N_("redefined extern inline functions are not "
876 "considered for inlining");
877 else if (!node->local.inlinable)
878 e->inline_failed = N_("function not inlinable");
879 else
880 e->inline_failed = N_("function not considered for inlining");
882 if (flag_really_no_inline && !node->local.disregard_inline_limits)
883 node->local.inlinable = 0;
884 /* Inlining characteristics are maintained by the cgraph_mark_inline. */
885 node->global.insns = node->local.self_insns;
887 node->analyzed = true;
888 current_function_decl = NULL;
891 /* Analyze the whole compilation unit once it is parsed completely. */
893 void
894 cgraph_finalize_compilation_unit (void)
896 struct cgraph_node *node;
898 if (!flag_unit_at_a_time)
900 cgraph_assemble_pending_functions ();
901 return;
904 cgraph_varpool_assemble_pending_decls ();
905 if (!quiet_flag)
906 fprintf (stderr, "\nAnalyzing compilation unit\n");
908 timevar_push (TV_CGRAPH);
909 if (cgraph_dump_file)
911 fprintf (cgraph_dump_file, "Initial entry points:");
912 for (node = cgraph_nodes; node; node = node->next)
913 if (node->needed && DECL_SAVED_TREE (node->decl))
914 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
915 fprintf (cgraph_dump_file, "\n");
918 /* Propagate reachability flag and lower representation of all reachable
919 functions. In the future, lowering will introduce new functions and
920 new entry points on the way (by template instantiation and virtual
921 method table generation for instance). */
922 while (cgraph_nodes_queue)
924 struct cgraph_edge *edge;
925 tree decl = cgraph_nodes_queue->decl;
927 node = cgraph_nodes_queue;
928 cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
929 node->next_needed = NULL;
931 /* ??? It is possible to create extern inline function and later using
932 weak alas attribute to kill its body. See
933 gcc.c-torture/compile/20011119-1.c */
934 if (!DECL_SAVED_TREE (decl))
935 continue;
937 gcc_assert (!node->analyzed && node->reachable);
938 gcc_assert (DECL_SAVED_TREE (decl));
940 cgraph_analyze_function (node);
942 for (edge = node->callees; edge; edge = edge->next_callee)
943 if (!edge->callee->reachable)
944 cgraph_mark_reachable_node (edge->callee);
946 cgraph_varpool_assemble_pending_decls ();
949 /* Collect entry points to the unit. */
951 if (cgraph_dump_file)
953 fprintf (cgraph_dump_file, "Unit entry points:");
954 for (node = cgraph_nodes; node; node = node->next)
955 if (node->needed && DECL_SAVED_TREE (node->decl))
956 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
957 fprintf (cgraph_dump_file, "\n\nInitial ");
958 dump_cgraph (cgraph_dump_file);
961 if (cgraph_dump_file)
962 fprintf (cgraph_dump_file, "\nReclaiming functions:");
964 for (node = cgraph_nodes; node; node = node->next)
966 tree decl = node->decl;
968 if (!node->reachable && DECL_SAVED_TREE (decl))
970 if (cgraph_dump_file)
971 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
972 cgraph_remove_node (node);
974 else
975 node->next_needed = NULL;
977 if (cgraph_dump_file)
979 fprintf (cgraph_dump_file, "\n\nReclaimed ");
980 dump_cgraph (cgraph_dump_file);
982 ggc_collect ();
983 timevar_pop (TV_CGRAPH);
985 /* Figure out what functions we want to assemble. */
987 static void
988 cgraph_mark_functions_to_output (void)
990 struct cgraph_node *node;
992 for (node = cgraph_nodes; node; node = node->next)
994 tree decl = node->decl;
995 struct cgraph_edge *e;
997 gcc_assert (!node->output);
999 for (e = node->callers; e; e = e->next_caller)
1000 if (e->inline_failed)
1001 break;
1003 /* We need to output all local functions that are used and not
1004 always inlined, as well as those that are reachable from
1005 outside the current compilation unit. */
1006 if (DECL_SAVED_TREE (decl)
1007 && !node->global.inlined_to
1008 && (node->needed
1009 || (e && node->reachable))
1010 && !TREE_ASM_WRITTEN (decl)
1011 && !DECL_EXTERNAL (decl))
1012 node->output = 1;
1013 else
1015 /* We should've reclaimed all functions that are not needed. */
1016 #ifdef ENABLE_CHECKING
1017 if (!node->global.inlined_to && DECL_SAVED_TREE (decl)
1018 && !DECL_EXTERNAL (decl))
1020 dump_cgraph_node (stderr, node);
1021 internal_error ("failed to reclaim unneeded function");
1023 #endif
1024 gcc_assert (node->global.inlined_to || !DECL_SAVED_TREE (decl)
1025 || DECL_EXTERNAL (decl));
1032 /* Expand function specified by NODE. */
1034 static void
1035 cgraph_expand_function (struct cgraph_node *node)
1037 tree decl = node->decl;
1039 /* We ought to not compile any inline clones. */
1040 gcc_assert (!node->global.inlined_to);
1042 if (flag_unit_at_a_time)
1043 announce_function (decl);
1045 /* Generate RTL for the body of DECL. */
1046 lang_hooks.callgraph.expand_function (decl);
1048 /* Make sure that BE didn't give up on compiling. */
1049 /* ??? Can happen with nested function of extern inline. */
1050 gcc_assert (TREE_ASM_WRITTEN (node->decl));
1052 current_function_decl = NULL;
1053 if (!cgraph_preserve_function_body_p (node->decl))
1055 DECL_SAVED_TREE (node->decl) = NULL;
1056 DECL_STRUCT_FUNCTION (node->decl) = NULL;
1057 DECL_INITIAL (node->decl) = error_mark_node;
1058 /* Eliminate all call edges. This is important so the call_expr no longer
1059 points to the dead function body. */
1060 while (node->callees)
1061 cgraph_remove_edge (node->callees);
1065 /* Fill array order with all nodes with output flag set in the reverse
1066 topological order. */
1068 static int
1069 cgraph_postorder (struct cgraph_node **order)
1071 struct cgraph_node *node, *node2;
1072 int stack_size = 0;
1073 int order_pos = 0;
1074 struct cgraph_edge *edge, last;
1076 struct cgraph_node **stack =
1077 xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
1079 /* We have to deal with cycles nicely, so use a depth first traversal
1080 output algorithm. Ignore the fact that some functions won't need
1081 to be output and put them into order as well, so we get dependencies
1082 right through intline functions. */
1083 for (node = cgraph_nodes; node; node = node->next)
1084 node->aux = NULL;
1085 for (node = cgraph_nodes; node; node = node->next)
1086 if (!node->aux)
1088 node2 = node;
1089 if (!node->callers)
1090 node->aux = &last;
1091 else
1092 node->aux = node->callers;
1093 while (node2)
1095 while (node2->aux != &last)
1097 edge = node2->aux;
1098 if (edge->next_caller)
1099 node2->aux = edge->next_caller;
1100 else
1101 node2->aux = &last;
1102 if (!edge->caller->aux)
1104 if (!edge->caller->callers)
1105 edge->caller->aux = &last;
1106 else
1107 edge->caller->aux = edge->caller->callers;
1108 stack[stack_size++] = node2;
1109 node2 = edge->caller;
1110 break;
1113 if (node2->aux == &last)
1115 order[order_pos++] = node2;
1116 if (stack_size)
1117 node2 = stack[--stack_size];
1118 else
1119 node2 = NULL;
1123 free (stack);
1124 return order_pos;
1127 struct searchc_env {
1128 struct cgraph_node **stack;
1129 int stack_size;
1130 struct cgraph_node **result;
1131 int order_pos;
1132 splay_tree nodes_marked_new;
1133 bool reduce;
1134 int count;
1137 struct dfs_info {
1138 int dfn_number;
1139 int low_link;
1140 bool new;
1141 bool on_stack;
1144 /* This is an implementation of Tarjan's strongly connected region
1145 finder as reprinted in Aho Hopcraft and Ullman's The Design and
1146 Analysis of Computer Programs (1975) pages 192-193. This version
1147 has been customized for cgraph_nodes. The env parameter is because
1148 it is recursive and there are no nested functions here. This
1149 function should only be called from itself or
1150 cgraph_reduced_inorder. ENV is a stack env and would be
1151 unnecessary if C had nested functions. V is the node to start
1152 searching from. */
1154 static void
1155 searchc (struct searchc_env* env, struct cgraph_node *v)
1157 struct cgraph_edge *edge;
1158 struct dfs_info *v_info = v->aux;
1160 /* mark node as old */
1161 v_info->new = false;
1162 splay_tree_remove (env->nodes_marked_new, v->uid);
1164 v_info->dfn_number = env->count;
1165 v_info->low_link = env->count;
1166 env->count++;
1167 env->stack[(env->stack_size)++] = v;
1168 v_info->on_stack = true;
1170 for (edge = v->callers; edge; edge = edge->next_caller)
1172 struct dfs_info * w_info;
1173 struct cgraph_node *w = edge->caller;
1174 /* skip the nodes that we are supposed to ignore */
1175 if (w->aux)
1177 w_info = w->aux;
1178 if (w_info->new)
1180 searchc (env, w);
1181 v_info->low_link =
1182 (v_info->low_link < w_info->low_link) ?
1183 v_info->low_link : w_info->low_link;
1185 else
1186 if ((w_info->dfn_number < v_info->dfn_number)
1187 && (w_info->on_stack))
1188 v_info->low_link =
1189 (w_info->dfn_number < v_info->low_link) ?
1190 w_info->dfn_number : v_info->low_link;
1195 if (v_info->low_link == v_info->dfn_number)
1197 struct cgraph_node *last = NULL;
1198 struct cgraph_node *x;
1199 struct dfs_info *x_info;
1200 do {
1201 x = env->stack[--(env->stack_size)];
1202 x_info = x->aux;
1203 x_info->on_stack = false;
1205 if (env->reduce)
1207 x->next_cycle = last;
1208 last = x;
1210 else
1211 env->result[env->order_pos++] = x;
1213 while (v != x);
1214 if (env->reduce)
1215 env->result[env->order_pos++] = v;
1219 /* Topsort the call graph by caller relation. Put the result in ORDER.
1221 The REDUCE flag is true if you want the cycles reduced to single
1222 nodes. Only consider nodes that have the output bit set. */
1224 static int
1225 cgraph_reduced_inorder (struct cgraph_node **order, bool reduce)
1227 struct cgraph_node *node;
1228 struct searchc_env env;
1229 splay_tree_node result;
1230 env.stack = xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
1231 env.stack_size = 0;
1232 env.result = order;
1233 env.order_pos = 0;
1234 env.nodes_marked_new = splay_tree_new (splay_tree_compare_ints, 0, 0);
1235 env.count = 1;
1236 env.reduce = reduce;
1238 for (node = cgraph_nodes; node; node = node->next)
1239 if (node->output)
1241 struct dfs_info *info = xcalloc (1, sizeof (struct dfs_info));
1242 info->new = true;
1243 info->on_stack = false;
1244 node->aux = info;
1245 node->next_cycle = NULL;
1247 splay_tree_insert (env.nodes_marked_new,
1248 node->uid, (splay_tree_value)node);
1250 else
1251 node->aux = NULL;
1252 result = splay_tree_min (env.nodes_marked_new);
1253 while (result)
1255 node = (struct cgraph_node *)result->value;
1256 searchc (&env, node);
1257 result = splay_tree_min (env.nodes_marked_new);
1259 splay_tree_delete (env.nodes_marked_new);
1260 free (env.stack);
1262 for (node = cgraph_nodes; node; node = node->next)
1263 if (node->aux)
1265 free (node->aux);
1266 node->aux = NULL;
1268 return env.order_pos;
1271 /* Perform reachability analysis and reclaim all unreachable nodes.
1272 This function also remove unneeded bodies of extern inline functions
1273 and thus needs to be done only after inlining decisions has been made. */
1274 static bool
1275 cgraph_remove_unreachable_nodes (void)
1277 struct cgraph_node *first = (void *) 1;
1278 struct cgraph_node *node;
1279 bool changed = false;
1280 int insns = 0;
1282 #ifdef ENABLE_CHECKING
1283 verify_cgraph ();
1284 #endif
1285 if (cgraph_dump_file)
1286 fprintf (cgraph_dump_file, "\nReclaiming functions:");
1287 #ifdef ENABLE_CHECKING
1288 for (node = cgraph_nodes; node; node = node->next)
1289 gcc_assert (!node->aux);
1290 #endif
1291 for (node = cgraph_nodes; node; node = node->next)
1292 if (node->needed && !node->global.inlined_to
1293 && (!DECL_EXTERNAL (node->decl) || !node->analyzed))
1295 node->aux = first;
1296 first = node;
1298 else
1299 gcc_assert (!node->aux);
1301 /* Perform reachability analysis. As a special case do not consider
1302 extern inline functions not inlined as live because we won't output
1303 them at all. */
1304 while (first != (void *) 1)
1306 struct cgraph_edge *e;
1307 node = first;
1308 first = first->aux;
1310 for (e = node->callees; e; e = e->next_callee)
1311 if (!e->callee->aux
1312 && node->analyzed
1313 && (!e->inline_failed || !e->callee->analyzed
1314 || !DECL_EXTERNAL (e->callee->decl)))
1316 e->callee->aux = first;
1317 first = e->callee;
1321 /* Remove unreachable nodes. Extern inline functions need special care;
1322 Unreachable extern inline functions shall be removed.
1323 Reachable extern inline functions we never inlined shall get their bodies
1324 eliminated.
1325 Reachable extern inline functions we sometimes inlined will be turned into
1326 unanalyzed nodes so they look like for true extern functions to the rest
1327 of code. Body of such functions is released via remove_node once the
1328 inline clones are eliminated. */
1329 for (node = cgraph_nodes; node; node = node->next)
1331 if (!node->aux)
1333 int local_insns;
1334 tree decl = node->decl;
1336 node->global.inlined_to = NULL;
1337 if (DECL_STRUCT_FUNCTION (decl))
1338 local_insns = node->local.self_insns;
1339 else
1340 local_insns = 0;
1341 if (cgraph_dump_file)
1342 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1343 if (!node->analyzed || !DECL_EXTERNAL (node->decl))
1344 cgraph_remove_node (node);
1345 else
1347 struct cgraph_edge *e;
1349 for (e = node->callers; e; e = e->next_caller)
1350 if (e->caller->aux)
1351 break;
1352 if (e || node->needed)
1354 struct cgraph_node *clone;
1356 for (clone = node->next_clone; clone;
1357 clone = clone->next_clone)
1358 if (clone->aux)
1359 break;
1360 if (!clone)
1362 DECL_SAVED_TREE (node->decl) = NULL;
1363 DECL_STRUCT_FUNCTION (node->decl) = NULL;
1364 DECL_INITIAL (node->decl) = error_mark_node;
1366 while (node->callees)
1367 cgraph_remove_edge (node->callees);
1368 node->analyzed = false;
1370 else
1371 cgraph_remove_node (node);
1373 if (!DECL_SAVED_TREE (decl))
1374 insns += local_insns;
1375 changed = true;
1378 for (node = cgraph_nodes; node; node = node->next)
1379 node->aux = NULL;
1380 if (cgraph_dump_file)
1381 fprintf (cgraph_dump_file, "\nReclaimed %i insns", insns);
1382 return changed;
1385 /* Estimate size of the function after inlining WHAT into TO. */
1387 static int
1388 cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to,
1389 struct cgraph_node *what)
1391 return (what->global.insns - INSNS_PER_CALL) * times + to->global.insns;
1394 /* Estimate the growth caused by inlining NODE into all callees. */
1396 static int
1397 cgraph_estimate_growth (struct cgraph_node *node)
1399 int growth = 0;
1400 struct cgraph_edge *e;
1402 for (e = node->callers; e; e = e->next_caller)
1403 if (e->inline_failed)
1404 growth += (cgraph_estimate_size_after_inlining (1, e->caller, node)
1405 - e->caller->global.insns);
1407 /* ??? Wrong for self recursive functions or cases where we decide to not
1408 inline for different reasons, but it is not big deal as in that case
1409 we will keep the body around, but we will also avoid some inlining. */
1410 if (!node->needed && !DECL_EXTERNAL (node->decl))
1411 growth -= node->global.insns;
1413 return growth;
1416 /* E is expected to be an edge being inlined. Clone destination node of
1417 the edge and redirect it to the new clone.
1418 DUPLICATE is used for bookkeeping on whether we are actually creating new
1419 clones or re-using node originally representing out-of-line function call.
1421 void
1422 cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate)
1424 struct cgraph_node *n;
1426 /* We may eliminate the need for out-of-line copy to be output. In that
1427 case just go ahead and re-use it. */
1428 if (!e->callee->callers->next_caller
1429 && (!e->callee->needed || DECL_EXTERNAL (e->callee->decl))
1430 && duplicate
1431 && flag_unit_at_a_time)
1433 gcc_assert (!e->callee->global.inlined_to);
1434 if (!DECL_EXTERNAL (e->callee->decl))
1435 overall_insns -= e->callee->global.insns, nfunctions_inlined++;
1436 duplicate = 0;
1438 else if (duplicate)
1440 n = cgraph_clone_node (e->callee);
1441 cgraph_redirect_edge_callee (e, n);
1444 if (e->caller->global.inlined_to)
1445 e->callee->global.inlined_to = e->caller->global.inlined_to;
1446 else
1447 e->callee->global.inlined_to = e->caller;
1449 /* Recursively clone all bodies. */
1450 for (e = e->callee->callees; e; e = e->next_callee)
1451 if (!e->inline_failed)
1452 cgraph_clone_inlined_nodes (e, duplicate);
1455 /* Mark edge E as inlined and update callgraph accordingly. */
1457 void
1458 cgraph_mark_inline_edge (struct cgraph_edge *e)
1460 int old_insns = 0, new_insns = 0;
1461 struct cgraph_node *to = NULL, *what;
1463 gcc_assert (e->inline_failed);
1464 e->inline_failed = NULL;
1466 if (!e->callee->global.inlined && flag_unit_at_a_time)
1467 DECL_POSSIBLY_INLINED (e->callee->decl) = true;
1468 e->callee->global.inlined = true;
1470 cgraph_clone_inlined_nodes (e, true);
1472 what = e->callee;
1474 /* Now update size of caller and all functions caller is inlined into. */
1475 for (;e && !e->inline_failed; e = e->caller->callers)
1477 old_insns = e->caller->global.insns;
1478 new_insns = cgraph_estimate_size_after_inlining (1, e->caller,
1479 what);
1480 gcc_assert (new_insns >= 0);
1481 to = e->caller;
1482 to->global.insns = new_insns;
1484 gcc_assert (what->global.inlined_to == to);
1485 overall_insns += new_insns - old_insns;
1486 ncalls_inlined++;
1489 /* Mark all calls of EDGE->CALLEE inlined into EDGE->CALLER.
1490 Return following unredirected edge in the list of callers
1491 of EDGE->CALLEE */
1493 static struct cgraph_edge *
1494 cgraph_mark_inline (struct cgraph_edge *edge)
1496 struct cgraph_node *to = edge->caller;
1497 struct cgraph_node *what = edge->callee;
1498 struct cgraph_edge *e, *next;
1499 int times = 0;
1501 /* Look for all calls, mark them inline and clone recursively
1502 all inlined functions. */
1503 for (e = what->callers; e; e = next)
1505 next = e->next_caller;
1506 if (e->caller == to && e->inline_failed)
1508 cgraph_mark_inline_edge (e);
1509 if (e == edge)
1510 edge = next;
1511 times++;
1514 gcc_assert (times);
1515 return edge;
1518 /* Return false when inlining WHAT into TO is not good idea
1519 as it would cause too large growth of function bodies. */
1521 static bool
1522 cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what,
1523 const char **reason)
1525 int times = 0;
1526 struct cgraph_edge *e;
1527 int newsize;
1528 int limit;
1530 if (to->global.inlined_to)
1531 to = to->global.inlined_to;
1533 for (e = to->callees; e; e = e->next_callee)
1534 if (e->callee == what)
1535 times++;
1537 /* When inlining large function body called once into small function,
1538 take the inlined function as base for limiting the growth. */
1539 if (to->local.self_insns > what->local.self_insns)
1540 limit = to->local.self_insns;
1541 else
1542 limit = what->local.self_insns;
1544 limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;
1546 newsize = cgraph_estimate_size_after_inlining (times, to, what);
1547 if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
1548 && newsize > limit)
1550 if (reason)
1551 *reason = N_("--param large-function-growth limit reached");
1552 return false;
1554 return true;
1557 /* Return true when function N is small enough to be inlined. */
1559 static bool
1560 cgraph_default_inline_p (struct cgraph_node *n)
1562 if (!DECL_INLINE (n->decl) || !DECL_SAVED_TREE (n->decl))
1563 return false;
1564 if (DECL_DECLARED_INLINE_P (n->decl))
1565 return n->global.insns < MAX_INLINE_INSNS_SINGLE;
1566 else
1567 return n->global.insns < MAX_INLINE_INSNS_AUTO;
1570 /* Return true when inlining WHAT would create recursive inlining.
1571 We call recursive inlining all cases where same function appears more than
1572 once in the single recursion nest path in the inline graph. */
1574 static bool
1575 cgraph_recursive_inlining_p (struct cgraph_node *to,
1576 struct cgraph_node *what,
1577 const char **reason)
1579 bool recursive;
1580 if (to->global.inlined_to)
1581 recursive = what->decl == to->global.inlined_to->decl;
1582 else
1583 recursive = what->decl == to->decl;
1584 /* Marking recursive function inline has sane semantic and thus we should
1585 not warn on it. */
1586 if (recursive && reason)
1587 *reason = (what->local.disregard_inline_limits
1588 ? N_("recursive inlining") : "");
1589 return recursive;
1592 /* Recompute heap nodes for each of callees. */
1593 static void
1594 update_callee_keys (fibheap_t heap, struct fibnode **heap_node,
1595 struct cgraph_node *node)
1597 struct cgraph_edge *e;
1599 for (e = node->callees; e; e = e->next_callee)
1600 if (e->inline_failed && heap_node[e->callee->uid])
1601 fibheap_replace_key (heap, heap_node[e->callee->uid],
1602 cgraph_estimate_growth (e->callee));
1603 else if (!e->inline_failed)
1604 update_callee_keys (heap, heap_node, e->callee);
1607 /* Enqueue all recursive calls from NODE into queue linked via aux pointers
1608 in between FIRST and LAST. WHERE is used for bookkeeping while looking
1609 int calls inlined within NODE. */
1610 static void
1611 lookup_recursive_calls (struct cgraph_node *node, struct cgraph_node *where,
1612 struct cgraph_edge **first, struct cgraph_edge **last)
1614 struct cgraph_edge *e;
1615 for (e = where->callees; e; e = e->next_callee)
1616 if (e->callee == node)
1618 if (!*first)
1619 *first = e;
1620 else
1621 (*last)->aux = e;
1622 *last = e;
1624 for (e = where->callees; e; e = e->next_callee)
1625 if (!e->inline_failed)
1626 lookup_recursive_calls (node, e->callee, first, last);
1629 /* Decide on recursive inlining: in the case function has recursive calls,
1630 inline until body size reaches given argument. */
1631 static void
1632 cgraph_decide_recursive_inlining (struct cgraph_node *node)
1634 int limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO);
1635 int max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO);
1636 struct cgraph_edge *first_call = NULL, *last_call = NULL;
1637 struct cgraph_edge *last_in_current_depth;
1638 struct cgraph_edge *e;
1639 struct cgraph_node *master_clone;
1640 int depth = 0;
1641 int n = 0;
1643 if (DECL_DECLARED_INLINE_P (node->decl))
1645 limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE);
1646 max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH);
1649 /* Make sure that function is small enough to be considered for inlining. */
1650 if (!max_depth
1651 || cgraph_estimate_size_after_inlining (1, node, node) >= limit)
1652 return;
1653 lookup_recursive_calls (node, node, &first_call, &last_call);
1654 if (!first_call)
1655 return;
1657 if (cgraph_dump_file)
1658 fprintf (cgraph_dump_file,
1659 "\nPerforming recursive inlining on %s\n",
1660 cgraph_node_name (node));
1662 /* We need original clone to copy around. */
1663 master_clone = cgraph_clone_node (node);
1664 master_clone->needed = true;
1665 for (e = master_clone->callees; e; e = e->next_callee)
1666 if (!e->inline_failed)
1667 cgraph_clone_inlined_nodes (e, true);
1669 /* Do the inlining and update list of recursive call during process. */
1670 last_in_current_depth = last_call;
1671 while (first_call
1672 && cgraph_estimate_size_after_inlining (1, node, master_clone) <= limit)
1674 struct cgraph_edge *curr = first_call;
1676 first_call = first_call->aux;
1677 curr->aux = NULL;
1679 cgraph_redirect_edge_callee (curr, master_clone);
1680 cgraph_mark_inline_edge (curr);
1681 lookup_recursive_calls (node, curr->callee, &first_call, &last_call);
1683 if (last_in_current_depth
1684 && ++depth >= max_depth)
1685 break;
1686 n++;
1689 /* Cleanup queue pointers. */
1690 while (first_call)
1692 struct cgraph_edge *next = first_call->aux;
1693 first_call->aux = NULL;
1694 first_call = next;
1696 if (cgraph_dump_file)
1697 fprintf (cgraph_dump_file,
1698 "\n Inlined %i times, body grown from %i to %i insns\n", n,
1699 master_clone->global.insns, node->global.insns);
1701 /* Remove master clone we used for inlining. We rely that clones inlined
1702 into master clone gets queued just before master clone so we don't
1703 need recursion. */
1704 for (node = cgraph_nodes; node != master_clone;
1705 node = node->next)
1706 if (node->global.inlined_to == master_clone)
1707 cgraph_remove_node (node);
1708 cgraph_remove_node (master_clone);
1711 /* Set inline_failed for all callers of given function to REASON. */
1713 static void
1714 cgraph_set_inline_failed (struct cgraph_node *node, const char *reason)
1716 struct cgraph_edge *e;
1718 if (cgraph_dump_file)
1719 fprintf (cgraph_dump_file, "Inlining failed: %s\n", reason);
1720 for (e = node->callers; e; e = e->next_caller)
1721 if (e->inline_failed)
1722 e->inline_failed = reason;
1725 /* We use greedy algorithm for inlining of small functions:
1726 All inline candidates are put into prioritized heap based on estimated
1727 growth of the overall number of instructions and then update the estimates.
1729 INLINED and INLINED_CALEES are just pointers to arrays large enough
1730 to be passed to cgraph_inlined_into and cgraph_inlined_callees. */
1732 static void
1733 cgraph_decide_inlining_of_small_functions (void)
1735 struct cgraph_node *node;
1736 fibheap_t heap = fibheap_new ();
1737 struct fibnode **heap_node =
1738 xcalloc (cgraph_max_uid, sizeof (struct fibnode *));
1739 int max_insns = ((HOST_WIDEST_INT) initial_insns
1740 * (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100);
1742 /* Put all inline candidates into the heap. */
1744 for (node = cgraph_nodes; node; node = node->next)
1746 if (!node->local.inlinable || !node->callers
1747 || node->local.disregard_inline_limits)
1748 continue;
1750 if (!cgraph_default_inline_p (node))
1752 cgraph_set_inline_failed (node,
1753 N_("--param max-inline-insns-single limit reached"));
1754 continue;
1756 heap_node[node->uid] =
1757 fibheap_insert (heap, cgraph_estimate_growth (node), node);
1760 if (cgraph_dump_file)
1761 fprintf (cgraph_dump_file, "\nDeciding on smaller functions:\n");
1762 while (overall_insns <= max_insns && (node = fibheap_extract_min (heap)))
1764 struct cgraph_edge *e, *next;
1765 int old_insns = overall_insns;
1767 heap_node[node->uid] = NULL;
1768 if (cgraph_dump_file)
1769 fprintf (cgraph_dump_file,
1770 "\nConsidering %s with %i insns\n"
1771 " Estimated growth is %+i insns.\n",
1772 cgraph_node_name (node), node->global.insns,
1773 cgraph_estimate_growth (node));
1774 if (!cgraph_default_inline_p (node))
1776 cgraph_set_inline_failed (node,
1777 N_("--param max-inline-insns-single limit reached after inlining into the callee"));
1778 continue;
1780 for (e = node->callers; e; e = next)
1782 next = e->next_caller;
1783 if (e->inline_failed)
1785 struct cgraph_node *where;
1787 if (cgraph_recursive_inlining_p (e->caller, e->callee,
1788 &e->inline_failed)
1789 || !cgraph_check_inline_limits (e->caller, e->callee,
1790 &e->inline_failed))
1792 if (cgraph_dump_file)
1793 fprintf (cgraph_dump_file, " Not inlining into %s:%s.\n",
1794 cgraph_node_name (e->caller), e->inline_failed);
1795 continue;
1797 next = cgraph_mark_inline (e);
1798 where = e->caller;
1799 if (where->global.inlined_to)
1800 where = where->global.inlined_to;
1802 if (heap_node[where->uid])
1803 fibheap_replace_key (heap, heap_node[where->uid],
1804 cgraph_estimate_growth (where));
1806 if (cgraph_dump_file)
1807 fprintf (cgraph_dump_file,
1808 " Inlined into %s which now has %i insns.\n",
1809 cgraph_node_name (e->caller),
1810 e->caller->global.insns);
1814 cgraph_decide_recursive_inlining (node);
1816 /* Similarly all functions called by the function we just inlined
1817 are now called more times; update keys. */
1818 update_callee_keys (heap, heap_node, node);
1820 if (cgraph_dump_file)
1821 fprintf (cgraph_dump_file,
1822 " Inlined for a net change of %+i insns.\n",
1823 overall_insns - old_insns);
1825 while ((node = fibheap_extract_min (heap)) != NULL)
1826 if (!node->local.disregard_inline_limits)
1827 cgraph_set_inline_failed (node, N_("--param inline-unit-growth limit reached"));
1828 fibheap_delete (heap);
1829 free (heap_node);
1832 /* Decide on the inlining. We do so in the topological order to avoid
1833 expenses on updating data structures. */
1835 static void
1836 cgraph_decide_inlining (void)
1838 struct cgraph_node *node;
1839 int nnodes;
1840 struct cgraph_node **order =
1841 xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
1842 int old_insns = 0;
1843 int i;
1845 for (node = cgraph_nodes; node; node = node->next)
1846 initial_insns += node->local.self_insns;
1847 overall_insns = initial_insns;
1849 nnodes = cgraph_postorder (order);
1851 if (cgraph_dump_file)
1852 fprintf (cgraph_dump_file,
1853 "\nDeciding on inlining. Starting with %i insns.\n",
1854 initial_insns);
1856 for (node = cgraph_nodes; node; node = node->next)
1857 node->aux = 0;
1859 if (cgraph_dump_file)
1860 fprintf (cgraph_dump_file, "\nInlining always_inline functions:\n");
1862 /* In the first pass mark all always_inline edges. Do this with a priority
1863 so none of our later choices will make this impossible. */
1864 for (i = nnodes - 1; i >= 0; i--)
1866 struct cgraph_edge *e, *next;
1868 node = order[i];
1870 if (!node->local.disregard_inline_limits)
1871 continue;
1872 if (cgraph_dump_file)
1873 fprintf (cgraph_dump_file,
1874 "\nConsidering %s %i insns (always inline)\n",
1875 cgraph_node_name (node), node->global.insns);
1876 old_insns = overall_insns;
1877 for (e = node->callers; e; e = next)
1879 next = e->next_caller;
1880 if (!e->inline_failed)
1881 continue;
1882 if (cgraph_recursive_inlining_p (e->caller, e->callee,
1883 &e->inline_failed))
1884 continue;
1885 cgraph_mark_inline_edge (e);
1886 if (cgraph_dump_file)
1887 fprintf (cgraph_dump_file,
1888 " Inlined into %s which now has %i insns.\n",
1889 cgraph_node_name (e->caller),
1890 e->caller->global.insns);
1892 if (cgraph_dump_file)
1893 fprintf (cgraph_dump_file,
1894 " Inlined for a net change of %+i insns.\n",
1895 overall_insns - old_insns);
1898 if (!flag_really_no_inline)
1900 cgraph_decide_inlining_of_small_functions ();
1902 if (cgraph_dump_file)
1903 fprintf (cgraph_dump_file, "\nDeciding on functions called once:\n");
1905 /* And finally decide what functions are called once. */
1907 for (i = nnodes - 1; i >= 0; i--)
1909 node = order[i];
1911 if (node->callers && !node->callers->next_caller && !node->needed
1912 && node->local.inlinable && node->callers->inline_failed
1913 && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl))
1915 bool ok = true;
1916 struct cgraph_node *node1;
1918 /* Verify that we won't duplicate the caller. */
1919 for (node1 = node->callers->caller;
1920 node1->callers && !node1->callers->inline_failed
1921 && ok; node1 = node1->callers->caller)
1922 if (node1->callers->next_caller || node1->needed)
1923 ok = false;
1924 if (ok)
1926 if (cgraph_dump_file)
1927 fprintf (cgraph_dump_file,
1928 "\nConsidering %s %i insns.\n"
1929 " Called once from %s %i insns.\n",
1930 cgraph_node_name (node), node->global.insns,
1931 cgraph_node_name (node->callers->caller),
1932 node->callers->caller->global.insns);
1934 old_insns = overall_insns;
1936 if (cgraph_check_inline_limits (node->callers->caller, node,
1937 NULL))
1939 cgraph_mark_inline (node->callers);
1940 if (cgraph_dump_file)
1941 fprintf (cgraph_dump_file,
1942 " Inlined into %s which now has %i insns"
1943 " for a net change of %+i insns.\n",
1944 cgraph_node_name (node->callers->caller),
1945 node->callers->caller->global.insns,
1946 overall_insns - old_insns);
1948 else
1950 if (cgraph_dump_file)
1951 fprintf (cgraph_dump_file,
1952 " Inline limit reached, not inlined.\n");
1959 /* We will never output extern functions we didn't inline.
1960 ??? Perhaps we can prevent accounting of growth of external
1961 inline functions. */
1962 cgraph_remove_unreachable_nodes ();
1964 if (cgraph_dump_file)
1965 fprintf (cgraph_dump_file,
1966 "\nInlined %i calls, eliminated %i functions, "
1967 "%i insns turned to %i insns.\n\n",
1968 ncalls_inlined, nfunctions_inlined, initial_insns,
1969 overall_insns);
1970 free (order);
1973 /* Decide on the inlining. We do so in the topological order to avoid
1974 expenses on updating data structures. */
1976 static void
1977 cgraph_decide_inlining_incrementally (struct cgraph_node *node)
1979 struct cgraph_edge *e;
1981 /* First of all look for always inline functions. */
1982 for (e = node->callees; e; e = e->next_callee)
1983 if (e->callee->local.disregard_inline_limits
1984 && e->inline_failed
1985 && !cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)
1986 /* ??? It is possible that renaming variable removed the function body
1987 in duplicate_decls. See gcc.c-torture/compile/20011119-2.c */
1988 && DECL_SAVED_TREE (e->callee->decl))
1989 cgraph_mark_inline (e);
1991 /* Now do the automatic inlining. */
1992 if (!flag_really_no_inline)
1993 for (e = node->callees; e; e = e->next_callee)
1994 if (e->callee->local.inlinable
1995 && e->inline_failed
1996 && !e->callee->local.disregard_inline_limits
1997 && !cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)
1998 && cgraph_check_inline_limits (node, e->callee, &e->inline_failed)
1999 && DECL_SAVED_TREE (e->callee->decl))
2001 if (cgraph_default_inline_p (e->callee))
2002 cgraph_mark_inline (e);
2003 else
2004 e->inline_failed
2005 = N_("--param max-inline-insns-single limit reached");
2010 /* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
2012 bool
2013 cgraph_inline_p (struct cgraph_edge *e, const char **reason)
2015 *reason = e->inline_failed;
2016 return !e->inline_failed;
2019 /* FIXME this needs to be enhanced. If we are compiling a single
2020 module this returns true if the variable is a module level static,
2021 but if we are doing whole program compilation, this could return
2022 true if TREE_PUBLIC is true. */
2023 /* Return true if the variable T is the right kind of static variable to
2024 perform compilation unit scope escape analysis. */
2026 static inline
2027 bool has_proper_scope_for_analysis (tree t)
2029 return (TREE_STATIC(t)) && !(TREE_PUBLIC(t)) && !(TREE_THIS_VOLATILE(t));
2032 /* Check to see if T is a read or address of operation on a static var
2033 we are interested in analyzing. FN is passed in to get access to
2034 its bit vectors. */
2036 static void
2037 check_rhs_var (struct cgraph_node *fn, tree t)
2039 if (TREE_CODE (t) == ADDR_EXPR)
2041 tree x = TREE_OPERAND (t, 0);
2042 if ((TREE_CODE (x) == VAR_DECL) && has_proper_scope_for_analysis (x))
2044 if (cgraph_dump_file)
2045 fprintf (cgraph_dump_file, "\nadding address:%s",
2046 lang_hooks.decl_printable_name (x, 2));
2048 /* FIXME -- PROFILE-RESTRUCTURE: Change the call from
2049 DECL_UID to get the uid from the var_ann field. */
2050 bitmap_set_bit (module_statics_escape, DECL_UID (x));
2053 t = get_base_address (t);
2054 if (!t) return;
2055 if ((TREE_CODE (t) == VAR_DECL) && has_proper_scope_for_analysis (t))
2057 if (cgraph_dump_file)
2058 fprintf (cgraph_dump_file, "\nadding rhs:%s",
2059 lang_hooks.decl_printable_name (t, 2));
2060 /* FIXME -- PROFILE-RESTRUCTURE: Change the call from
2061 DECL_UID to get the uid from the var_ann field. */
2062 bitmap_set_bit (fn->static_vars_info->local->statics_read_by_decl_uid,
2063 DECL_UID (t));
2067 /* Check to see if T is an assignment to a static var we are
2068 interrested in analyzing. FN is passed in to get access to its bit
2069 vectors.
2072 static void
2073 check_lhs_var (struct cgraph_node *fn, tree t)
2075 t = get_base_address (t);
2076 if (!t) return;
2077 if ((TREE_CODE (t) == VAR_DECL) && has_proper_scope_for_analysis (t))
2079 if (cgraph_dump_file)
2080 fprintf (cgraph_dump_file, "\nadding lhs:%s",
2081 lang_hooks.decl_printable_name (t, 2));
2083 /* FIXME -- PROFILE-RESTRUCTURE: Change the call from
2084 DECL_UID to get the uid from the var_ann field. */
2085 bitmap_set_bit (fn->static_vars_info->local->statics_written_by_decl_uid,
2086 DECL_UID (t));
2090 /* This is a scaled down version of get_asm_expr_operands from
2091 tree_ssa_operands.c. The version there runs much later and assumes
2092 that aliasing information is already available. Here we are just
2093 trying to find if the set of inputs and outputs contain references
2094 or address of operations to local static variables. FN is the
2095 function being analyzed and STMT is the actual asm statement. */
2097 static void
2098 get_asm_expr_operands (struct cgraph_node * fn, tree stmt)
2100 int noutputs = list_length (ASM_OUTPUTS (stmt));
2101 const char **oconstraints
2102 = (const char **) alloca ((noutputs) * sizeof (const char *));
2103 int i;
2104 tree link;
2105 const char *constraint;
2106 bool allows_mem, allows_reg, is_inout;
2108 for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link))
2110 oconstraints[i] = constraint
2111 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
2112 parse_output_constraint (&constraint, i, 0, 0,
2113 &allows_mem, &allows_reg, &is_inout);
2115 /* Memory operands are addressable. Note that STMT needs the
2116 address of this operand. */
2117 if (!allows_reg && allows_mem)
2119 check_lhs_var (fn, TREE_VALUE (link));
2123 for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
2125 constraint
2126 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
2127 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
2128 oconstraints, &allows_mem, &allows_reg);
2130 /* Memory operands are addressable. Note that STMT needs the
2131 address of this operand. */
2132 if (!allows_reg && allows_mem)
2134 check_rhs_var (fn, TREE_VALUE (link));
2138 for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
2139 if (TREE_VALUE (link) == memory_identifier)
2141 /* Abandon all hope, ye who enter here. */
2142 local_static_vars_info_t l = fn->static_vars_info->local;
2143 bitmap_a_or_b (l->statics_read_by_decl_uid,
2144 l->statics_read_by_decl_uid,
2145 all_module_statics);
2146 bitmap_a_or_b (l->statics_written_by_decl_uid,
2147 l->statics_written_by_decl_uid,
2148 all_module_statics);
2153 /* Check the parameters of a function call from CALLER to CALL_EXPR to
2154 see if any of them are static vars. Also check to see if this is
2155 either an indirect call, a call outside the compilation unit, or
2156 has special attributes that effect the clobbers. The caller
2157 parameter is the tree node for the caller and the second operand is
2158 the tree node for the entire call expression. */
2159 static void
2160 process_call_for_static_vars(struct cgraph_node * caller, tree call_expr)
2162 int flags = call_expr_flags(call_expr);
2163 tree operandList = TREE_OPERAND (call_expr, 1);
2164 tree operand;
2166 for (operand = operandList;
2167 operand != NULL_TREE;
2168 operand = TREE_CHAIN (operand))
2170 tree argument = TREE_VALUE (operand);
2171 check_rhs_var (caller, argument);
2174 /* Const and pure functions have less clobber effects than other
2175 functions so we process these first. Otherwise if it is a call
2176 outside the compilation unit or an indirect call we punt. This
2177 leaves local calls which will be processed by following the call
2178 graph. */
2179 if (flags & ECF_CONST)
2180 return;
2181 else if (flags & ECF_PURE)
2182 caller->local.calls_write_all = true;
2183 else
2185 tree callee_t = get_callee_fndecl (call_expr);
2186 if (callee_t == NULL)
2188 /* Indirect call. */
2189 caller->local.calls_read_all = true;
2190 caller->local.calls_write_all = true;
2192 else
2194 struct cgraph_node* callee = cgraph_node(callee_t);
2196 if (callee->local.external)
2198 caller->local.calls_read_all = true;
2199 caller->local.calls_write_all = true;
2205 /* FIXME -- PROFILE-RESTRUCTURE: Change to walk by explicitly walking
2206 the basic blocks rather than calling walktree. */
2208 /* Walk tree and record all calls. Called via walk_tree. FIXME When
2209 this is moved into the tree-profiling-branch, and is dealing with
2210 low GIMPLE, this routine should be changed to use tree iterators
2211 rather than being a walk_tree callback. The data is the function
2212 that is being scanned. */
2213 /* TP is the part of the tree currently under the
2214 microscope. WALK_SUBTREES is part of the walk_tree api but is
2215 unused here. DATA is cgraph_node of the function being walked. */
2217 static tree
2218 scan_for_static_refs (tree *tp,
2219 int *walk_subtrees ATTRIBUTE_UNUSED,
2220 void *data)
2222 struct cgraph_node *fn = data;
2223 tree t = *tp;
2225 switch (TREE_CODE (t))
2227 case MODIFY_EXPR:
2229 /* First look on the lhs and see what variable is stored to */
2230 tree rhs = TREE_OPERAND (t, 1);
2231 check_lhs_var (fn, TREE_OPERAND (t, 0));
2232 /* Next check the operands on the rhs to see if they are ok. */
2233 switch (TREE_CODE_CLASS (TREE_CODE (rhs))) {
2234 case tcc_binary:
2235 check_rhs_var (fn, TREE_OPERAND (rhs, 0));
2236 check_rhs_var (fn, TREE_OPERAND (rhs, 1));
2237 break;
2238 case tcc_unary:
2239 case tcc_reference:
2240 check_rhs_var (fn, TREE_OPERAND (rhs, 0));
2241 break;
2242 case tcc_declaration:
2243 check_rhs_var (fn, rhs);
2244 break;
2245 case tcc_expression:
2246 switch (TREE_CODE (rhs)) {
2247 case ADDR_EXPR:
2248 check_rhs_var (fn, rhs);
2249 break;
2250 case CALL_EXPR:
2251 process_call_for_static_vars (fn, rhs);
2252 break;
2253 default:
2254 break;
2256 break;
2257 default:
2258 break;
2261 break;
2264 case CALL_EXPR:
2265 process_call_for_static_vars (fn, t);
2266 break;
2268 case ASM_EXPR:
2269 get_asm_expr_operands (fn, t);
2270 break;
2272 default:
2273 break;
2275 return NULL;
2279 /* This is the main routine for finding the reference patterns for
2280 global variables within a function FN */
2281 static void
2282 cgraph_characterize_statics_local (struct cgraph_node *fn)
2284 tree decl = fn->decl;
2285 static_vars_info_t info = new_static_vars_info(fn, false);
2286 local_static_vars_info_t l = info->local;
2289 /* The nodes we're interested in are never shared, so walk
2290 the tree ignoring duplicates. */
2291 visited_nodes = htab_create (37, htab_hash_pointer,
2292 htab_eq_pointer, NULL);
2294 /* FIXME -- PROFILE-RESTRUCTURE: Remove creation of _decl_uid vars. */
2295 l->statics_read_by_decl_uid = BITMAP_GGC_ALLOC ();
2296 l->statics_written_by_decl_uid = BITMAP_GGC_ALLOC ();
2298 if (cgraph_dump_file)
2299 fprintf (cgraph_dump_file, "\n local analysis of %s", cgraph_node_name (fn));
2301 walk_tree (&DECL_SAVED_TREE (decl), scan_for_static_refs, fn, visited_nodes);
2302 htab_delete (visited_nodes);
2303 visited_nodes = NULL;
2306 /* Lookup the tree node for the static variable that has UID and
2307 conver the name to a string for debugging. */
2308 static const char *
2309 cgraph_get_static_name_by_uid (int index)
2311 splay_tree_node stn = splay_tree_lookup (static_vars_to_consider_by_uid, index);
2312 if (stn)
2313 return lang_hooks.decl_printable_name ((tree)(stn->value), 2);
2314 return NULL;
2317 /* Clear out any the static variable with uid INDEX from further
2318 consideration because it escapes (i.e. has had its address
2319 taken). */
2320 static void
2321 clear_static_vars_maps (int index)
2323 splay_tree_node stn = splay_tree_lookup (static_vars_to_consider_by_uid, index);
2324 if (stn)
2326 splay_tree_remove (static_vars_to_consider_by_tree, stn->value);
2327 splay_tree_remove (static_vars_to_consider_by_uid, index);
2331 /* FIXME -- PROFILE-RESTRUCTURE: Change all *_decl_uid to *_ann_uid. */
2333 /* Or in all of the bits from every callee into X, the caller's, bit
2334 vector. There are several cases to check to avoid the sparse
2335 bitmap oring. */
2336 static void
2337 cgraph_propagate_bits (struct cgraph_node *x)
2339 static_vars_info_t x_info = x->static_vars_info;
2340 global_static_vars_info_t x_global = x_info->global;
2342 struct cgraph_edge *e;
2343 for (e = x->callees; e; e = e->next_callee)
2345 struct cgraph_node *y = e->callee;
2347 /* We are only going to look at edges that point to nodes that
2348 have their output bit set. */
2349 if (y->output)
2351 static_vars_info_t y_info;
2352 global_static_vars_info_t y_global;
2353 y_info = y->static_vars_info;
2354 y_global = y_info->global;
2356 if (x_global->statics_read_by_decl_uid != all_module_statics)
2358 if (y_global->statics_read_by_decl_uid == all_module_statics)
2359 x_global->statics_read_by_decl_uid = all_module_statics;
2360 /* Skip bitmaps that are pointer equal to node's bitmap
2361 (no reason to spin within the cycle). */
2362 else if (x_global->statics_read_by_decl_uid != y_global->statics_read_by_decl_uid)
2363 bitmap_a_or_b (x_global->statics_read_by_decl_uid,
2364 x_global->statics_read_by_decl_uid,
2365 y_global->statics_read_by_decl_uid);
2368 if (x_global->statics_written_by_decl_uid != all_module_statics)
2370 if (y_global->statics_written_by_decl_uid == all_module_statics)
2371 x_global->statics_written_by_decl_uid = all_module_statics;
2372 /* Skip bitmaps that are pointer equal to node's bitmap
2373 (no reason to spin within the cycle). */
2374 else if (x_global->statics_written_by_decl_uid != y_global->statics_written_by_decl_uid)
2375 bitmap_a_or_b (x_global->statics_written_by_decl_uid,
2376 x_global->statics_written_by_decl_uid,
2377 y_global->statics_written_by_decl_uid);
2383 /* FIXME -- PROFILE-RESTRUCTURE: Change all *_decl_uid to *_ann_uid
2384 except where noted below. */
2386 /* The main routine for analyzing global static variable usage. See
2387 comments at top for description. */
2389 static void
2390 cgraph_characterize_statics (void)
2392 struct cgraph_node *node;
2393 struct cgraph_node *w;
2394 struct cgraph_node **order =
2395 xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
2396 int order_pos = 0;
2397 int i;
2399 struct cgraph_varpool_node *vnode;
2400 tree global;
2402 /* get rid of the splay trees from the previous compilation unit. */
2404 static_vars_to_consider_by_tree =
2405 splay_tree_new_ggc (splay_tree_compare_pointers);
2406 static_vars_to_consider_by_uid =
2407 splay_tree_new_ggc (splay_tree_compare_ints);
2409 if (module_statics_escape)
2411 bitmap_clear (module_statics_escape);
2412 bitmap_clear (all_module_statics);
2414 else
2416 module_statics_escape = BITMAP_XMALLOC ();
2417 all_module_statics = BITMAP_GGC_ALLOC ();
2420 /* Find all of the global variables that we wish to analyze. */
2421 for (vnode = cgraph_varpool_nodes_queue; vnode; vnode = vnode->next_needed)
2423 global = vnode->decl;
2424 if ((TREE_CODE (global) == VAR_DECL) &&
2425 has_proper_scope_for_analysis (global))
2427 splay_tree_insert (static_vars_to_consider_by_tree,
2428 (splay_tree_key) global,
2429 (splay_tree_value) global);
2430 /* FIXME -- PROFILE-RESTRUCTURE: Change the call from
2431 DECL_UID to get the uid from the var_ann field. */
2432 splay_tree_insert (static_vars_to_consider_by_uid,
2433 DECL_UID (global), (splay_tree_value)global);
2435 if (cgraph_dump_file)
2436 fprintf (cgraph_dump_file, "\nConsidering global:%s",
2437 lang_hooks.decl_printable_name (global, 2));
2438 /* FIXME -- PROFILE-RESTRUCTURE: Change the call from
2439 DECL_UID to get the uid from the var_ann field. */
2440 bitmap_set_bit (all_module_statics, DECL_UID (global));
2444 order_pos = cgraph_reduced_inorder (order, false);
2445 if (cgraph_dump_file)
2446 print_order("new", order, order_pos);
2448 for (i = order_pos - 1; i >= 0; i--)
2450 node = order[i];
2452 /* Scan each function to determine the variable usage
2453 patterns. */
2454 cgraph_characterize_statics_local (node);
2457 /* Prune out the variables that were found to behave badly
2458 (i.e. have there address taken). */
2460 int index;
2461 bitmap_iterator bi;
2463 EXECUTE_IF_SET_IN_BITMAP (module_statics_escape, 0, index, bi)
2465 clear_static_vars_maps (index);
2467 bitmap_operation (all_module_statics, all_module_statics,
2468 module_statics_escape, BITMAP_AND_COMPL);
2470 for (i = order_pos - 1; i >= 0; i--)
2472 local_static_vars_info_t l;
2473 node = order[i];
2474 l = node->static_vars_info->local;
2476 bitmap_operation (l->statics_read_by_decl_uid,
2477 l->statics_read_by_decl_uid,
2478 module_statics_escape,
2479 BITMAP_AND_COMPL);
2480 bitmap_operation (l->statics_written_by_decl_uid,
2481 l->statics_written_by_decl_uid,
2482 module_statics_escape,
2483 BITMAP_AND_COMPL);
2487 if (cgraph_dump_file)
2489 for (i = order_pos - 1; i >= 0; i--)
2491 int index;
2492 local_static_vars_info_t l;
2493 bitmap_iterator bi;
2495 node = order[i];
2496 l = node->static_vars_info->local;
2497 fprintf (cgraph_dump_file,
2498 "\nFunction name:%s/%i:",
2499 cgraph_node_name (node), node->uid);
2500 fprintf (cgraph_dump_file, "\n locals read: ");
2501 EXECUTE_IF_SET_IN_BITMAP (l->statics_read_by_decl_uid,
2502 0, index, bi)
2504 fprintf (cgraph_dump_file, "%s ",
2505 cgraph_get_static_name_by_uid (index));
2507 fprintf (cgraph_dump_file, "\n locals written: ");
2508 EXECUTE_IF_SET_IN_BITMAP (l->statics_written_by_decl_uid,
2509 0, index, bi)
2511 fprintf(cgraph_dump_file, "%s ",
2512 cgraph_get_static_name_by_uid (index));
2517 /* Propagate the local information thru the call graph to produce
2518 the global information. All the nodes within a cycle will have
2519 the same info so we collapse cycles first. Then we can do the
2520 propagation in one pass from the leaves to the roots. */
2521 order_pos = cgraph_reduced_inorder (order, true);
2522 for (i = order_pos - 1; i >= 0; i--)
2524 static_vars_info_t node_info;
2525 global_static_vars_info_t node_g =
2526 ggc_calloc (1, sizeof (struct global_static_vars_info_d));
2527 local_static_vars_info_t node_l;
2530 bool read_all;
2531 bool write_all;
2533 node = order[i];
2534 node_info = node->static_vars_info;
2535 node_info->global = node_g;
2536 node_l = node_info->local;
2538 read_all = node->local.calls_read_all;
2539 write_all = node->local.calls_write_all;
2541 /* If any node in a cycle is calls_read_all or calls_write_all
2542 they all are. */
2543 w = node->next_cycle;
2544 while (w)
2546 read_all |= w->local.calls_read_all;
2547 write_all |= w->local.calls_write_all;
2548 w = w->next_cycle;
2551 /* Initialized the bitmaps for the reduced nodes */
2552 if (read_all)
2553 node_g->statics_read_by_decl_uid = all_module_statics;
2554 else
2556 node_g->statics_read_by_decl_uid = BITMAP_GGC_ALLOC ();
2557 bitmap_copy (node_g->statics_read_by_decl_uid,
2558 node_l->statics_read_by_decl_uid);
2561 if (write_all)
2562 node_g->statics_written_by_decl_uid = all_module_statics;
2563 else
2565 node_g->statics_written_by_decl_uid = BITMAP_GGC_ALLOC ();
2566 bitmap_copy (node_g->statics_written_by_decl_uid,
2567 node_l->statics_written_by_decl_uid);
2570 w = node->next_cycle;
2571 while (w)
2573 /* All nodes within a cycle share the same global info bitmaps. */
2574 static_vars_info_t w_info = w->static_vars_info;
2575 local_static_vars_info_t w_l;
2577 w_info->global = node_g;
2578 w_l = w_info->local;
2580 /* These global bitmaps are initialized from the local info
2581 of all of the nodes in the region. However there is no
2582 need to do any work if the bitmaps were set to
2583 all_module_statics. */
2584 if (!read_all)
2585 bitmap_a_or_b (node_g->statics_read_by_decl_uid,
2586 node_g->statics_read_by_decl_uid,
2587 w_l->statics_read_by_decl_uid);
2588 if (!write_all)
2589 bitmap_a_or_b (node_g->statics_written_by_decl_uid,
2590 node_g->statics_written_by_decl_uid,
2591 w_l->statics_written_by_decl_uid);
2592 w = w->next_cycle;
2595 cgraph_propagate_bits (node);
2597 w = node->next_cycle;
2598 while (w)
2600 cgraph_propagate_bits (w);
2601 w = w->next_cycle;
2605 if (cgraph_dump_file)
2607 for (i = order_pos - 1; i >= 0; i--)
2609 static_vars_info_t node_info;
2610 global_static_vars_info_t node_g;
2611 int index;
2612 bitmap_iterator bi;
2614 node = order[i];
2615 node_info = node->static_vars_info;
2616 node_g = node_info->global;
2617 fprintf (cgraph_dump_file,
2618 "\nFunction name:%s/%i:",
2619 cgraph_node_name (node), node->uid);
2620 w = node->next_cycle;
2621 while (w)
2623 fprintf (cgraph_dump_file, "\n next cycle: %s/%i ",
2624 cgraph_node_name (w), w->uid);
2625 w = w->next_cycle;
2627 fprintf (cgraph_dump_file, "\n globals read: ");
2628 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_read_by_decl_uid,
2629 0, index, bi)
2631 fprintf (cgraph_dump_file, "%s ",
2632 cgraph_get_static_name_by_uid (index));
2634 fprintf (cgraph_dump_file, "\n globals written: ");
2635 EXECUTE_IF_SET_IN_BITMAP (node_g->statics_written_by_decl_uid,
2636 0, index, bi)
2638 fprintf (cgraph_dump_file, "%s ",
2639 cgraph_get_static_name_by_uid (index));
2644 /* Cleanup. */
2645 for (i = order_pos - 1; i >= 0; i--)
2647 static_vars_info_t node_info;
2648 global_static_vars_info_t node_g;
2649 node = order[i];
2650 node_info = node->static_vars_info;
2651 node_g = node_info->global;
2653 node_g->var_anns_valid = false;
2655 /* Create the complimentary sets. These are more useful for
2656 certain apis. */
2657 node_g->statics_not_read_by_decl_uid = BITMAP_GGC_ALLOC ();
2658 node_g->statics_not_written_by_decl_uid = BITMAP_GGC_ALLOC ();
2660 /* FIXME -- PROFILE-RESTRUCTURE: Delete next 4 assignments. */
2661 node_g->statics_read_by_ann_uid = BITMAP_GGC_ALLOC ();
2662 node_g->statics_written_by_ann_uid = BITMAP_GGC_ALLOC ();
2663 node_g->statics_not_read_by_ann_uid = BITMAP_GGC_ALLOC ();
2664 node_g->statics_not_written_by_ann_uid = BITMAP_GGC_ALLOC ();
2666 if (node_g->statics_read_by_decl_uid != all_module_statics)
2668 bitmap_operation (node_g->statics_not_read_by_decl_uid,
2669 all_module_statics,
2670 node_g->statics_read_by_decl_uid,
2671 BITMAP_AND_COMPL);
2674 if (node_g->statics_written_by_decl_uid != all_module_statics)
2675 bitmap_operation (node_g->statics_not_written_by_decl_uid,
2676 all_module_statics,
2677 node_g->statics_written_by_decl_uid,
2678 BITMAP_AND_COMPL);
2680 w = node->next_cycle;
2682 while (w)
2684 struct cgraph_node * last = w;
2685 w = w->next_cycle;
2686 last->next_cycle = NULL;
2690 free (order);
2693 /* Expand all functions that must be output.
2695 Attempt to topologically sort the nodes so function is output when
2696 all called functions are already assembled to allow data to be
2697 propagated across the callgraph. Use a stack to get smaller distance
2698 between a function and its callees (later we may choose to use a more
2699 sophisticated algorithm for function reordering; we will likely want
2700 to use subsections to make the output functions appear in top-down
2701 order). */
2703 static void
2704 cgraph_expand_all_functions (void)
2706 struct cgraph_node *node;
2707 struct cgraph_node **order =
2708 xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
2709 int order_pos = 0, new_order_pos = 0;
2710 int i;
2712 order_pos = cgraph_postorder (order);
2713 gcc_assert (order_pos == cgraph_n_nodes);
2715 /* Garbage collector may remove inline clones we eliminate during
2716 optimization. So we must be sure to not reference them. */
2717 for (i = 0; i < order_pos; i++)
2718 if (order[i]->output)
2719 order[new_order_pos++] = order[i];
2721 for (i = new_order_pos - 1; i >= 0; i--)
2723 node = order[i];
2724 if (node->output)
2726 gcc_assert (node->reachable);
2727 node->output = 0;
2728 cgraph_expand_function (node);
2731 free (order);
2734 /* Mark all local and external functions.
2736 A local function is one whose calls can occur only in the current
2737 compilation unit and all its calls are explicit, so we can change
2738 its calling convention. We simply mark all static functions whose
2739 address is not taken as local.
2741 An external function is one whose body is outside the current
2742 compilation unit. */
2744 static void
2745 cgraph_mark_local_and_external_functions (void)
2747 struct cgraph_node *node;
2749 /* Figure out functions we want to assemble. */
2750 for (node = cgraph_nodes; node; node = node->next)
2752 node->local.local = (!node->needed
2753 && DECL_SAVED_TREE (node->decl)
2754 && !TREE_PUBLIC (node->decl));
2755 node->local.external = (!DECL_SAVED_TREE (node->decl)
2756 && TREE_PUBLIC (node->decl));
2759 if (cgraph_dump_file)
2761 fprintf (cgraph_dump_file, "\nMarking local functions:");
2762 for (node = cgraph_nodes; node; node = node->next)
2763 if (node->local.local)
2764 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
2765 fprintf (cgraph_dump_file, "\n\n");
2767 fprintf (cgraph_dump_file, "\nMarking external functions:");
2768 for (node = cgraph_nodes; node; node = node->next)
2769 if (node->local.external)
2770 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
2771 fprintf (cgraph_dump_file, "\n\n");
2775 /* Return true when function body of DECL still needs to be kept around
2776 for later re-use. */
2777 bool
2778 cgraph_preserve_function_body_p (tree decl)
2780 struct cgraph_node *node;
2781 /* Keep the body; we're going to dump it. */
2782 if (dump_enabled_p (TDI_tree_all))
2783 return true;
2784 if (!cgraph_global_info_ready)
2785 return (DECL_INLINE (decl) && !flag_really_no_inline);
2786 /* Look if there is any clone around. */
2787 for (node = cgraph_node (decl); node; node = node->next_clone)
2788 if (node->global.inlined_to)
2789 return true;
2790 return false;
2793 /* Perform simple optimizations based on callgraph. */
2795 void
2796 cgraph_optimize (void)
2798 #ifdef ENABLE_CHECKING
2799 verify_cgraph ();
2800 #endif
2801 if (!flag_unit_at_a_time)
2802 return;
2803 timevar_push (TV_CGRAPHOPT);
2804 if (!quiet_flag)
2805 fprintf (stderr, "Performing intraprocedural optimizations\n");
2807 cgraph_mark_local_and_external_functions ();
2808 if (cgraph_dump_file)
2810 fprintf (cgraph_dump_file, "Marked ");
2811 dump_cgraph (cgraph_dump_file);
2814 if (flag_inline_trees)
2815 cgraph_decide_inlining ();
2816 cgraph_global_info_ready = true;
2817 if (cgraph_dump_file)
2819 fprintf (cgraph_dump_file, "Optimized ");
2820 dump_cgraph (cgraph_dump_file);
2822 timevar_pop (TV_CGRAPHOPT);
2824 /* Output everything. */
2825 if (!quiet_flag)
2826 fprintf (stderr, "Assembling functions:\n");
2827 #ifdef ENABLE_CHECKING
2828 verify_cgraph ();
2829 #endif
2831 /* This call was moved here from cgraph_expand_all_functions so that
2832 cgraph_characterize_statics could use the output flag of the cgraph
2833 node. */
2835 cgraph_mark_functions_to_output ();
2837 cgraph_characterize_statics ();
2839 cgraph_expand_all_functions ();
2840 if (cgraph_dump_file)
2842 fprintf (cgraph_dump_file, "\nFinal ");
2843 dump_cgraph (cgraph_dump_file);
2845 #ifdef ENABLE_CHECKING
2846 verify_cgraph ();
2847 /* Double check that all inline clones are gone and that all
2848 function bodies have been released from memory. */
2849 if (flag_unit_at_a_time
2850 && !dump_enabled_p (TDI_tree_all)
2851 && !(sorrycount || errorcount))
2853 struct cgraph_node *node;
2854 bool error_found = false;
2856 for (node = cgraph_nodes; node; node = node->next)
2857 if (node->analyzed
2858 && (node->global.inlined_to
2859 || DECL_SAVED_TREE (node->decl)))
2861 error_found = true;
2862 dump_cgraph_node (stderr, node);
2864 if (error_found)
2865 internal_error ("Nodes with no released memory found.");
2867 #endif
2870 /* Generate and emit a static constructor or destructor. WHICH must be
2871 one of 'I' or 'D'. BODY should be a STATEMENT_LIST containing
2872 GENERIC statements. */
2874 void
2875 cgraph_build_static_cdtor (char which, tree body, int priority)
2877 static int counter = 0;
2878 char which_buf[16];
2879 tree decl, name, resdecl;
2881 sprintf (which_buf, "%c_%d", which, counter++);
2882 name = get_file_function_name_long (which_buf);
2884 decl = build_decl (FUNCTION_DECL, name,
2885 build_function_type (void_type_node, void_list_node));
2886 current_function_decl = decl;
2888 resdecl = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
2889 DECL_ARTIFICIAL (resdecl) = 1;
2890 DECL_IGNORED_P (resdecl) = 1;
2891 DECL_RESULT (decl) = resdecl;
2893 allocate_struct_function (decl);
2895 TREE_STATIC (decl) = 1;
2896 TREE_USED (decl) = 1;
2897 DECL_ARTIFICIAL (decl) = 1;
2898 DECL_IGNORED_P (decl) = 1;
2899 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
2900 DECL_SAVED_TREE (decl) = body;
2901 TREE_PUBLIC (decl) = ! targetm.have_ctors_dtors;
2902 DECL_UNINLINABLE (decl) = 1;
2904 DECL_INITIAL (decl) = make_node (BLOCK);
2905 TREE_USED (DECL_INITIAL (decl)) = 1;
2907 DECL_SOURCE_LOCATION (decl) = input_location;
2908 cfun->function_end_locus = input_location;
2910 switch (which)
2912 case 'I':
2913 DECL_STATIC_CONSTRUCTOR (decl) = 1;
2914 break;
2915 case 'D':
2916 DECL_STATIC_DESTRUCTOR (decl) = 1;
2917 break;
2918 default:
2919 gcc_unreachable ();
2922 gimplify_function_tree (decl);
2924 /* ??? We will get called LATE in the compilation process. */
2925 if (cgraph_global_info_ready)
2926 tree_rest_of_compilation (decl);
2927 else
2928 cgraph_finalize_function (decl, 0);
2930 if (targetm.have_ctors_dtors)
2932 void (*fn) (rtx, int);
2934 if (which == 'I')
2935 fn = targetm.asm_out.constructor;
2936 else
2937 fn = targetm.asm_out.destructor;
2938 fn (XEXP (DECL_RTL (decl), 0), priority);
2942 void
2943 init_cgraph (void)
2945 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
2946 memory_identifier = get_identifier("memory");
2948 #include "gt-cgraphunit.h"