1169689Skan/* Callgraph based interprocedural optimizations.
2169689Skan   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3132718Skan   Contributed by Jan Hubicka
4132718Skan
5132718SkanThis file is part of GCC.
6132718Skan
7132718SkanGCC is free software; you can redistribute it and/or modify it under
8132718Skanthe terms of the GNU General Public License as published by the Free
9132718SkanSoftware Foundation; either version 2, or (at your option) any later
10132718Skanversion.
11132718Skan
12132718SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
13132718SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
14132718SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15132718Skanfor more details.
16132718Skan
17132718SkanYou should have received a copy of the GNU General Public License
18132718Skanalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
21132718Skan
22169689Skan/* This module implements main driver of compilation process as well as
23169689Skan   few basic interprocedural optimizers.
24169689Skan
25169689Skan   The main scope of this file is to act as an interface in between
26169689Skan   tree based frontends and the backend (and middle end)
27169689Skan
28169689Skan   The front-end is supposed to use following functionality:
29169689Skan
30169689Skan    - cgraph_finalize_function
31169689Skan
32169689Skan      This function is called once front-end has parsed whole body of function
33169689Skan      and it is certain that the function body nor the declaration will change.
34169689Skan
35169689Skan      (There is one exception needed for implementing GCC extern inline function.)
36169689Skan
37169689Skan    - cgraph_varpool_finalize_variable
38169689Skan
39169689Skan      This function has same behavior as the above but is used for static
40169689Skan      variables.
41169689Skan
42169689Skan    - cgraph_finalize_compilation_unit
43169689Skan
44169689Skan      This function is called once compilation unit is finalized and it will
45169689Skan      no longer change.
46169689Skan
47169689Skan      In the unit-at-a-time the call-graph construction and local function
48169689Skan      analysis takes place here.  Bodies of unreachable functions are released
49169689Skan      to conserve memory usage.
50169689Skan
51169689Skan      ???  The compilation unit in this point of view should be compilation
52169689Skan      unit as defined by the language - for instance C frontend allows multiple
53169689Skan      compilation units to be parsed at once and it should call function each
54169689Skan      time parsing is done so we save memory.
55169689Skan
56169689Skan    - cgraph_optimize
57169689Skan
58169689Skan      In this unit-at-a-time compilation the intra procedural analysis takes
59169689Skan      place here.  In particular the static functions whose address is never
60169689Skan      taken are marked as local.  Backend can then use this information to
61169689Skan      modify calling conventions, do better inlining or similar optimizations.
62169689Skan
63169689Skan    - cgraph_assemble_pending_functions
64169689Skan    - cgraph_varpool_assemble_pending_variables
65169689Skan
66169689Skan      In non-unit-at-a-time mode these functions can be used to force compilation
67169689Skan      of functions or variables that are known to be needed at given stage
68169689Skan      of compilation
69169689Skan
70169689Skan    - cgraph_mark_needed_node
71169689Skan    - cgraph_varpool_mark_needed_node
72169689Skan
73169689Skan      When function or variable is referenced by some hidden way (for instance
74169689Skan      via assembly code and marked by attribute "used"), the call-graph data structure
75169689Skan      must be updated accordingly by this function.
76169689Skan
77169689Skan    - analyze_expr callback
78169689Skan
79169689Skan      This function is responsible for lowering tree nodes not understood by
80169689Skan      generic code into understandable ones or alternatively marking
81169689Skan      callgraph and varpool nodes referenced by the as needed.
82169689Skan
83169689Skan      ??? On the tree-ssa genericizing should take place here and we will avoid
84169689Skan      need for these hooks (replacing them by genericizing hook)
85169689Skan
86169689Skan    - expand_function callback
87169689Skan
88169689Skan      This function is used to expand function and pass it into RTL back-end.
89169689Skan      Front-end should not make any assumptions about when this function can be
90169689Skan      called.  In particular cgraph_assemble_pending_functions,
91169689Skan      cgraph_varpool_assemble_pending_variables, cgraph_finalize_function,
92169689Skan      cgraph_varpool_finalize_function, cgraph_optimize can cause arbitrarily
93169689Skan      previously finalized functions to be expanded.
94169689Skan
95169689Skan    We implement two compilation modes.
96169689Skan
97169689Skan      - unit-at-a-time:  In this mode analyzing of all functions is deferred
98169689Skan	to cgraph_finalize_compilation_unit and expansion into cgraph_optimize.
99169689Skan
100169689Skan	In cgraph_finalize_compilation_unit the reachable functions are
101169689Skan	analyzed.  During analysis the call-graph edges from reachable
102169689Skan	functions are constructed and their destinations are marked as
103169689Skan	reachable.  References to functions and variables are discovered too
104169689Skan	and variables found to be needed output to the assembly file.  Via
105169689Skan	mark_referenced call in assemble_variable functions referenced by
106169689Skan	static variables are noticed too.
107169689Skan
108169689Skan	The intra-procedural information is produced and its existence
109169689Skan	indicated by global_info_ready.  Once this flag is set it is impossible
110169689Skan	to change function from !reachable to reachable and thus
111169689Skan	assemble_variable no longer call mark_referenced.
112169689Skan
113169689Skan	Finally the call-graph is topologically sorted and all reachable functions
114169689Skan	that has not been completely inlined or are not external are output.
115169689Skan
116169689Skan	??? It is possible that reference to function or variable is optimized
117169689Skan	out.  We can not deal with this nicely because topological order is not
118169689Skan	suitable for it.  For tree-ssa we may consider another pass doing
119169689Skan	optimization and re-discovering reachable functions.
120169689Skan
121169689Skan	??? Reorganize code so variables are output very last and only if they
122169689Skan	really has been referenced by produced code, so we catch more cases
123169689Skan	where reference has been optimized out.
124169689Skan
125169689Skan      - non-unit-at-a-time
126169689Skan
127169689Skan	All functions are variables are output as early as possible to conserve
128169689Skan	memory consumption.  This may or may not result in less memory used but
129169689Skan	it is still needed for some legacy code that rely on particular ordering
130169689Skan	of things output from the compiler.
131169689Skan
132169689Skan	Varpool data structures are not used and variables are output directly.
133169689Skan
134169689Skan	Functions are output early using call of
135169689Skan	cgraph_assemble_pending_function from cgraph_finalize_function.  The
136169689Skan	decision on whether function is needed is made more conservative so
137169689Skan	uninlininable static functions are needed too.  During the call-graph
138169689Skan	construction the edge destinations are not marked as reachable and it
139169689Skan	is completely relied upn assemble_variable to mark them.  */
140169689Skan
141169689Skan
142132718Skan#include "config.h"
143132718Skan#include "system.h"
144132718Skan#include "coretypes.h"
145132718Skan#include "tm.h"
146132718Skan#include "tree.h"
147169689Skan#include "rtl.h"
148169689Skan#include "tree-flow.h"
149132718Skan#include "tree-inline.h"
150132718Skan#include "langhooks.h"
151169689Skan#include "pointer-set.h"
152132718Skan#include "toplev.h"
153132718Skan#include "flags.h"
154132718Skan#include "ggc.h"
155132718Skan#include "debug.h"
156132718Skan#include "target.h"
157132718Skan#include "cgraph.h"
158132718Skan#include "diagnostic.h"
159132718Skan#include "timevar.h"
160132718Skan#include "params.h"
161132718Skan#include "fibheap.h"
162132718Skan#include "c-common.h"
163132718Skan#include "intl.h"
164132718Skan#include "function.h"
165169689Skan#include "ipa-prop.h"
166169689Skan#include "tree-gimple.h"
167169689Skan#include "tree-pass.h"
168169689Skan#include "output.h"
169132718Skan
170132718Skanstatic void cgraph_expand_all_functions (void);
171132718Skanstatic void cgraph_mark_functions_to_output (void);
172132718Skanstatic void cgraph_expand_function (struct cgraph_node *);
173169689Skanstatic tree record_reference (tree *, int *, void *);
174169689Skanstatic void cgraph_output_pending_asms (void);
175169689Skanstatic void cgraph_increase_alignment (void);
176132718Skan
177169689Skan/* Lists all assembled variables to be sent to debugger output later on.  */
178169689Skanstatic GTY(()) struct cgraph_varpool_node *cgraph_varpool_assembled_nodes_queue;
179132718Skan
180169689Skan/* Records tree nodes seen in record_reference.  Simply using
181132718Skan   walk_tree_without_duplicates doesn't guarantee each node is visited
182132718Skan   once because it gets a new htab upon each recursive call from
183169689Skan   record_reference itself.  */
184169689Skanstatic struct pointer_set_t *visited_nodes;
185132718Skan
186169689Skanstatic FILE *cgraph_dump_file;
187169689Skan
188132718Skan/* Determine if function DECL is needed.  That is, visible to something
189132718Skan   either outside this translation unit, something magic in the system
190132718Skan   configury, or (if not doing unit-at-a-time) to something we havn't
191132718Skan   seen yet.  */
192132718Skan
193132718Skanstatic bool
194132718Skandecide_is_function_needed (struct cgraph_node *node, tree decl)
195132718Skan{
196169689Skan  tree origin;
197169689Skan  if (MAIN_NAME_P (DECL_NAME (decl))
198169689Skan      && TREE_PUBLIC (decl))
199169689Skan    {
200169689Skan      node->local.externally_visible = true;
201169689Skan      return true;
202169689Skan    }
203169689Skan
204169689Skan  /* If the user told us it is used, then it must be so.  */
205169689Skan  if (node->local.externally_visible)
206169689Skan    return true;
207169689Skan
208169689Skan  if (!flag_unit_at_a_time && lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
209169689Skan    return true;
210169689Skan
211169689Skan  /* ??? If the assembler name is set by hand, it is possible to assemble
212169689Skan     the name later after finalizing the function and the fact is noticed
213169689Skan     in assemble_name then.  This is arguably a bug.  */
214169689Skan  if (DECL_ASSEMBLER_NAME_SET_P (decl)
215169689Skan      && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
216169689Skan    return true;
217169689Skan
218132718Skan  /* If we decided it was needed before, but at the time we didn't have
219132718Skan     the body of the function available, then it's still needed.  We have
220132718Skan     to go back and re-check its dependencies now.  */
221132718Skan  if (node->needed)
222132718Skan    return true;
223132718Skan
224132718Skan  /* Externally visible functions must be output.  The exception is
225169689Skan     COMDAT functions that must be output only when they are needed.
226169689Skan
227169689Skan     When not optimizing, also output the static functions. (see
228169689Skan     PR24561), but don't do so for always_inline functions, functions
229169689Skan     declared inline and nested functions.  These was optimized out
230169689Skan     in the original implementation and it is unclear whether we want
231169689Skan     to change the behavior here.  */
232169689Skan  if (((TREE_PUBLIC (decl)
233169689Skan	|| (!optimize && !node->local.disregard_inline_limits
234169689Skan	    && !DECL_DECLARED_INLINE_P (decl)
235169689Skan	    && !node->origin))
236169689Skan      && !flag_whole_program)
237169689Skan      && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
238132718Skan    return true;
239132718Skan
240132718Skan  /* Constructors and destructors are reachable from the runtime by
241132718Skan     some mechanism.  */
242132718Skan  if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))
243132718Skan    return true;
244132718Skan
245132718Skan  if (flag_unit_at_a_time)
246132718Skan    return false;
247132718Skan
248132718Skan  /* If not doing unit at a time, then we'll only defer this function
249132718Skan     if its marked for inlining.  Otherwise we want to emit it now.  */
250132718Skan
251132718Skan  /* "extern inline" functions are never output locally.  */
252132718Skan  if (DECL_EXTERNAL (decl))
253132718Skan    return false;
254169689Skan  /* Nested functions of extern inline function shall not be emit unless
255169689Skan     we inlined the origin.  */
256169689Skan  for (origin = decl_function_context (decl); origin;
257169689Skan       origin = decl_function_context (origin))
258169689Skan    if (DECL_EXTERNAL (origin))
259169689Skan      return false;
260132718Skan  /* We want to emit COMDAT functions only when absolutely necessary.  */
261132718Skan  if (DECL_COMDAT (decl))
262132718Skan    return false;
263132718Skan  if (!DECL_INLINE (decl)
264132718Skan      || (!node->local.disregard_inline_limits
265132718Skan	  /* When declared inline, defer even the uninlinable functions.
266132718Skan	     This allows them to be eliminated when unused.  */
267169689Skan	  && !DECL_DECLARED_INLINE_P (decl)
268169689Skan	  && (!node->local.inlinable || !cgraph_default_inline_p (node, NULL))))
269132718Skan    return true;
270132718Skan
271132718Skan  return false;
272132718Skan}
273132718Skan
274169689Skan/* Walk the decls we marked as necessary and see if they reference new
275169689Skan   variables or functions and add them into the worklists.  */
276169689Skanstatic bool
277169689Skancgraph_varpool_analyze_pending_decls (void)
278169689Skan{
279169689Skan  bool changed = false;
280169689Skan  timevar_push (TV_CGRAPH);
281169689Skan
282169689Skan  while (cgraph_varpool_first_unanalyzed_node)
283169689Skan    {
284169689Skan      tree decl = cgraph_varpool_first_unanalyzed_node->decl;
285169689Skan
286169689Skan      cgraph_varpool_first_unanalyzed_node->analyzed = true;
287169689Skan
288169689Skan      cgraph_varpool_first_unanalyzed_node = cgraph_varpool_first_unanalyzed_node->next_needed;
289169689Skan
290169689Skan      /* Compute the alignment early so function body expanders are
291169689Skan	 already informed about increased alignment.  */
292169689Skan      align_variable (decl, 0);
293169689Skan
294169689Skan      if (DECL_INITIAL (decl))
295169689Skan	{
296169689Skan	  visited_nodes = pointer_set_create ();
297169689Skan	  walk_tree (&DECL_INITIAL (decl), record_reference, NULL, visited_nodes);
298169689Skan	  pointer_set_destroy (visited_nodes);
299169689Skan	  visited_nodes = NULL;
300169689Skan	}
301169689Skan      changed = true;
302169689Skan    }
303169689Skan  timevar_pop (TV_CGRAPH);
304169689Skan  return changed;
305169689Skan}
306169689Skan
307169689Skan/* Optimization of function bodies might've rendered some variables as
308169689Skan   unnecessary so we want to avoid these from being compiled.
309169689Skan
310169689Skan   This is done by pruning the queue and keeping only the variables that
311169689Skan   really appear needed (ie they are either externally visible or referenced
312169689Skan   by compiled function). Re-doing the reachability analysis on variables
313169689Skan   brings back the remaining variables referenced by these.  */
314169689Skanstatic void
315169689Skancgraph_varpool_remove_unreferenced_decls (void)
316169689Skan{
317169689Skan  struct cgraph_varpool_node *next, *node = cgraph_varpool_nodes_queue;
318169689Skan
319169689Skan  cgraph_varpool_reset_queue ();
320169689Skan
321169689Skan  if (errorcount || sorrycount)
322169689Skan    return;
323169689Skan
324169689Skan  while (node)
325169689Skan    {
326169689Skan      tree decl = node->decl;
327169689Skan      next = node->next_needed;
328169689Skan      node->needed = 0;
329169689Skan
330169689Skan      if (node->finalized
331169689Skan	  && ((DECL_ASSEMBLER_NAME_SET_P (decl)
332169689Skan	       && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
333169689Skan	      || node->force_output
334169689Skan	      || decide_is_variable_needed (node, decl)
335169689Skan	      /* ??? Cgraph does not yet rule the world with an iron hand,
336169689Skan		 and does not control the emission of debug information.
337169689Skan		 After a variable has its DECL_RTL set, we must assume that
338169689Skan		 it may be referenced by the debug information, and we can
339169689Skan		 no longer elide it.  */
340169689Skan	      || DECL_RTL_SET_P (decl)))
341169689Skan	cgraph_varpool_mark_needed_node (node);
342169689Skan
343169689Skan      node = next;
344169689Skan    }
345169689Skan  /* Make sure we mark alias targets as used targets.  */
346169689Skan  finish_aliases_1 ();
347169689Skan  cgraph_varpool_analyze_pending_decls ();
348169689Skan}
349169689Skan
350169689Skan
351132718Skan/* When not doing unit-at-a-time, output all functions enqueued.
352132718Skan   Return true when such a functions were found.  */
353132718Skan
354132718Skanbool
355132718Skancgraph_assemble_pending_functions (void)
356132718Skan{
357132718Skan  bool output = false;
358132718Skan
359132718Skan  if (flag_unit_at_a_time)
360132718Skan    return false;
361132718Skan
362169689Skan  cgraph_output_pending_asms ();
363169689Skan
364132718Skan  while (cgraph_nodes_queue)
365132718Skan    {
366132718Skan      struct cgraph_node *n = cgraph_nodes_queue;
367132718Skan
368132718Skan      cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
369169689Skan      n->next_needed = NULL;
370169689Skan      if (!n->global.inlined_to
371169689Skan	  && !n->alias
372169689Skan	  && !DECL_EXTERNAL (n->decl))
373132718Skan	{
374132718Skan	  cgraph_expand_function (n);
375132718Skan	  output = true;
376132718Skan	}
377132718Skan    }
378132718Skan
379169689Skan  /* Process CGRAPH_EXPAND_QUEUE, these are functions created during
380169689Skan     the expansion process.  Note that this queue may grow as its
381169689Skan     being processed, as the new functions may generate new ones.  */
382169689Skan  while (cgraph_expand_queue)
383169689Skan    {
384169689Skan      struct cgraph_node *n = cgraph_expand_queue;
385169689Skan      cgraph_expand_queue = cgraph_expand_queue->next_needed;
386169689Skan      n->next_needed = NULL;
387169689Skan      cgraph_finalize_function (n->decl, false);
388169689Skan      output = true;
389169689Skan    }
390169689Skan
391132718Skan  return output;
392132718Skan}
393132718Skan
394169689Skan
395169689Skan/* As an GCC extension we allow redefinition of the function.  The
396169689Skan   semantics when both copies of bodies differ is not well defined.
397169689Skan   We replace the old body with new body so in unit at a time mode
398169689Skan   we always use new body, while in normal mode we may end up with
399169689Skan   old body inlined into some functions and new body expanded and
400169689Skan   inlined in others.
401169689Skan
402169689Skan   ??? It may make more sense to use one body for inlining and other
403169689Skan   body for expanding the function but this is difficult to do.  */
404169689Skan
405169689Skanstatic void
406169689Skancgraph_reset_node (struct cgraph_node *node)
407169689Skan{
408169689Skan  /* If node->output is set, then this is a unit-at-a-time compilation
409169689Skan     and we have already begun whole-unit analysis.  This is *not*
410169689Skan     testing for whether we've already emitted the function.  That
411169689Skan     case can be sort-of legitimately seen with real function
412169689Skan     redefinition errors.  I would argue that the front end should
413169689Skan     never present us with such a case, but don't enforce that for now.  */
414169689Skan  gcc_assert (!node->output);
415169689Skan
416169689Skan  /* Reset our data structures so we can analyze the function again.  */
417169689Skan  memset (&node->local, 0, sizeof (node->local));
418169689Skan  memset (&node->global, 0, sizeof (node->global));
419169689Skan  memset (&node->rtl, 0, sizeof (node->rtl));
420169689Skan  node->analyzed = false;
421169689Skan  node->local.redefined_extern_inline = true;
422169689Skan  node->local.finalized = false;
423169689Skan
424169689Skan  if (!flag_unit_at_a_time)
425169689Skan    {
426169689Skan      struct cgraph_node *n, *next;
427169689Skan
428169689Skan      for (n = cgraph_nodes; n; n = next)
429169689Skan	{
430169689Skan	  next = n->next;
431169689Skan	  if (n->global.inlined_to == node)
432169689Skan	    cgraph_remove_node (n);
433169689Skan	}
434169689Skan    }
435169689Skan
436169689Skan  cgraph_node_remove_callees (node);
437169689Skan
438169689Skan  /* We may need to re-queue the node for assembling in case
439169689Skan     we already proceeded it and ignored as not needed.  */
440169689Skan  if (node->reachable && !flag_unit_at_a_time)
441169689Skan    {
442169689Skan      struct cgraph_node *n;
443169689Skan
444169689Skan      for (n = cgraph_nodes_queue; n; n = n->next_needed)
445169689Skan	if (n == node)
446169689Skan	  break;
447169689Skan      if (!n)
448169689Skan	node->reachable = 0;
449169689Skan    }
450169689Skan}
451169689Skan
452169689Skanstatic void
453169689Skancgraph_lower_function (struct cgraph_node *node)
454169689Skan{
455169689Skan  if (node->lowered)
456169689Skan    return;
457169689Skan  tree_lowering_passes (node->decl);
458169689Skan  node->lowered = true;
459169689Skan}
460169689Skan
461261188Spfg/* APPLE LOCAL begin radar 6305545 */
462261188Spfg/** lower_if_nested_functions - This routine is called from cplus side only.
463261188Spfg    Its purpose is to lower block helper (or any other nested function)
464261188Spfg    which may have been nested in a constructor or destructor. We have to
465261188Spfg    do this because structors are cloned and are not lowered themselves (which
466261188Spfg    is the only way to lower the nested functions). */
467261188Spfgvoid
468261188Spfglower_if_nested_functions (tree decl)
469261188Spfg{
470261188Spfg    lower_nested_functions (decl, true);
471261188Spfg}
472261188Spfg/* APPLE LOCAL end radar 6305545 */
473261188Spfg
474132718Skan/* DECL has been parsed.  Take it, queue it, compile it at the whim of the
475132718Skan   logic in effect.  If NESTED is true, then our caller cannot stand to have
476132718Skan   the garbage collector run at the moment.  We would need to either create
477132718Skan   a new GC context, or just not compile right now.  */
478132718Skan
479132718Skanvoid
480132718Skancgraph_finalize_function (tree decl, bool nested)
481132718Skan{
482132718Skan  struct cgraph_node *node = cgraph_node (decl);
483132718Skan
484132718Skan  if (node->local.finalized)
485169689Skan    cgraph_reset_node (node);
486132718Skan
487132718Skan  notice_global_symbol (decl);
488132718Skan  node->decl = decl;
489132718Skan  node->local.finalized = true;
490169689Skan  node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
491169689Skan  if (node->nested)
492261188Spfg    /* APPLE LOCAL radar 6305545 */
493261188Spfg    lower_nested_functions (decl, false);
494169689Skan  gcc_assert (!node->nested);
495132718Skan
496132718Skan  /* If not unit at a time, then we need to create the call graph
497132718Skan     now, so that called functions can be queued and emitted now.  */
498132718Skan  if (!flag_unit_at_a_time)
499132718Skan    {
500132718Skan      cgraph_analyze_function (node);
501169689Skan      cgraph_decide_inlining_incrementally (node, false);
502132718Skan    }
503132718Skan
504132718Skan  if (decide_is_function_needed (node, decl))
505132718Skan    cgraph_mark_needed_node (node);
506132718Skan
507169689Skan  /* Since we reclaim unreachable nodes at the end of every language
508169689Skan     level unit, we need to be conservative about possible entry points
509169689Skan     there.  */
510169689Skan  if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)))
511169689Skan    cgraph_mark_reachable_node (node);
512169689Skan
513132718Skan  /* If not unit at a time, go ahead and emit everything we've found
514132718Skan     to be reachable at this time.  */
515132718Skan  if (!nested)
516132718Skan    {
517132718Skan      if (!cgraph_assemble_pending_functions ())
518132718Skan	ggc_collect ();
519132718Skan    }
520132718Skan
521132718Skan  /* If we've not yet emitted decl, tell the debug info about it.  */
522132718Skan  if (!TREE_ASM_WRITTEN (decl))
523132718Skan    (*debug_hooks->deferred_inline_function) (decl);
524132718Skan
525169689Skan  /* Possibly warn about unused parameters.  */
526169689Skan  if (warn_unused_parameter)
527169689Skan    do_warn_unused_parameter (decl);
528132718Skan}
529132718Skan
530132718Skan/* Walk tree and record all calls.  Called via walk_tree.  */
531132718Skanstatic tree
532169689Skanrecord_reference (tree *tp, int *walk_subtrees, void *data)
533132718Skan{
534132718Skan  tree t = *tp;
535132718Skan
536132718Skan  switch (TREE_CODE (t))
537132718Skan    {
538132718Skan    case VAR_DECL:
539132718Skan      /* ??? Really, we should mark this decl as *potentially* referenced
540132718Skan	 by this function and re-examine whether the decl is actually used
541132718Skan	 after rtl has been generated.  */
542169689Skan      if (TREE_STATIC (t) || DECL_EXTERNAL (t))
543169689Skan	{
544169689Skan	  cgraph_varpool_mark_needed_node (cgraph_varpool_node (t));
545169689Skan	  if (lang_hooks.callgraph.analyze_expr)
546169689Skan	    return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees,
547169689Skan						      data);
548169689Skan	}
549132718Skan      break;
550132718Skan
551169689Skan    case FDESC_EXPR:
552132718Skan    case ADDR_EXPR:
553132718Skan      if (flag_unit_at_a_time)
554132718Skan	{
555132718Skan	  /* Record dereferences to the functions.  This makes the
556132718Skan	     functions reachable unconditionally.  */
557132718Skan	  tree decl = TREE_OPERAND (*tp, 0);
558132718Skan	  if (TREE_CODE (decl) == FUNCTION_DECL)
559132718Skan	    cgraph_mark_needed_node (cgraph_node (decl));
560132718Skan	}
561132718Skan      break;
562132718Skan
563132718Skan    default:
564132718Skan      /* Save some cycles by not walking types and declaration as we
565132718Skan	 won't find anything useful there anyway.  */
566169689Skan      if (IS_TYPE_OR_DECL_P (*tp))
567132718Skan	{
568132718Skan	  *walk_subtrees = 0;
569132718Skan	  break;
570132718Skan	}
571132718Skan
572132718Skan      if ((unsigned int) TREE_CODE (t) >= LAST_AND_UNUSED_TREE_CODE)
573169689Skan	return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees, data);
574132718Skan      break;
575132718Skan    }
576132718Skan
577132718Skan  return NULL;
578132718Skan}
579132718Skan
580169689Skan/* Create cgraph edges for function calls inside BODY from NODE.  */
581132718Skan
582169689Skanstatic void
583169689Skancgraph_create_edges (struct cgraph_node *node, tree body)
584132718Skan{
585169689Skan  basic_block bb;
586169689Skan
587169689Skan  struct function *this_cfun = DECL_STRUCT_FUNCTION (body);
588169689Skan  block_stmt_iterator bsi;
589169689Skan  tree step;
590169689Skan  visited_nodes = pointer_set_create ();
591169689Skan
592169689Skan  /* Reach the trees by walking over the CFG, and note the
593169689Skan     enclosing basic-blocks in the call edges.  */
594169689Skan  FOR_EACH_BB_FN (bb, this_cfun)
595169689Skan    for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
596169689Skan      {
597169689Skan	tree stmt = bsi_stmt (bsi);
598169689Skan	tree call = get_call_expr_in (stmt);
599169689Skan	tree decl;
600169689Skan
601169689Skan	if (call && (decl = get_callee_fndecl (call)))
602169689Skan	  {
603169689Skan	    cgraph_create_edge (node, cgraph_node (decl), stmt,
604169689Skan				bb->count,
605169689Skan				bb->loop_depth);
606169689Skan	    walk_tree (&TREE_OPERAND (call, 1),
607169689Skan		       record_reference, node, visited_nodes);
608169689Skan	    if (TREE_CODE (stmt) == MODIFY_EXPR)
609169689Skan	      walk_tree (&TREE_OPERAND (stmt, 0),
610169689Skan			 record_reference, node, visited_nodes);
611169689Skan	  }
612169689Skan	else
613169689Skan	  walk_tree (bsi_stmt_ptr (bsi), record_reference, node, visited_nodes);
614169689Skan      }
615169689Skan
616169689Skan  /* Look for initializers of constant variables and private statics.  */
617169689Skan  for (step = DECL_STRUCT_FUNCTION (body)->unexpanded_var_list;
618169689Skan       step;
619169689Skan       step = TREE_CHAIN (step))
620169689Skan    {
621169689Skan      tree decl = TREE_VALUE (step);
622169689Skan      if (TREE_CODE (decl) == VAR_DECL
623169689Skan	  && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
624169689Skan	  && flag_unit_at_a_time)
625169689Skan	cgraph_varpool_finalize_decl (decl);
626169689Skan      else if (TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
627169689Skan	walk_tree (&DECL_INITIAL (decl), record_reference, node, visited_nodes);
628169689Skan    }
629169689Skan
630169689Skan  pointer_set_destroy (visited_nodes);
631132718Skan  visited_nodes = NULL;
632132718Skan}
633132718Skan
634169689Skan/* Give initial reasons why inlining would fail.  Those gets
635169689Skan   either NULLified or usually overwritten by more precise reason
636169689Skan   later.  */
637169689Skanstatic void
638169689Skaninitialize_inline_failed (struct cgraph_node *node)
639169689Skan{
640169689Skan  struct cgraph_edge *e;
641169689Skan
642169689Skan  for (e = node->callers; e; e = e->next_caller)
643169689Skan    {
644169689Skan      gcc_assert (!e->callee->global.inlined_to);
645169689Skan      gcc_assert (e->inline_failed);
646169689Skan      if (node->local.redefined_extern_inline)
647169689Skan	e->inline_failed = N_("redefined extern inline functions are not "
648169689Skan			   "considered for inlining");
649169689Skan      else if (!node->local.inlinable)
650169689Skan	e->inline_failed = N_("function not inlinable");
651169689Skan      else
652169689Skan	e->inline_failed = N_("function not considered for inlining");
653169689Skan    }
654169689Skan}
655169689Skan
656169689Skan/* Rebuild call edges from current function after a passes not aware
657169689Skan   of cgraph updating.  */
658169689Skanstatic unsigned int
659169689Skanrebuild_cgraph_edges (void)
660169689Skan{
661169689Skan  basic_block bb;
662169689Skan  struct cgraph_node *node = cgraph_node (current_function_decl);
663169689Skan  block_stmt_iterator bsi;
664169689Skan
665169689Skan  cgraph_node_remove_callees (node);
666169689Skan
667169689Skan  node->count = ENTRY_BLOCK_PTR->count;
668169689Skan
669169689Skan  FOR_EACH_BB (bb)
670169689Skan    for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
671169689Skan      {
672169689Skan	tree stmt = bsi_stmt (bsi);
673169689Skan	tree call = get_call_expr_in (stmt);
674169689Skan	tree decl;
675169689Skan
676169689Skan	if (call && (decl = get_callee_fndecl (call)))
677169689Skan	  cgraph_create_edge (node, cgraph_node (decl), stmt,
678169689Skan			      bb->count,
679169689Skan			      bb->loop_depth);
680169689Skan      }
681169689Skan  initialize_inline_failed (node);
682169689Skan  gcc_assert (!node->global.inlined_to);
683169689Skan  return 0;
684169689Skan}
685169689Skan
686169689Skanstruct tree_opt_pass pass_rebuild_cgraph_edges =
687169689Skan{
688169689Skan  NULL,					/* name */
689169689Skan  NULL,					/* gate */
690169689Skan  rebuild_cgraph_edges,			/* execute */
691169689Skan  NULL,					/* sub */
692169689Skan  NULL,					/* next */
693169689Skan  0,					/* static_pass_number */
694169689Skan  0,					/* tv_id */
695169689Skan  PROP_cfg,				/* properties_required */
696169689Skan  0,					/* properties_provided */
697169689Skan  0,					/* properties_destroyed */
698169689Skan  0,					/* todo_flags_start */
699169689Skan  0,					/* todo_flags_finish */
700169689Skan  0					/* letter */
701169689Skan};
702169689Skan
703169689Skan/* Verify cgraph nodes of given cgraph node.  */
704169689Skanvoid
705169689Skanverify_cgraph_node (struct cgraph_node *node)
706169689Skan{
707169689Skan  struct cgraph_edge *e;
708169689Skan  struct cgraph_node *main_clone;
709169689Skan  struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl);
710169689Skan  basic_block this_block;
711169689Skan  block_stmt_iterator bsi;
712169689Skan  bool error_found = false;
713169689Skan
714169689Skan  if (errorcount || sorrycount)
715169689Skan    return;
716169689Skan
717169689Skan  timevar_push (TV_CGRAPH_VERIFY);
718169689Skan  for (e = node->callees; e; e = e->next_callee)
719169689Skan    if (e->aux)
720169689Skan      {
721169689Skan	error ("aux field set for edge %s->%s",
722169689Skan	       cgraph_node_name (e->caller), cgraph_node_name (e->callee));
723169689Skan	error_found = true;
724169689Skan      }
725169689Skan  if (node->count < 0)
726169689Skan    {
727169689Skan      error ("Execution count is negative");
728169689Skan      error_found = true;
729169689Skan    }
730169689Skan  for (e = node->callers; e; e = e->next_caller)
731169689Skan    {
732169689Skan      if (e->count < 0)
733169689Skan	{
734169689Skan	  error ("caller edge count is negative");
735169689Skan	  error_found = true;
736169689Skan	}
737169689Skan      if (!e->inline_failed)
738169689Skan	{
739169689Skan	  if (node->global.inlined_to
740169689Skan	      != (e->caller->global.inlined_to
741169689Skan		  ? e->caller->global.inlined_to : e->caller))
742169689Skan	    {
743169689Skan	      error ("inlined_to pointer is wrong");
744169689Skan	      error_found = true;
745169689Skan	    }
746169689Skan	  if (node->callers->next_caller)
747169689Skan	    {
748169689Skan	      error ("multiple inline callers");
749169689Skan	      error_found = true;
750169689Skan	    }
751169689Skan	}
752169689Skan      else
753169689Skan	if (node->global.inlined_to)
754169689Skan	  {
755169689Skan	    error ("inlined_to pointer set for noninline callers");
756169689Skan	    error_found = true;
757169689Skan	  }
758169689Skan    }
759169689Skan  if (!node->callers && node->global.inlined_to)
760169689Skan    {
761169689Skan      error ("inlined_to pointer is set but no predecessors found");
762169689Skan      error_found = true;
763169689Skan    }
764169689Skan  if (node->global.inlined_to == node)
765169689Skan    {
766169689Skan      error ("inlined_to pointer refers to itself");
767169689Skan      error_found = true;
768169689Skan    }
769169689Skan
770169689Skan  for (main_clone = cgraph_node (node->decl); main_clone;
771169689Skan       main_clone = main_clone->next_clone)
772169689Skan    if (main_clone == node)
773169689Skan      break;
774169689Skan  if (!cgraph_node (node->decl))
775169689Skan    {
776169689Skan      error ("node not found in cgraph_hash");
777169689Skan      error_found = true;
778169689Skan    }
779169689Skan
780169689Skan  if (node->analyzed
781169689Skan      && DECL_SAVED_TREE (node->decl) && !TREE_ASM_WRITTEN (node->decl)
782169689Skan      && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to))
783169689Skan    {
784169689Skan      if (this_cfun->cfg)
785169689Skan	{
786169689Skan	  /* The nodes we're interested in are never shared, so walk
787169689Skan	     the tree ignoring duplicates.  */
788169689Skan	  visited_nodes = pointer_set_create ();
789169689Skan	  /* Reach the trees by walking over the CFG, and note the
790169689Skan	     enclosing basic-blocks in the call edges.  */
791169689Skan	  FOR_EACH_BB_FN (this_block, this_cfun)
792169689Skan	    for (bsi = bsi_start (this_block); !bsi_end_p (bsi); bsi_next (&bsi))
793169689Skan	      {
794169689Skan		tree stmt = bsi_stmt (bsi);
795169689Skan		tree call = get_call_expr_in (stmt);
796169689Skan		tree decl;
797169689Skan		if (call && (decl = get_callee_fndecl (call)))
798169689Skan		  {
799169689Skan		    struct cgraph_edge *e = cgraph_edge (node, stmt);
800169689Skan		    if (e)
801169689Skan		      {
802169689Skan			if (e->aux)
803169689Skan			  {
804169689Skan			    error ("shared call_stmt:");
805169689Skan			    debug_generic_stmt (stmt);
806169689Skan			    error_found = true;
807169689Skan			  }
808169689Skan			if (e->callee->decl != cgraph_node (decl)->decl
809169689Skan			    && e->inline_failed)
810169689Skan			  {
811169689Skan			    error ("edge points to wrong declaration:");
812169689Skan			    debug_tree (e->callee->decl);
813169689Skan			    fprintf (stderr," Instead of:");
814169689Skan			    debug_tree (decl);
815169689Skan			  }
816169689Skan			e->aux = (void *)1;
817169689Skan		      }
818169689Skan		    else
819169689Skan		      {
820169689Skan			error ("missing callgraph edge for call stmt:");
821169689Skan			debug_generic_stmt (stmt);
822169689Skan			error_found = true;
823169689Skan		      }
824169689Skan		  }
825169689Skan	      }
826169689Skan	  pointer_set_destroy (visited_nodes);
827169689Skan	  visited_nodes = NULL;
828169689Skan	}
829169689Skan      else
830169689Skan	/* No CFG available?!  */
831169689Skan	gcc_unreachable ();
832169689Skan
833169689Skan      for (e = node->callees; e; e = e->next_callee)
834169689Skan	{
835169689Skan	  if (!e->aux)
836169689Skan	    {
837169689Skan	      error ("edge %s->%s has no corresponding call_stmt",
838169689Skan		     cgraph_node_name (e->caller),
839169689Skan		     cgraph_node_name (e->callee));
840169689Skan	      debug_generic_stmt (e->call_stmt);
841169689Skan	      error_found = true;
842169689Skan	    }
843169689Skan	  e->aux = 0;
844169689Skan	}
845169689Skan    }
846169689Skan  if (error_found)
847169689Skan    {
848169689Skan      dump_cgraph_node (stderr, node);
849169689Skan      internal_error ("verify_cgraph_node failed");
850169689Skan    }
851169689Skan  timevar_pop (TV_CGRAPH_VERIFY);
852169689Skan}
853169689Skan
854169689Skan/* Verify whole cgraph structure.  */
855169689Skanvoid
856169689Skanverify_cgraph (void)
857169689Skan{
858169689Skan  struct cgraph_node *node;
859169689Skan
860169689Skan  if (sorrycount || errorcount)
861169689Skan    return;
862169689Skan
863169689Skan  for (node = cgraph_nodes; node; node = node->next)
864169689Skan    verify_cgraph_node (node);
865169689Skan}
866169689Skan
867169689Skan/* Output one variable, if necessary.  Return whether we output it.  */
868169689Skanstatic bool
869169689Skancgraph_varpool_assemble_decl (struct cgraph_varpool_node *node)
870169689Skan{
871169689Skan  tree decl = node->decl;
872169689Skan
873169689Skan  if (!TREE_ASM_WRITTEN (decl)
874169689Skan      && !node->alias
875169689Skan      && !DECL_EXTERNAL (decl)
876169689Skan      && (TREE_CODE (decl) != VAR_DECL || !DECL_HAS_VALUE_EXPR_P (decl)))
877169689Skan    {
878169689Skan      assemble_variable (decl, 0, 1, 0);
879169689Skan      return TREE_ASM_WRITTEN (decl);
880169689Skan    }
881169689Skan
882169689Skan  return false;
883169689Skan}
884169689Skan
885169689Skan/* Output all variables enqueued to be assembled.  */
886169689Skanbool
887169689Skancgraph_varpool_assemble_pending_decls (void)
888169689Skan{
889169689Skan  bool changed = false;
890169689Skan
891169689Skan  if (errorcount || sorrycount)
892169689Skan    return false;
893169689Skan
894169689Skan  /* EH might mark decls as needed during expansion.  This should be safe since
895169689Skan     we don't create references to new function, but it should not be used
896169689Skan     elsewhere.  */
897169689Skan  cgraph_varpool_analyze_pending_decls ();
898169689Skan
899169689Skan  while (cgraph_varpool_nodes_queue)
900169689Skan    {
901169689Skan      struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue;
902169689Skan
903169689Skan      cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed;
904169689Skan      if (cgraph_varpool_assemble_decl (node))
905169689Skan	{
906169689Skan	  changed = true;
907169689Skan	  node->next_needed = cgraph_varpool_assembled_nodes_queue;
908169689Skan	  cgraph_varpool_assembled_nodes_queue = node;
909169689Skan	  node->finalized = 1;
910169689Skan	}
911169689Skan      else
912169689Skan        node->next_needed = NULL;
913169689Skan    }
914169689Skan  /* cgraph_varpool_nodes_queue is now empty, clear the pointer to the last
915169689Skan     element in the queue.  */
916169689Skan  cgraph_varpool_last_needed_node = NULL;
917169689Skan  return changed;
918169689Skan}
919169689Skan/* Output all variables enqueued to be assembled.  */
920169689Skanstatic void
921169689Skancgraph_varpool_output_debug_info (void)
922169689Skan{
923169689Skan  timevar_push (TV_SYMOUT);
924169689Skan  if (errorcount == 0 && sorrycount == 0)
925169689Skan    while (cgraph_varpool_assembled_nodes_queue)
926169689Skan      {
927169689Skan	struct cgraph_varpool_node *node = cgraph_varpool_assembled_nodes_queue;
928169689Skan
929169689Skan	/* Local static variables are never seen by check_global_declarations
930169689Skan	   so we need to output debug info by hand.  */
931169689Skan	if (DECL_CONTEXT (node->decl)
932169689Skan	    && (TREE_CODE (DECL_CONTEXT (node->decl)) == BLOCK
933169689Skan		|| TREE_CODE (DECL_CONTEXT (node->decl)) == FUNCTION_DECL)
934169689Skan	    && errorcount == 0 && sorrycount == 0)
935169689Skan	     (*debug_hooks->global_decl) (node->decl);
936169689Skan	cgraph_varpool_assembled_nodes_queue = node->next_needed;
937169689Skan	node->next_needed = 0;
938169689Skan      }
939169689Skan  timevar_pop (TV_SYMOUT);
940169689Skan}
941169689Skan
942169689Skan/* Output all asm statements we have stored up to be output.  */
943169689Skan
944169689Skanstatic void
945169689Skancgraph_output_pending_asms (void)
946169689Skan{
947169689Skan  struct cgraph_asm_node *can;
948169689Skan
949169689Skan  if (errorcount || sorrycount)
950169689Skan    return;
951169689Skan
952169689Skan  for (can = cgraph_asm_nodes; can; can = can->next)
953169689Skan    assemble_asm (can->asm_str);
954169689Skan  cgraph_asm_nodes = NULL;
955169689Skan}
956169689Skan
957132718Skan/* Analyze the function scheduled to be output.  */
958169689Skanvoid
959132718Skancgraph_analyze_function (struct cgraph_node *node)
960132718Skan{
961132718Skan  tree decl = node->decl;
962132718Skan
963132718Skan  current_function_decl = decl;
964169689Skan  push_cfun (DECL_STRUCT_FUNCTION (decl));
965169689Skan  cgraph_lower_function (node);
966132718Skan
967132718Skan  /* First kill forward declaration so reverse inlining works properly.  */
968169689Skan  cgraph_create_edges (node, decl);
969132718Skan
970132718Skan  node->local.inlinable = tree_inlinable_function_p (decl);
971169689Skan  if (!flag_unit_at_a_time)
972169689Skan    node->local.self_insns = estimate_num_insns (decl);
973132718Skan  if (node->local.inlinable)
974132718Skan    node->local.disregard_inline_limits
975169689Skan      = lang_hooks.tree_inlining.disregard_inline_limits (decl);
976169689Skan  initialize_inline_failed (node);
977132718Skan  if (flag_really_no_inline && !node->local.disregard_inline_limits)
978132718Skan    node->local.inlinable = 0;
979132718Skan  /* Inlining characteristics are maintained by the cgraph_mark_inline.  */
980132718Skan  node->global.insns = node->local.self_insns;
981132718Skan
982132718Skan  node->analyzed = true;
983169689Skan  pop_cfun ();
984132718Skan  current_function_decl = NULL;
985169689Skan}
986132718Skan
987169689Skan/* Look for externally_visible and used attributes and mark cgraph nodes
988169689Skan   accordingly.
989169689Skan
990169689Skan   We cannot mark the nodes at the point the attributes are processed (in
991169689Skan   handle_*_attribute) because the copy of the declarations available at that
992169689Skan   point may not be canonical.  For example, in:
993169689Skan
994169689Skan    void f();
995169689Skan    void f() __attribute__((used));
996169689Skan
997169689Skan   the declaration we see in handle_used_attribute will be the second
998169689Skan   declaration -- but the front end will subsequently merge that declaration
999169689Skan   with the original declaration and discard the second declaration.
1000169689Skan
1001169689Skan   Furthermore, we can't mark these nodes in cgraph_finalize_function because:
1002169689Skan
1003169689Skan    void f() {}
1004169689Skan    void f() __attribute__((externally_visible));
1005169689Skan
1006169689Skan   is valid.
1007169689Skan
1008169689Skan   So, we walk the nodes at the end of the translation unit, applying the
1009169689Skan   attributes at that point.  */
1010169689Skan
1011169689Skanstatic void
1012169689Skanprocess_function_and_variable_attributes (struct cgraph_node *first,
1013169689Skan                                          struct cgraph_varpool_node *first_var)
1014169689Skan{
1015169689Skan  struct cgraph_node *node;
1016169689Skan  struct cgraph_varpool_node *vnode;
1017169689Skan
1018169689Skan  for (node = cgraph_nodes; node != first; node = node->next)
1019169689Skan    {
1020169689Skan      tree decl = node->decl;
1021169689Skan      if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
1022169689Skan	{
1023169689Skan	  mark_decl_referenced (decl);
1024169689Skan	  if (node->local.finalized)
1025169689Skan	     cgraph_mark_needed_node (node);
1026169689Skan	}
1027169689Skan      if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
1028169689Skan	{
1029169689Skan	  if (! TREE_PUBLIC (node->decl))
1030169689Skan	    warning (OPT_Wattributes,
1031169689Skan		     "%J%<externally_visible%> attribute have effect only on public objects",
1032169689Skan		     node->decl);
1033169689Skan	  else
1034169689Skan	    {
1035169689Skan	      if (node->local.finalized)
1036169689Skan		cgraph_mark_needed_node (node);
1037169689Skan	      node->local.externally_visible = true;
1038169689Skan	    }
1039169689Skan	}
1040169689Skan    }
1041169689Skan  for (vnode = cgraph_varpool_nodes; vnode != first_var; vnode = vnode->next)
1042169689Skan    {
1043169689Skan      tree decl = vnode->decl;
1044169689Skan      if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
1045169689Skan	{
1046169689Skan	  mark_decl_referenced (decl);
1047169689Skan	  if (vnode->finalized)
1048169689Skan	    cgraph_varpool_mark_needed_node (vnode);
1049169689Skan	}
1050169689Skan      if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
1051169689Skan	{
1052169689Skan	  if (! TREE_PUBLIC (vnode->decl))
1053169689Skan	    warning (OPT_Wattributes,
1054169689Skan		     "%J%<externally_visible%> attribute have effect only on public objects",
1055169689Skan		     vnode->decl);
1056169689Skan	  else
1057169689Skan	    {
1058169689Skan	      if (vnode->finalized)
1059169689Skan		cgraph_varpool_mark_needed_node (vnode);
1060169689Skan	      vnode->externally_visible = true;
1061169689Skan	    }
1062169689Skan	}
1063169689Skan    }
1064132718Skan}
1065132718Skan
1066132718Skan/* Analyze the whole compilation unit once it is parsed completely.  */
1067132718Skan
1068132718Skanvoid
1069132718Skancgraph_finalize_compilation_unit (void)
1070132718Skan{
1071169689Skan  struct cgraph_node *node, *next;
1072169689Skan  /* Keep track of already processed nodes when called multiple times for
1073169689Skan     intermodule optimization.  */
1074169689Skan  static struct cgraph_node *first_analyzed;
1075169689Skan  struct cgraph_node *first_processed = first_analyzed;
1076169689Skan  static struct cgraph_varpool_node *first_analyzed_var;
1077132718Skan
1078169689Skan  if (errorcount || sorrycount)
1079169689Skan    return;
1080169689Skan
1081169689Skan  finish_aliases_1 ();
1082169689Skan
1083132718Skan  if (!flag_unit_at_a_time)
1084132718Skan    {
1085169689Skan      cgraph_output_pending_asms ();
1086132718Skan      cgraph_assemble_pending_functions ();
1087169689Skan      cgraph_varpool_output_debug_info ();
1088132718Skan      return;
1089132718Skan    }
1090132718Skan
1091132718Skan  if (!quiet_flag)
1092169689Skan    {
1093169689Skan      fprintf (stderr, "\nAnalyzing compilation unit");
1094169689Skan      fflush (stderr);
1095169689Skan    }
1096132718Skan
1097132718Skan  timevar_push (TV_CGRAPH);
1098169689Skan  process_function_and_variable_attributes (first_processed,
1099169689Skan					    first_analyzed_var);
1100169689Skan  first_processed = cgraph_nodes;
1101169689Skan  first_analyzed_var = cgraph_varpool_nodes;
1102169689Skan  cgraph_varpool_analyze_pending_decls ();
1103132718Skan  if (cgraph_dump_file)
1104132718Skan    {
1105132718Skan      fprintf (cgraph_dump_file, "Initial entry points:");
1106169689Skan      for (node = cgraph_nodes; node != first_analyzed; node = node->next)
1107132718Skan	if (node->needed && DECL_SAVED_TREE (node->decl))
1108132718Skan	  fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1109132718Skan      fprintf (cgraph_dump_file, "\n");
1110132718Skan    }
1111132718Skan
1112132718Skan  /* Propagate reachability flag and lower representation of all reachable
1113132718Skan     functions.  In the future, lowering will introduce new functions and
1114132718Skan     new entry points on the way (by template instantiation and virtual
1115132718Skan     method table generation for instance).  */
1116132718Skan  while (cgraph_nodes_queue)
1117132718Skan    {
1118132718Skan      struct cgraph_edge *edge;
1119132718Skan      tree decl = cgraph_nodes_queue->decl;
1120132718Skan
1121132718Skan      node = cgraph_nodes_queue;
1122132718Skan      cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
1123169689Skan      node->next_needed = NULL;
1124132718Skan
1125132718Skan      /* ??? It is possible to create extern inline function and later using
1126169689Skan	 weak alias attribute to kill its body. See
1127132718Skan	 gcc.c-torture/compile/20011119-1.c  */
1128132718Skan      if (!DECL_SAVED_TREE (decl))
1129169689Skan	{
1130169689Skan	  cgraph_reset_node (node);
1131169689Skan	  continue;
1132169689Skan	}
1133132718Skan
1134169689Skan      gcc_assert (!node->analyzed && node->reachable);
1135169689Skan      gcc_assert (DECL_SAVED_TREE (decl));
1136132718Skan
1137132718Skan      cgraph_analyze_function (node);
1138132718Skan
1139132718Skan      for (edge = node->callees; edge; edge = edge->next_callee)
1140132718Skan	if (!edge->callee->reachable)
1141132718Skan	  cgraph_mark_reachable_node (edge->callee);
1142132718Skan
1143169689Skan      /* We finalize local static variables during constructing callgraph
1144169689Skan         edges.  Process their attributes too.  */
1145169689Skan      process_function_and_variable_attributes (first_processed,
1146169689Skan						first_analyzed_var);
1147169689Skan      first_processed = cgraph_nodes;
1148169689Skan      first_analyzed_var = cgraph_varpool_nodes;
1149169689Skan      cgraph_varpool_analyze_pending_decls ();
1150132718Skan    }
1151132718Skan
1152132718Skan  /* Collect entry points to the unit.  */
1153132718Skan  if (cgraph_dump_file)
1154132718Skan    {
1155132718Skan      fprintf (cgraph_dump_file, "Unit entry points:");
1156169689Skan      for (node = cgraph_nodes; node != first_analyzed; node = node->next)
1157132718Skan	if (node->needed && DECL_SAVED_TREE (node->decl))
1158132718Skan	  fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1159132718Skan      fprintf (cgraph_dump_file, "\n\nInitial ");
1160132718Skan      dump_cgraph (cgraph_dump_file);
1161132718Skan    }
1162132718Skan
1163132718Skan  if (cgraph_dump_file)
1164132718Skan    fprintf (cgraph_dump_file, "\nReclaiming functions:");
1165132718Skan
1166169689Skan  for (node = cgraph_nodes; node != first_analyzed; node = next)
1167132718Skan    {
1168132718Skan      tree decl = node->decl;
1169169689Skan      next = node->next;
1170132718Skan
1171169689Skan      if (node->local.finalized && !DECL_SAVED_TREE (decl))
1172169689Skan	cgraph_reset_node (node);
1173169689Skan
1174132718Skan      if (!node->reachable && DECL_SAVED_TREE (decl))
1175132718Skan	{
1176132718Skan	  if (cgraph_dump_file)
1177132718Skan	    fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1178169689Skan	  cgraph_remove_node (node);
1179169689Skan	  continue;
1180132718Skan	}
1181132718Skan      else
1182132718Skan	node->next_needed = NULL;
1183169689Skan      gcc_assert (!node->local.finalized || DECL_SAVED_TREE (decl));
1184169689Skan      gcc_assert (node->analyzed == node->local.finalized);
1185132718Skan    }
1186132718Skan  if (cgraph_dump_file)
1187132718Skan    {
1188132718Skan      fprintf (cgraph_dump_file, "\n\nReclaimed ");
1189132718Skan      dump_cgraph (cgraph_dump_file);
1190132718Skan    }
1191169689Skan  first_analyzed = cgraph_nodes;
1192132718Skan  ggc_collect ();
1193132718Skan  timevar_pop (TV_CGRAPH);
1194132718Skan}
1195132718Skan/* Figure out what functions we want to assemble.  */
1196132718Skan
1197132718Skanstatic void
1198132718Skancgraph_mark_functions_to_output (void)
1199132718Skan{
1200132718Skan  struct cgraph_node *node;
1201132718Skan
1202132718Skan  for (node = cgraph_nodes; node; node = node->next)
1203132718Skan    {
1204132718Skan      tree decl = node->decl;
1205132718Skan      struct cgraph_edge *e;
1206132718Skan
1207169689Skan      gcc_assert (!node->output);
1208132718Skan
1209132718Skan      for (e = node->callers; e; e = e->next_caller)
1210132718Skan	if (e->inline_failed)
1211132718Skan	  break;
1212132718Skan
1213132718Skan      /* We need to output all local functions that are used and not
1214132718Skan	 always inlined, as well as those that are reachable from
1215132718Skan	 outside the current compilation unit.  */
1216132718Skan      if (DECL_SAVED_TREE (decl)
1217169689Skan	  && !node->global.inlined_to
1218132718Skan	  && (node->needed
1219132718Skan	      || (e && node->reachable))
1220169689Skan	  && !TREE_ASM_WRITTEN (decl)
1221132718Skan	  && !DECL_EXTERNAL (decl))
1222132718Skan	node->output = 1;
1223132718Skan      else
1224169689Skan	{
1225169689Skan	  /* We should've reclaimed all functions that are not needed.  */
1226169689Skan#ifdef ENABLE_CHECKING
1227169689Skan	  if (!node->global.inlined_to && DECL_SAVED_TREE (decl)
1228169689Skan	      && !DECL_EXTERNAL (decl))
1229169689Skan	    {
1230169689Skan	      dump_cgraph_node (stderr, node);
1231169689Skan	      internal_error ("failed to reclaim unneeded function");
1232169689Skan	    }
1233169689Skan#endif
1234169689Skan	  gcc_assert (node->global.inlined_to || !DECL_SAVED_TREE (decl)
1235169689Skan		      || DECL_EXTERNAL (decl));
1236132718Skan
1237169689Skan	}
1238132718Skan
1239132718Skan    }
1240132718Skan}
1241132718Skan
1242132718Skan/* Expand function specified by NODE.  */
1243132718Skan
1244132718Skanstatic void
1245132718Skancgraph_expand_function (struct cgraph_node *node)
1246132718Skan{
1247132718Skan  tree decl = node->decl;
1248132718Skan
1249169689Skan  /* We ought to not compile any inline clones.  */
1250169689Skan  gcc_assert (!node->global.inlined_to);
1251169689Skan
1252132718Skan  if (flag_unit_at_a_time)
1253132718Skan    announce_function (decl);
1254132718Skan
1255169689Skan  cgraph_lower_function (node);
1256132718Skan
1257169689Skan  /* Generate RTL for the body of DECL.  */
1258169689Skan  lang_hooks.callgraph.expand_function (decl);
1259132718Skan
1260169689Skan  /* Make sure that BE didn't give up on compiling.  */
1261169689Skan  /* ??? Can happen with nested function of extern inline.  */
1262169689Skan  gcc_assert (TREE_ASM_WRITTEN (node->decl));
1263169689Skan
1264132718Skan  current_function_decl = NULL;
1265169689Skan  if (!cgraph_preserve_function_body_p (node->decl))
1266169689Skan    {
1267169689Skan      DECL_SAVED_TREE (node->decl) = NULL;
1268169689Skan      DECL_STRUCT_FUNCTION (node->decl) = NULL;
1269169689Skan      DECL_INITIAL (node->decl) = error_mark_node;
1270169689Skan      /* Eliminate all call edges.  This is important so the call_expr no longer
1271169689Skan	 points to the dead function body.  */
1272169689Skan      cgraph_node_remove_callees (node);
1273169689Skan    }
1274169689Skan
1275169689Skan  cgraph_function_flags_ready = true;
1276132718Skan}
1277132718Skan
1278169689Skan/* Return true when CALLER_DECL should be inlined into CALLEE_DECL.  */
1279132718Skan
1280169689Skanbool
1281169689Skancgraph_inline_p (struct cgraph_edge *e, const char **reason)
1282132718Skan{
1283169689Skan  *reason = e->inline_failed;
1284169689Skan  return !e->inline_failed;
1285169689Skan}
1286132718Skan
1287132718Skan
1288132718Skan
1289169689Skan/* Expand all functions that must be output.
1290132718Skan
1291169689Skan   Attempt to topologically sort the nodes so function is output when
1292169689Skan   all called functions are already assembled to allow data to be
1293169689Skan   propagated across the callgraph.  Use a stack to get smaller distance
1294169689Skan   between a function and its callees (later we may choose to use a more
1295169689Skan   sophisticated algorithm for function reordering; we will likely want
1296169689Skan   to use subsections to make the output functions appear in top-down
1297169689Skan   order).  */
1298132718Skan
1299169689Skanstatic void
1300169689Skancgraph_expand_all_functions (void)
1301132718Skan{
1302169689Skan  struct cgraph_node *node;
1303169689Skan  struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1304169689Skan  int order_pos = 0, new_order_pos = 0;
1305132718Skan  int i;
1306132718Skan
1307169689Skan  order_pos = cgraph_postorder (order);
1308169689Skan  gcc_assert (order_pos == cgraph_n_nodes);
1309132718Skan
1310169689Skan  /* Garbage collector may remove inline clones we eliminate during
1311169689Skan     optimization.  So we must be sure to not reference them.  */
1312169689Skan  for (i = 0; i < order_pos; i++)
1313169689Skan    if (order[i]->output)
1314169689Skan      order[new_order_pos++] = order[i];
1315132718Skan
1316169689Skan  for (i = new_order_pos - 1; i >= 0; i--)
1317132718Skan    {
1318169689Skan      node = order[i];
1319169689Skan      if (node->output)
1320132718Skan	{
1321169689Skan	  gcc_assert (node->reachable);
1322169689Skan	  node->output = 0;
1323169689Skan	  cgraph_expand_function (node);
1324132718Skan	}
1325132718Skan    }
1326132718Skan
1327169689Skan  free (order);
1328132718Skan
1329169689Skan  /* Process CGRAPH_EXPAND_QUEUE, these are functions created during
1330169689Skan     the expansion process.  Note that this queue may grow as its
1331169689Skan     being processed, as the new functions may generate new ones.  */
1332169689Skan  while (cgraph_expand_queue)
1333132718Skan    {
1334169689Skan      node = cgraph_expand_queue;
1335169689Skan      cgraph_expand_queue = cgraph_expand_queue->next_needed;
1336169689Skan      node->next_needed = NULL;
1337169689Skan      node->output = 0;
1338169689Skan      node->lowered = DECL_STRUCT_FUNCTION (node->decl)->cfg != NULL;
1339169689Skan      cgraph_expand_function (node);
1340132718Skan    }
1341132718Skan}
1342132718Skan
1343169689Skan/* This is used to sort the node types by the cgraph order number.  */
1344132718Skan
1345169689Skanstruct cgraph_order_sort
1346169689Skan{
1347169689Skan  enum { ORDER_UNDEFINED = 0, ORDER_FUNCTION, ORDER_VAR, ORDER_ASM } kind;
1348169689Skan  union
1349169689Skan  {
1350169689Skan    struct cgraph_node *f;
1351169689Skan    struct cgraph_varpool_node *v;
1352169689Skan    struct cgraph_asm_node *a;
1353169689Skan  } u;
1354169689Skan};
1355132718Skan
1356169689Skan/* Output all functions, variables, and asm statements in the order
1357169689Skan   according to their order fields, which is the order in which they
1358169689Skan   appeared in the file.  This implements -fno-toplevel-reorder.  In
1359169689Skan   this mode we may output functions and variables which don't really
1360169689Skan   need to be output.  */
1361169689Skan
1362169689Skanstatic void
1363169689Skancgraph_output_in_order (void)
1364132718Skan{
1365169689Skan  int max;
1366169689Skan  size_t size;
1367169689Skan  struct cgraph_order_sort *nodes;
1368132718Skan  int i;
1369169689Skan  struct cgraph_node *pf;
1370169689Skan  struct cgraph_varpool_node *pv;
1371169689Skan  struct cgraph_asm_node *pa;
1372132718Skan
1373169689Skan  max = cgraph_order;
1374169689Skan  size = max * sizeof (struct cgraph_order_sort);
1375169689Skan  nodes = (struct cgraph_order_sort *) alloca (size);
1376169689Skan  memset (nodes, 0, size);
1377132718Skan
1378169689Skan  cgraph_varpool_analyze_pending_decls ();
1379132718Skan
1380169689Skan  for (pf = cgraph_nodes; pf; pf = pf->next)
1381132718Skan    {
1382169689Skan      if (pf->output)
1383132718Skan	{
1384169689Skan	  i = pf->order;
1385169689Skan	  gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1386169689Skan	  nodes[i].kind = ORDER_FUNCTION;
1387169689Skan	  nodes[i].u.f = pf;
1388132718Skan	}
1389132718Skan    }
1390132718Skan
1391169689Skan  for (pv = cgraph_varpool_nodes_queue; pv; pv = pv->next_needed)
1392132718Skan    {
1393169689Skan      i = pv->order;
1394169689Skan      gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1395169689Skan      nodes[i].kind = ORDER_VAR;
1396169689Skan      nodes[i].u.v = pv;
1397132718Skan    }
1398132718Skan
1399169689Skan  for (pa = cgraph_asm_nodes; pa; pa = pa->next)
1400132718Skan    {
1401169689Skan      i = pa->order;
1402169689Skan      gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1403169689Skan      nodes[i].kind = ORDER_ASM;
1404169689Skan      nodes[i].u.a = pa;
1405132718Skan    }
1406132718Skan
1407169689Skan  for (i = 0; i < max; ++i)
1408132718Skan    {
1409169689Skan      switch (nodes[i].kind)
1410132718Skan	{
1411169689Skan	case ORDER_FUNCTION:
1412169689Skan	  nodes[i].u.f->output = 0;
1413169689Skan	  cgraph_expand_function (nodes[i].u.f);
1414169689Skan	  break;
1415132718Skan
1416169689Skan	case ORDER_VAR:
1417169689Skan	  cgraph_varpool_assemble_decl (nodes[i].u.v);
1418169689Skan	  break;
1419132718Skan
1420169689Skan	case ORDER_ASM:
1421169689Skan	  assemble_asm (nodes[i].u.a->asm_str);
1422169689Skan	  break;
1423169689Skan
1424169689Skan	case ORDER_UNDEFINED:
1425169689Skan	  break;
1426169689Skan
1427169689Skan	default:
1428169689Skan	  gcc_unreachable ();
1429132718Skan	}
1430132718Skan    }
1431132718Skan
1432169689Skan  cgraph_asm_nodes = NULL;
1433132718Skan}
1434132718Skan
1435169689Skan/* Mark visibility of all functions.
1436132718Skan
1437169689Skan   A local function is one whose calls can occur only in the current
1438169689Skan   compilation unit and all its calls are explicit, so we can change
1439169689Skan   its calling convention.  We simply mark all static functions whose
1440169689Skan   address is not taken as local.
1441132718Skan
1442169689Skan   We also change the TREE_PUBLIC flag of all declarations that are public
1443169689Skan   in language point of view but we want to overwrite this default
1444169689Skan   via visibilities for the backend point of view.  */
1445132718Skan
1446132718Skanstatic void
1447169689Skancgraph_function_and_variable_visibility (void)
1448132718Skan{
1449169689Skan  struct cgraph_node *node;
1450169689Skan  struct cgraph_varpool_node *vnode;
1451132718Skan
1452169689Skan  for (node = cgraph_nodes; node; node = node->next)
1453132718Skan    {
1454169689Skan      if (node->reachable
1455169689Skan	  && (DECL_COMDAT (node->decl)
1456169689Skan	      || (!flag_whole_program
1457169689Skan		  && TREE_PUBLIC (node->decl) && !DECL_EXTERNAL (node->decl))))
1458169689Skan	node->local.externally_visible = true;
1459169689Skan      if (!node->local.externally_visible && node->analyzed
1460169689Skan	  && !DECL_EXTERNAL (node->decl))
1461132718Skan	{
1462169689Skan	  gcc_assert (flag_whole_program || !TREE_PUBLIC (node->decl));
1463169689Skan	  TREE_PUBLIC (node->decl) = 0;
1464132718Skan	}
1465169689Skan      node->local.local = (!node->needed
1466169689Skan			   && node->analyzed
1467169689Skan			   && !DECL_EXTERNAL (node->decl)
1468169689Skan			   && !node->local.externally_visible);
1469132718Skan    }
1470169689Skan  for (vnode = cgraph_varpool_nodes_queue; vnode; vnode = vnode->next_needed)
1471169689Skan    {
1472169689Skan      if (vnode->needed
1473169689Skan	  && !flag_whole_program
1474169689Skan	  && (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl)))
1475169689Skan	vnode->externally_visible = 1;
1476169689Skan      if (!vnode->externally_visible)
1477169689Skan	{
1478169689Skan	  gcc_assert (flag_whole_program || !TREE_PUBLIC (vnode->decl));
1479169689Skan	  TREE_PUBLIC (vnode->decl) = 0;
1480169689Skan	}
1481169689Skan     gcc_assert (TREE_STATIC (vnode->decl));
1482169689Skan    }
1483132718Skan
1484169689Skan  /* Because we have to be conservative on the boundaries of source
1485169689Skan     level units, it is possible that we marked some functions in
1486169689Skan     reachable just because they might be used later via external
1487169689Skan     linkage, but after making them local they are really unreachable
1488169689Skan     now.  */
1489169689Skan  cgraph_remove_unreachable_nodes (true, cgraph_dump_file);
1490132718Skan
1491169689Skan  if (cgraph_dump_file)
1492132718Skan    {
1493169689Skan      fprintf (cgraph_dump_file, "\nMarking local functions:");
1494169689Skan      for (node = cgraph_nodes; node; node = node->next)
1495169689Skan	if (node->local.local)
1496169689Skan	  fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1497169689Skan      fprintf (cgraph_dump_file, "\n\n");
1498169689Skan      fprintf (cgraph_dump_file, "\nMarking externally visible functions:");
1499169689Skan      for (node = cgraph_nodes; node; node = node->next)
1500169689Skan	if (node->local.externally_visible)
1501169689Skan	  fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1502169689Skan      fprintf (cgraph_dump_file, "\n\n");
1503132718Skan    }
1504169689Skan  cgraph_function_flags_ready = true;
1505132718Skan}
1506132718Skan
1507169689Skan/* Return true when function body of DECL still needs to be kept around
1508169689Skan   for later re-use.  */
1509169689Skanbool
1510169689Skancgraph_preserve_function_body_p (tree decl)
1511169689Skan{
1512169689Skan  struct cgraph_node *node;
1513169689Skan  if (!cgraph_global_info_ready)
1514169689Skan    return (flag_really_no_inline
1515169689Skan	    ? lang_hooks.tree_inlining.disregard_inline_limits (decl)
1516169689Skan	    : DECL_INLINE (decl));
1517169689Skan  /* Look if there is any clone around.  */
1518169689Skan  for (node = cgraph_node (decl); node; node = node->next_clone)
1519169689Skan    if (node->global.inlined_to)
1520169689Skan      return true;
1521169689Skan  return false;
1522169689Skan}
1523132718Skan
1524169689Skanstatic void
1525169689Skanipa_passes (void)
1526132718Skan{
1527169689Skan  cfun = NULL;
1528169689Skan  tree_register_cfg_hooks ();
1529169689Skan  bitmap_obstack_initialize (NULL);
1530169689Skan  execute_ipa_pass_list (all_ipa_passes);
1531169689Skan  bitmap_obstack_release (NULL);
1532169689Skan}
1533132718Skan
1534169689Skan/* Perform simple optimizations based on callgraph.  */
1535132718Skan
1536169689Skanvoid
1537169689Skancgraph_optimize (void)
1538169689Skan{
1539169689Skan  if (errorcount || sorrycount)
1540169689Skan    return;
1541132718Skan
1542169689Skan#ifdef ENABLE_CHECKING
1543169689Skan  verify_cgraph ();
1544169689Skan#endif
1545169689Skan  if (!flag_unit_at_a_time)
1546132718Skan    {
1547169689Skan      cgraph_output_pending_asms ();
1548169689Skan      cgraph_varpool_assemble_pending_decls ();
1549169689Skan      cgraph_varpool_output_debug_info ();
1550169689Skan      return;
1551132718Skan    }
1552132718Skan
1553169689Skan  /* Frontend may output common variables after the unit has been finalized.
1554169689Skan     It is safe to deal with them here as they are always zero initialized.  */
1555169689Skan  cgraph_varpool_analyze_pending_decls ();
1556132718Skan
1557169689Skan  timevar_push (TV_CGRAPHOPT);
1558169689Skan  if (!quiet_flag)
1559169689Skan    fprintf (stderr, "Performing interprocedural optimizations\n");
1560132718Skan
1561169689Skan  cgraph_function_and_variable_visibility ();
1562169689Skan  if (cgraph_dump_file)
1563169689Skan    {
1564169689Skan      fprintf (cgraph_dump_file, "Marked ");
1565169689Skan      dump_cgraph (cgraph_dump_file);
1566169689Skan    }
1567169689Skan
1568169689Skan  /* Don't run the IPA passes if there was any error or sorry messages.  */
1569169689Skan  if (errorcount == 0 && sorrycount == 0)
1570169689Skan    ipa_passes ();
1571132718Skan
1572169689Skan  /* This pass remove bodies of extern inline functions we never inlined.
1573169689Skan     Do this later so other IPA passes see what is really going on.  */
1574169689Skan  cgraph_remove_unreachable_nodes (false, dump_file);
1575169689Skan  cgraph_increase_alignment ();
1576169689Skan  cgraph_global_info_ready = true;
1577132718Skan  if (cgraph_dump_file)
1578169689Skan    {
1579169689Skan      fprintf (cgraph_dump_file, "Optimized ");
1580169689Skan      dump_cgraph (cgraph_dump_file);
1581169689Skan      dump_varpool (cgraph_dump_file);
1582169689Skan    }
1583169689Skan  timevar_pop (TV_CGRAPHOPT);
1584132718Skan
1585169689Skan  /* Output everything.  */
1586169689Skan  if (!quiet_flag)
1587169689Skan    fprintf (stderr, "Assembling functions:\n");
1588169689Skan#ifdef ENABLE_CHECKING
1589169689Skan  verify_cgraph ();
1590169689Skan#endif
1591132718Skan
1592169689Skan  cgraph_mark_functions_to_output ();
1593132718Skan
1594169689Skan  if (!flag_toplevel_reorder)
1595169689Skan    cgraph_output_in_order ();
1596169689Skan  else
1597169689Skan    {
1598169689Skan      cgraph_output_pending_asms ();
1599132718Skan
1600169689Skan      cgraph_expand_all_functions ();
1601169689Skan      cgraph_varpool_remove_unreferenced_decls ();
1602132718Skan
1603169689Skan      cgraph_varpool_assemble_pending_decls ();
1604169689Skan      cgraph_varpool_output_debug_info ();
1605132718Skan    }
1606132718Skan
1607132718Skan  if (cgraph_dump_file)
1608132718Skan    {
1609169689Skan      fprintf (cgraph_dump_file, "\nFinal ");
1610169689Skan      dump_cgraph (cgraph_dump_file);
1611169689Skan    }
1612169689Skan#ifdef ENABLE_CHECKING
1613169689Skan  verify_cgraph ();
1614169689Skan  /* Double check that all inline clones are gone and that all
1615169689Skan     function bodies have been released from memory.  */
1616169689Skan  if (flag_unit_at_a_time
1617169689Skan      && !(sorrycount || errorcount))
1618169689Skan    {
1619169689Skan      struct cgraph_node *node;
1620169689Skan      bool error_found = false;
1621132718Skan
1622169689Skan      for (node = cgraph_nodes; node; node = node->next)
1623169689Skan	if (node->analyzed
1624169689Skan	    && (node->global.inlined_to
1625169689Skan		|| DECL_SAVED_TREE (node->decl)))
1626132718Skan	  {
1627169689Skan	    error_found = true;
1628169689Skan	    dump_cgraph_node (stderr, node);
1629132718Skan	  }
1630169689Skan      if (error_found)
1631169689Skan	internal_error ("nodes with no released memory found");
1632169689Skan    }
1633169689Skan#endif
1634169689Skan}
1635132718Skan
1636169689Skan/* Increase alignment of global arrays to improve vectorization potential.
1637169689Skan   TODO:
1638169689Skan   - Consider also structs that have an array field.
1639169689Skan   - Use ipa analysis to prune arrays that can't be vectorized?
1640169689Skan     This should involve global alignment analysis and in the future also
1641169689Skan     array padding.  */
1642132718Skan
1643169689Skanstatic void
1644169689Skancgraph_increase_alignment (void)
1645169689Skan{
1646169689Skan  if (flag_section_anchors && flag_tree_vectorize)
1647169689Skan    {
1648169689Skan      struct cgraph_varpool_node *vnode;
1649132718Skan
1650169689Skan      /* Increase the alignment of all global arrays for vectorization.  */
1651169689Skan      for (vnode = cgraph_varpool_nodes_queue;
1652169689Skan           vnode;
1653169689Skan           vnode = vnode->next_needed)
1654169689Skan        {
1655169689Skan          tree vectype, decl = vnode->decl;
1656169689Skan          unsigned int alignment;
1657132718Skan
1658169689Skan          if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
1659169689Skan            continue;
1660169689Skan          vectype = get_vectype_for_scalar_type (TREE_TYPE (TREE_TYPE (decl)));
1661169689Skan          if (!vectype)
1662169689Skan            continue;
1663169689Skan          alignment = TYPE_ALIGN (vectype);
1664169689Skan          if (DECL_ALIGN (decl) >= alignment)
1665169689Skan            continue;
1666132718Skan
1667169689Skan          if (vect_can_force_dr_alignment_p (decl, alignment))
1668169689Skan            {
1669169689Skan              DECL_ALIGN (decl) = TYPE_ALIGN (vectype);
1670169689Skan              DECL_USER_ALIGN (decl) = 1;
1671169689Skan              if (cgraph_dump_file)
1672169689Skan                {
1673169689Skan                  fprintf (cgraph_dump_file, "Increasing alignment of decl: ");
1674169689Skan                  print_generic_expr (cgraph_dump_file, decl, TDF_SLIM);
1675169689Skan                }
1676169689Skan            }
1677169689Skan        }
1678132718Skan    }
1679132718Skan}
1680132718Skan
1681169689Skan/* Generate and emit a static constructor or destructor.  WHICH must be
1682169689Skan   one of 'I' or 'D'.  BODY should be a STATEMENT_LIST containing
1683169689Skan   GENERIC statements.  */
1684132718Skan
1685169689Skanvoid
1686169689Skancgraph_build_static_cdtor (char which, tree body, int priority)
1687132718Skan{
1688169689Skan  static int counter = 0;
1689169689Skan  char which_buf[16];
1690169689Skan  tree decl, name, resdecl;
1691132718Skan
1692169689Skan  sprintf (which_buf, "%c_%d", which, counter++);
1693259563Spfg  name = get_file_function_name (which_buf);
1694132718Skan
1695169689Skan  decl = build_decl (FUNCTION_DECL, name,
1696169689Skan		     build_function_type (void_type_node, void_list_node));
1697169689Skan  current_function_decl = decl;
1698132718Skan
1699169689Skan  resdecl = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1700169689Skan  DECL_ARTIFICIAL (resdecl) = 1;
1701169689Skan  DECL_IGNORED_P (resdecl) = 1;
1702169689Skan  DECL_RESULT (decl) = resdecl;
1703132718Skan
1704169689Skan  allocate_struct_function (decl);
1705132718Skan
1706169689Skan  TREE_STATIC (decl) = 1;
1707169689Skan  TREE_USED (decl) = 1;
1708169689Skan  DECL_ARTIFICIAL (decl) = 1;
1709169689Skan  DECL_IGNORED_P (decl) = 1;
1710169689Skan  DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
1711169689Skan  DECL_SAVED_TREE (decl) = body;
1712169689Skan  TREE_PUBLIC (decl) = ! targetm.have_ctors_dtors;
1713169689Skan  DECL_UNINLINABLE (decl) = 1;
1714132718Skan
1715169689Skan  DECL_INITIAL (decl) = make_node (BLOCK);
1716169689Skan  TREE_USED (DECL_INITIAL (decl)) = 1;
1717169689Skan
1718169689Skan  DECL_SOURCE_LOCATION (decl) = input_location;
1719169689Skan  cfun->function_end_locus = input_location;
1720169689Skan
1721169689Skan  switch (which)
1722132718Skan    {
1723169689Skan    case 'I':
1724169689Skan      DECL_STATIC_CONSTRUCTOR (decl) = 1;
1725169689Skan      break;
1726169689Skan    case 'D':
1727169689Skan      DECL_STATIC_DESTRUCTOR (decl) = 1;
1728169689Skan      break;
1729169689Skan    default:
1730169689Skan      gcc_unreachable ();
1731169689Skan    }
1732132718Skan
1733169689Skan  gimplify_function_tree (decl);
1734132718Skan
1735169689Skan  /* ??? We will get called LATE in the compilation process.  */
1736169689Skan  if (cgraph_global_info_ready)
1737169689Skan    {
1738169689Skan      tree_lowering_passes (decl);
1739169689Skan      tree_rest_of_compilation (decl);
1740132718Skan    }
1741169689Skan  else
1742169689Skan    cgraph_finalize_function (decl, 0);
1743132718Skan
1744169689Skan  if (targetm.have_ctors_dtors)
1745132718Skan    {
1746169689Skan      void (*fn) (rtx, int);
1747132718Skan
1748169689Skan      if (which == 'I')
1749169689Skan	fn = targetm.asm_out.constructor;
1750169689Skan      else
1751169689Skan	fn = targetm.asm_out.destructor;
1752169689Skan      fn (XEXP (DECL_RTL (decl), 0), priority);
1753132718Skan    }
1754169689Skan}
1755132718Skan
1756169689Skanvoid
1757169689Skaninit_cgraph (void)
1758169689Skan{
1759169689Skan  cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
1760132718Skan}
1761132718Skan
1762169689Skan/* The edges representing the callers of the NEW_VERSION node were
1763169689Skan   fixed by cgraph_function_versioning (), now the call_expr in their
1764169689Skan   respective tree code should be updated to call the NEW_VERSION.  */
1765132718Skan
1766132718Skanstatic void
1767169689Skanupdate_call_expr (struct cgraph_node *new_version)
1768132718Skan{
1769132718Skan  struct cgraph_edge *e;
1770132718Skan
1771169689Skan  gcc_assert (new_version);
1772169689Skan  for (e = new_version->callers; e; e = e->next_caller)
1773169689Skan    /* Update the call expr on the edges
1774169689Skan       to call the new version.  */
1775169689Skan    TREE_OPERAND (TREE_OPERAND (get_call_expr_in (e->call_stmt), 0), 0) = new_version->decl;
1776169689Skan}
1777132718Skan
1778132718Skan
1779169689Skan/* Create a new cgraph node which is the new version of
1780169689Skan   OLD_VERSION node.  REDIRECT_CALLERS holds the callers
1781169689Skan   edges which should be redirected to point to
1782169689Skan   NEW_VERSION.  ALL the callees edges of OLD_VERSION
1783169689Skan   are cloned to the new version node.  Return the new
1784169689Skan   version node.  */
1785132718Skan
1786169689Skanstatic struct cgraph_node *
1787169689Skancgraph_copy_node_for_versioning (struct cgraph_node *old_version,
1788169689Skan				 tree new_decl,
1789169689Skan				 VEC(cgraph_edge_p,heap) *redirect_callers)
1790169689Skan {
1791169689Skan   struct cgraph_node *new_version;
1792169689Skan   struct cgraph_edge *e, *new_e;
1793169689Skan   struct cgraph_edge *next_callee;
1794169689Skan   unsigned i;
1795132718Skan
1796169689Skan   gcc_assert (old_version);
1797132718Skan
1798169689Skan   new_version = cgraph_node (new_decl);
1799132718Skan
1800169689Skan   new_version->analyzed = true;
1801169689Skan   new_version->local = old_version->local;
1802169689Skan   new_version->global = old_version->global;
1803169689Skan   new_version->rtl = new_version->rtl;
1804169689Skan   new_version->reachable = true;
1805169689Skan   new_version->count = old_version->count;
1806132718Skan
1807169689Skan   /* Clone the old node callees.  Recursive calls are
1808169689Skan      also cloned.  */
1809169689Skan   for (e = old_version->callees;e; e=e->next_callee)
1810169689Skan     {
1811169689Skan       new_e = cgraph_clone_edge (e, new_version, e->call_stmt, 0, e->loop_nest, true);
1812169689Skan       new_e->count = e->count;
1813169689Skan     }
1814169689Skan   /* Fix recursive calls.
1815169689Skan      If OLD_VERSION has a recursive call after the
1816169689Skan      previous edge cloning, the new version will have an edge
1817169689Skan      pointing to the old version, which is wrong;
1818169689Skan      Redirect it to point to the new version. */
1819169689Skan   for (e = new_version->callees ; e; e = next_callee)
1820169689Skan     {
1821169689Skan       next_callee = e->next_callee;
1822169689Skan       if (e->callee == old_version)
1823169689Skan	 cgraph_redirect_edge_callee (e, new_version);
1824132718Skan
1825169689Skan       if (!next_callee)
1826169689Skan	 break;
1827169689Skan     }
1828169689Skan   for (i = 0; VEC_iterate (cgraph_edge_p, redirect_callers, i, e); i++)
1829169689Skan     {
1830169689Skan       /* Redirect calls to the old version node to point to its new
1831169689Skan	  version.  */
1832169689Skan       cgraph_redirect_edge_callee (e, new_version);
1833169689Skan     }
1834132718Skan
1835169689Skan   return new_version;
1836169689Skan }
1837132718Skan
1838169689Skan /* Perform function versioning.
1839169689Skan    Function versioning includes copying of the tree and
1840169689Skan    a callgraph update (creating a new cgraph node and updating
1841169689Skan    its callees and callers).
1842169689Skan
1843169689Skan    REDIRECT_CALLERS varray includes the edges to be redirected
1844169689Skan    to the new version.
1845169689Skan
1846169689Skan    TREE_MAP is a mapping of tree nodes we want to replace with
1847169689Skan    new ones (according to results of prior analysis).
1848169689Skan    OLD_VERSION_NODE is the node that is versioned.
1849169689Skan    It returns the new version's cgraph node.  */
1850169689Skan
1851169689Skanstruct cgraph_node *
1852169689Skancgraph_function_versioning (struct cgraph_node *old_version_node,
1853169689Skan			    VEC(cgraph_edge_p,heap) *redirect_callers,
1854169689Skan			    varray_type tree_map)
1855132718Skan{
1856169689Skan  tree old_decl = old_version_node->decl;
1857169689Skan  struct cgraph_node *new_version_node = NULL;
1858169689Skan  tree new_decl;
1859132718Skan
1860169689Skan  if (!tree_versionable_function_p (old_decl))
1861169689Skan    return NULL;
1862132718Skan
1863169689Skan  /* Make a new FUNCTION_DECL tree node for the
1864169689Skan     new version. */
1865169689Skan  new_decl = copy_node (old_decl);
1866132718Skan
1867169689Skan  /* Create the new version's call-graph node.
1868169689Skan     and update the edges of the new node. */
1869169689Skan  new_version_node =
1870169689Skan    cgraph_copy_node_for_versioning (old_version_node, new_decl,
1871169689Skan				     redirect_callers);
1872132718Skan
1873169689Skan  /* Copy the OLD_VERSION_NODE function tree to the new version.  */
1874169689Skan  tree_function_versioning (old_decl, new_decl, tree_map, false);
1875169689Skan  /* Update the call_expr on the edges to call the new version node. */
1876169689Skan  update_call_expr (new_version_node);
1877132718Skan
1878169689Skan  /* Update the new version's properties.
1879169689Skan     Make The new version visible only within this translation unit.
1880169689Skan     ??? We cannot use COMDAT linkage because there is no
1881169689Skan     ABI support for this.  */
1882169689Skan  DECL_EXTERNAL (new_version_node->decl) = 0;
1883169689Skan  DECL_ONE_ONLY (new_version_node->decl) = 0;
1884169689Skan  TREE_PUBLIC (new_version_node->decl) = 0;
1885169689Skan  DECL_COMDAT (new_version_node->decl) = 0;
1886169689Skan  new_version_node->local.externally_visible = 0;
1887169689Skan  new_version_node->local.local = 1;
1888169689Skan  new_version_node->lowered = true;
1889169689Skan  return new_version_node;
1890169689Skan}
1891132718Skan
1892169689Skan/* Produce separate function body for inline clones so the offline copy can be
1893169689Skan   modified without affecting them.  */
1894169689Skanstruct cgraph_node *
1895169689Skansave_inline_function_body (struct cgraph_node *node)
1896132718Skan{
1897169689Skan  struct cgraph_node *first_clone;
1898132718Skan
1899169689Skan  gcc_assert (node == cgraph_node (node->decl));
1900132718Skan
1901169689Skan  cgraph_lower_function (node);
1902169689Skan
1903169689Skan  /* In non-unit-at-a-time we construct full fledged clone we never output to
1904169689Skan     assembly file.  This clone is pointed out by inline_decl of original function
1905169689Skan     and inlining infrastructure knows how to deal with this.  */
1906169689Skan  if (!flag_unit_at_a_time)
1907132718Skan    {
1908169689Skan      struct cgraph_edge *e;
1909169689Skan
1910169689Skan      first_clone = cgraph_clone_node (node, node->count, 0, false);
1911169689Skan      first_clone->needed = 0;
1912169689Skan      first_clone->reachable = 1;
1913169689Skan      /* Recursively clone all bodies.  */
1914169689Skan      for (e = first_clone->callees; e; e = e->next_callee)
1915169689Skan	if (!e->inline_failed)
1916169689Skan	  cgraph_clone_inlined_nodes (e, true, false);
1917132718Skan    }
1918169689Skan  else
1919169689Skan    first_clone = node->next_clone;
1920132718Skan
1921169689Skan  first_clone->decl = copy_node (node->decl);
1922169689Skan  node->next_clone = NULL;
1923132718Skan  if (!flag_unit_at_a_time)
1924169689Skan    node->inline_decl = first_clone->decl;
1925169689Skan  first_clone->prev_clone = NULL;
1926169689Skan  cgraph_insert_node_to_hashtable (first_clone);
1927169689Skan  gcc_assert (first_clone == cgraph_node (first_clone->decl));
1928132718Skan
1929169689Skan  /* Copy the OLD_VERSION_NODE function tree to the new version.  */
1930169689Skan  tree_function_versioning (node->decl, first_clone->decl, NULL, true);
1931132718Skan
1932169689Skan  DECL_EXTERNAL (first_clone->decl) = 0;
1933169689Skan  DECL_ONE_ONLY (first_clone->decl) = 0;
1934169689Skan  TREE_PUBLIC (first_clone->decl) = 0;
1935169689Skan  DECL_COMDAT (first_clone->decl) = 0;
1936132718Skan
1937169689Skan  for (node = first_clone->next_clone; node; node = node->next_clone)
1938169689Skan    node->decl = first_clone->decl;
1939169689Skan#ifdef ENABLE_CHECKING
1940169689Skan  verify_cgraph_node (first_clone);
1941169689Skan#endif
1942169689Skan  return first_clone;
1943132718Skan}
1944169689Skan
1945169689Skan#include "gt-cgraphunit.h"
1946