]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/cgraphunit.c
coretypes.h (gimple_seq, [...]): Typedef as gimple.
[thirdparty/gcc.git] / gcc / cgraphunit.c
1 /* Driver of optimization process
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
3 2011, 2012 Free Software Foundation, Inc.
4 Contributed by Jan Hubicka
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22 /* This module implements main driver of compilation process.
23
24 The main scope of this file is to act as an interface in between
25 tree based frontends and the backend.
26
27 The front-end is supposed to use following functionality:
28
29 - cgraph_finalize_function
30
31 This function is called once front-end has parsed whole body of function
32 and it is certain that the function body nor the declaration will change.
33
34 (There is one exception needed for implementing GCC extern inline
35 function.)
36
37 - varpool_finalize_variable
38
39 This function has same behavior as the above but is used for static
40 variables.
41
42 - add_asm_node
43
44 Insert new toplevel ASM statement
45
46 - finalize_compilation_unit
47
48 This function is called once (source level) compilation unit is finalized
49 and it will no longer change.
50
51 The symbol table is constructed starting from the trivially needed
52 symbols finalized by the frontend. Functions are lowered into
53 GIMPLE representation and callgraph/reference lists are constructed.
54 Those are used to discover other neccesary functions and variables.
55
56 At the end the bodies of unreachable functions are removed.
57
58 The function can be called multiple times when multiple source level
59 compilation units are combined.
60
61 - compile
62
63 This passes control to the back-end. Optimizations are performed and
64 final assembler is generated. This is done in the following way. Note
65 that with link time optimization the process is split into three
66 stages (compile time, linktime analysis and parallel linktime as
67 indicated bellow).
68
69 Compile time:
70
71 1) Inter-procedural optimization.
72 (ipa_passes)
73
74 This part is further split into:
75
76 a) early optimizations. These are local passes executed in
77 the topological order on the callgraph.
78
79 The purpose of early optimiations is to optimize away simple
80 things that may otherwise confuse IP analysis. Very simple
81 propagation across the callgraph is done i.e. to discover
82 functions without side effects and simple inlining is performed.
83
84 b) early small interprocedural passes.
85
86 Those are interprocedural passes executed only at compilation
87 time. These include, for exmaple, transational memory lowering,
88 unreachable code removal and other simple transformations.
89
90 c) IP analysis stage. All interprocedural passes do their
91 analysis.
92
93 Interprocedural passes differ from small interprocedural
94 passes by their ability to operate across whole program
95 at linktime. Their analysis stage is performed early to
96 both reduce linking times and linktime memory usage by
97 not having to represent whole program in memory.
98
99 d) LTO sreaming. When doing LTO, everything important gets
100 streamed into the object file.
101
102 Compile time and or linktime analysis stage (WPA):
103
104 At linktime units gets streamed back and symbol table is
105 merged. Function bodies are not streamed in and not
106 available.
107 e) IP propagation stage. All IP passes execute their
108 IP propagation. This is done based on the earlier analysis
109 without having function bodies at hand.
110 f) Ltrans streaming. When doing WHOPR LTO, the program
111 is partitioned and streamed into multple object files.
112
113 Compile time and/or parallel linktime stage (ltrans)
114
115 Each of the object files is streamed back and compiled
116 separately. Now the function bodies becomes available
117 again.
118
119 2) Virtual clone materialization
120 (cgraph_materialize_clone)
121
122 IP passes can produce copies of existing functoins (such
123 as versioned clones or inline clones) without actually
124 manipulating their bodies by creating virtual clones in
125 the callgraph. At this time the virtual clones are
126 turned into real functions
127 3) IP transformation
128
129 All IP passes transform function bodies based on earlier
130 decision of the IP propagation.
131
132 4) late small IP passes
133
134 Simple IP passes working within single program partition.
135
136 5) Expansion
137 (expand_all_functions)
138
139 At this stage functions that needs to be output into
140 assembler are identified and compiled in topological order
141 6) Output of variables and aliases
142 Now it is known what variable references was not optimized
143 out and thus all variables are output to the file.
144
145 Note that with -fno-toplevel-reorder passes 5 and 6
146 are combined together in cgraph_output_in_order.
147
148 Finally there are functions to manipulate the callgraph from
149 backend.
150 - cgraph_add_new_function is used to add backend produced
151 functions introduced after the unit is finalized.
152 The functions are enqueue for later processing and inserted
153 into callgraph with cgraph_process_new_functions.
154
155 - cgraph_function_versioning
156
157 produces a copy of function into new one (a version)
158 and apply simple transformations
159 */
160
161 #include "config.h"
162 #include "system.h"
163 #include "coretypes.h"
164 #include "tm.h"
165 #include "tree.h"
166 #include "output.h"
167 #include "rtl.h"
168 #include "tree-flow.h"
169 #include "tree-inline.h"
170 #include "langhooks.h"
171 #include "pointer-set.h"
172 #include "toplev.h"
173 #include "flags.h"
174 #include "ggc.h"
175 #include "debug.h"
176 #include "target.h"
177 #include "cgraph.h"
178 #include "diagnostic.h"
179 #include "timevar.h"
180 #include "params.h"
181 #include "fibheap.h"
182 #include "intl.h"
183 #include "function.h"
184 #include "ipa-prop.h"
185 #include "gimple.h"
186 #include "tree-iterator.h"
187 #include "tree-pass.h"
188 #include "tree-dump.h"
189 #include "gimple-pretty-print.h"
190 #include "output.h"
191 #include "coverage.h"
192 #include "plugin.h"
193 #include "ipa-inline.h"
194 #include "ipa-utils.h"
195 #include "lto-streamer.h"
196 #include "except.h"
197 #include "regset.h" /* FIXME: For reg_obstack. */
198
199 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
200 secondary queue used during optimization to accommodate passes that
201 may generate new functions that need to be optimized and expanded. */
202 cgraph_node_set cgraph_new_nodes;
203
204 static void expand_all_functions (void);
205 static void mark_functions_to_output (void);
206 static void expand_function (struct cgraph_node *);
207 static void cgraph_analyze_function (struct cgraph_node *);
208
209 FILE *cgraph_dump_file;
210
211 /* Linked list of cgraph asm nodes. */
212 struct asm_node *asm_nodes;
213
214 /* Last node in cgraph_asm_nodes. */
215 static GTY(()) struct asm_node *asm_last_node;
216
217 /* Used for vtable lookup in thunk adjusting. */
218 static GTY (()) tree vtable_entry_type;
219
220 /* Determine if function DECL is trivially needed and should stay in the
221 compilation unit. This is used at the symbol table construction time
222 and differs from later logic removing unnecesary functions that can
223 take into account results of analysis, whole program info etc. */
224
225 static bool
226 cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
227 {
228 /* If the user told us it is used, then it must be so. */
229 if (node->symbol.force_output)
230 return true;
231
232 /* Double check that no one output the function into assembly file
233 early. */
234 gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
235 || (node->thunk.thunk_p || node->same_body_alias)
236 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
237
238
239 /* Keep constructors, destructors and virtual functions. */
240 if (DECL_STATIC_CONSTRUCTOR (decl)
241 || DECL_STATIC_DESTRUCTOR (decl)
242 || (DECL_VIRTUAL_P (decl)
243 && optimize && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl))))
244 return true;
245
246 /* Externally visible functions must be output. The exception is
247 COMDAT functions that must be output only when they are needed. */
248
249 if (TREE_PUBLIC (decl)
250 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
251 return true;
252
253 return false;
254 }
255
256 /* Head of the queue of nodes to be processed while building callgraph */
257
258 static symtab_node first = (symtab_node)(void *)1;
259
260 /* Add NODE to queue starting at FIRST.
261 The queue is linked via AUX pointers and terminated by pointer to 1. */
262
263 static void
264 enqueue_node (symtab_node node)
265 {
266 if (node->symbol.aux)
267 return;
268 gcc_checking_assert (first);
269 node->symbol.aux = first;
270 first = node;
271 }
272
273 /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
274 functions into callgraph in a way so they look like ordinary reachable
275 functions inserted into callgraph already at construction time. */
276
277 bool
278 cgraph_process_new_functions (void)
279 {
280 bool output = false;
281 tree fndecl;
282 struct cgraph_node *node;
283 cgraph_node_set_iterator csi;
284
285 if (!cgraph_new_nodes)
286 return false;
287 /* Note that this queue may grow as its being processed, as the new
288 functions may generate new ones. */
289 for (csi = csi_start (cgraph_new_nodes); !csi_end_p (csi); csi_next (&csi))
290 {
291 node = csi_node (csi);
292 fndecl = node->symbol.decl;
293 switch (cgraph_state)
294 {
295 case CGRAPH_STATE_CONSTRUCTION:
296 /* At construction time we just need to finalize function and move
297 it into reachable functions list. */
298
299 cgraph_finalize_function (fndecl, false);
300 output = true;
301 cgraph_call_function_insertion_hooks (node);
302 enqueue_node ((symtab_node) node);
303 break;
304
305 case CGRAPH_STATE_IPA:
306 case CGRAPH_STATE_IPA_SSA:
307 /* When IPA optimization already started, do all essential
308 transformations that has been already performed on the whole
309 cgraph but not on this function. */
310
311 gimple_register_cfg_hooks ();
312 if (!node->analyzed)
313 cgraph_analyze_function (node);
314 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
315 current_function_decl = fndecl;
316 if ((cgraph_state == CGRAPH_STATE_IPA_SSA
317 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
318 /* When not optimizing, be sure we run early local passes anyway
319 to expand OMP. */
320 || !optimize)
321 execute_pass_list (pass_early_local_passes.pass.sub);
322 else
323 compute_inline_parameters (node, true);
324 free_dominance_info (CDI_POST_DOMINATORS);
325 free_dominance_info (CDI_DOMINATORS);
326 pop_cfun ();
327 current_function_decl = NULL;
328 cgraph_call_function_insertion_hooks (node);
329 break;
330
331 case CGRAPH_STATE_EXPANSION:
332 /* Functions created during expansion shall be compiled
333 directly. */
334 node->process = 0;
335 cgraph_call_function_insertion_hooks (node);
336 expand_function (node);
337 break;
338
339 default:
340 gcc_unreachable ();
341 break;
342 }
343 }
344 free_cgraph_node_set (cgraph_new_nodes);
345 cgraph_new_nodes = NULL;
346 return output;
347 }
348
349 /* As an GCC extension we allow redefinition of the function. The
350 semantics when both copies of bodies differ is not well defined.
351 We replace the old body with new body so in unit at a time mode
352 we always use new body, while in normal mode we may end up with
353 old body inlined into some functions and new body expanded and
354 inlined in others.
355
356 ??? It may make more sense to use one body for inlining and other
357 body for expanding the function but this is difficult to do. */
358
359 static void
360 cgraph_reset_node (struct cgraph_node *node)
361 {
362 /* If node->process is set, then we have already begun whole-unit analysis.
363 This is *not* testing for whether we've already emitted the function.
364 That case can be sort-of legitimately seen with real function redefinition
365 errors. I would argue that the front end should never present us with
366 such a case, but don't enforce that for now. */
367 gcc_assert (!node->process);
368
369 /* Reset our data structures so we can analyze the function again. */
370 memset (&node->local, 0, sizeof (node->local));
371 memset (&node->global, 0, sizeof (node->global));
372 memset (&node->rtl, 0, sizeof (node->rtl));
373 node->analyzed = false;
374 node->local.finalized = false;
375
376 cgraph_node_remove_callees (node);
377 }
378
379 /* Return true when there are references to NODE. */
380
381 static bool
382 referred_to_p (symtab_node node)
383 {
384 struct ipa_ref *ref;
385
386 /* See if there are any refrences at all. */
387 if (ipa_ref_list_referring_iterate (&node->symbol.ref_list, 0, ref))
388 return true;
389 /* For functions check also calls. */
390 if (symtab_function_p (node) && cgraph (node)->callers)
391 return true;
392 return false;
393 }
394
395 /* DECL has been parsed. Take it, queue it, compile it at the whim of the
396 logic in effect. If NESTED is true, then our caller cannot stand to have
397 the garbage collector run at the moment. We would need to either create
398 a new GC context, or just not compile right now. */
399
400 void
401 cgraph_finalize_function (tree decl, bool nested)
402 {
403 struct cgraph_node *node = cgraph_get_create_node (decl);
404
405 if (node->local.finalized)
406 {
407 cgraph_reset_node (node);
408 node->local.redefined_extern_inline = true;
409 }
410
411 notice_global_symbol (decl);
412 node->local.finalized = true;
413 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
414
415 /* With -fkeep-inline-functions we are keeping all inline functions except
416 for extern inline ones. */
417 if (flag_keep_inline_functions
418 && DECL_DECLARED_INLINE_P (decl)
419 && !DECL_EXTERNAL (decl)
420 && !DECL_DISREGARD_INLINE_LIMITS (decl))
421 node->symbol.force_output = 1;
422
423 /* When not optimizing, also output the static functions. (see
424 PR24561), but don't do so for always_inline functions, functions
425 declared inline and nested functions. These were optimized out
426 in the original implementation and it is unclear whether we want
427 to change the behavior here. */
428 if ((!optimize
429 && !node->same_body_alias
430 && !DECL_DISREGARD_INLINE_LIMITS (decl)
431 && !DECL_DECLARED_INLINE_P (decl)
432 && !(DECL_CONTEXT (decl)
433 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))
434 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
435 node->symbol.force_output = 1;
436
437 /* If we've not yet emitted decl, tell the debug info about it. */
438 if (!TREE_ASM_WRITTEN (decl))
439 (*debug_hooks->deferred_inline_function) (decl);
440
441 /* Possibly warn about unused parameters. */
442 if (warn_unused_parameter)
443 do_warn_unused_parameter (decl);
444
445 if (!nested)
446 ggc_collect ();
447
448 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
449 && (cgraph_decide_is_function_needed (node, decl)
450 || referred_to_p ((symtab_node)node)))
451 enqueue_node ((symtab_node)node);
452 }
453
454 /* Add the function FNDECL to the call graph.
455 Unlike cgraph_finalize_function, this function is intended to be used
456 by middle end and allows insertion of new function at arbitrary point
457 of compilation. The function can be either in high, low or SSA form
458 GIMPLE.
459
460 The function is assumed to be reachable and have address taken (so no
461 API breaking optimizations are performed on it).
462
463 Main work done by this function is to enqueue the function for later
464 processing to avoid need the passes to be re-entrant. */
465
466 void
467 cgraph_add_new_function (tree fndecl, bool lowered)
468 {
469 struct cgraph_node *node;
470 switch (cgraph_state)
471 {
472 case CGRAPH_STATE_PARSING:
473 cgraph_finalize_function (fndecl, false);
474 break;
475 case CGRAPH_STATE_CONSTRUCTION:
476 /* Just enqueue function to be processed at nearest occurrence. */
477 node = cgraph_create_node (fndecl);
478 if (lowered)
479 node->lowered = true;
480 if (!cgraph_new_nodes)
481 cgraph_new_nodes = cgraph_node_set_new ();
482 cgraph_node_set_add (cgraph_new_nodes, node);
483 break;
484
485 case CGRAPH_STATE_IPA:
486 case CGRAPH_STATE_IPA_SSA:
487 case CGRAPH_STATE_EXPANSION:
488 /* Bring the function into finalized state and enqueue for later
489 analyzing and compilation. */
490 node = cgraph_get_create_node (fndecl);
491 node->local.local = false;
492 node->local.finalized = true;
493 node->symbol.force_output = true;
494 if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
495 {
496 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
497 current_function_decl = fndecl;
498 gimple_register_cfg_hooks ();
499 bitmap_obstack_initialize (NULL);
500 execute_pass_list (all_lowering_passes);
501 execute_pass_list (pass_early_local_passes.pass.sub);
502 bitmap_obstack_release (NULL);
503 pop_cfun ();
504 current_function_decl = NULL;
505
506 lowered = true;
507 }
508 if (lowered)
509 node->lowered = true;
510 if (!cgraph_new_nodes)
511 cgraph_new_nodes = cgraph_node_set_new ();
512 cgraph_node_set_add (cgraph_new_nodes, node);
513 break;
514
515 case CGRAPH_STATE_FINISHED:
516 /* At the very end of compilation we have to do all the work up
517 to expansion. */
518 node = cgraph_create_node (fndecl);
519 if (lowered)
520 node->lowered = true;
521 cgraph_analyze_function (node);
522 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
523 current_function_decl = fndecl;
524 gimple_register_cfg_hooks ();
525 bitmap_obstack_initialize (NULL);
526 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
527 execute_pass_list (pass_early_local_passes.pass.sub);
528 bitmap_obstack_release (NULL);
529 pop_cfun ();
530 expand_function (node);
531 current_function_decl = NULL;
532 break;
533
534 default:
535 gcc_unreachable ();
536 }
537
538 /* Set a personality if required and we already passed EH lowering. */
539 if (lowered
540 && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
541 == eh_personality_lang))
542 DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
543 }
544
545 /* Add a top-level asm statement to the list. */
546
547 struct asm_node *
548 add_asm_node (tree asm_str)
549 {
550 struct asm_node *node;
551
552 node = ggc_alloc_cleared_asm_node ();
553 node->asm_str = asm_str;
554 node->order = symtab_order++;
555 node->next = NULL;
556 if (asm_nodes == NULL)
557 asm_nodes = node;
558 else
559 asm_last_node->next = node;
560 asm_last_node = node;
561 return node;
562 }
563
564 /* Output all asm statements we have stored up to be output. */
565
566 static void
567 output_asm_statements (void)
568 {
569 struct asm_node *can;
570
571 if (seen_error ())
572 return;
573
574 for (can = asm_nodes; can; can = can->next)
575 assemble_asm (can->asm_str);
576 asm_nodes = NULL;
577 }
578
579 /* C++ FE sometimes change linkage flags after producing same body aliases. */
580 void
581 fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias)
582 {
583 DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (alias);
584 if (TREE_PUBLIC (node->symbol.decl))
585 {
586 DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (alias);
587 DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (alias);
588 DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (alias);
589 if (DECL_ONE_ONLY (alias)
590 && !node->symbol.same_comdat_group)
591 symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target);
592 }
593 }
594
595 /* Analyze the function scheduled to be output. */
596 static void
597 cgraph_analyze_function (struct cgraph_node *node)
598 {
599 tree save = current_function_decl;
600 tree decl = node->symbol.decl;
601 location_t saved_loc = input_location;
602 input_location = DECL_SOURCE_LOCATION (decl);
603
604 if (node->alias && node->thunk.alias)
605 {
606 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
607 struct cgraph_node *n;
608
609 for (n = tgt; n && n->alias;
610 n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
611 if (n == node)
612 {
613 error ("function %q+D part of alias cycle", node->symbol.decl);
614 node->alias = false;
615 input_location = saved_loc;
616 return;
617 }
618 if (!VEC_length (ipa_ref_t, node->symbol.ref_list.references))
619 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
620 IPA_REF_ALIAS, NULL);
621 if (node->same_body_alias)
622 {
623 DECL_DECLARED_INLINE_P (node->symbol.decl)
624 = DECL_DECLARED_INLINE_P (node->thunk.alias);
625 DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
626 = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
627 fixup_same_cpp_alias_visibility ((symtab_node) node, (symtab_node) tgt, node->thunk.alias);
628 }
629
630 if (node->symbol.address_taken)
631 cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
632 }
633 else if (node->thunk.thunk_p)
634 {
635 cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
636 NULL, 0, CGRAPH_FREQ_BASE);
637 }
638 else
639 {
640 current_function_decl = decl;
641 push_cfun (DECL_STRUCT_FUNCTION (decl));
642
643 assign_assembler_name_if_neeeded (node->symbol.decl);
644
645 /* Make sure to gimplify bodies only once. During analyzing a
646 function we lower it, which will require gimplified nested
647 functions, so we can end up here with an already gimplified
648 body. */
649 if (!gimple_has_body_p (decl))
650 gimplify_function_tree (decl);
651 dump_function (TDI_generic, decl);
652
653 /* Lower the function. */
654 if (!node->lowered)
655 {
656 if (node->nested)
657 lower_nested_functions (node->symbol.decl);
658 gcc_assert (!node->nested);
659
660 gimple_register_cfg_hooks ();
661 bitmap_obstack_initialize (NULL);
662 execute_pass_list (all_lowering_passes);
663 free_dominance_info (CDI_POST_DOMINATORS);
664 free_dominance_info (CDI_DOMINATORS);
665 compact_blocks ();
666 bitmap_obstack_release (NULL);
667 node->lowered = true;
668 }
669
670 pop_cfun ();
671 }
672 node->analyzed = true;
673
674 current_function_decl = save;
675 input_location = saved_loc;
676 }
677
678 /* C++ frontend produce same body aliases all over the place, even before PCH
679 gets streamed out. It relies on us linking the aliases with their function
680 in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
681 first produce aliases without links, but once C++ FE is sure he won't sream
682 PCH we build the links via this function. */
683
684 void
685 cgraph_process_same_body_aliases (void)
686 {
687 struct cgraph_node *node;
688 FOR_EACH_FUNCTION (node)
689 if (node->same_body_alias
690 && !VEC_length (ipa_ref_t, node->symbol.ref_list.references))
691 {
692 struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
693 ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
694 IPA_REF_ALIAS, NULL);
695 }
696 same_body_aliases_done = true;
697 }
698
699 /* Process attributes common for vars and functions. */
700
701 static void
702 process_common_attributes (tree decl)
703 {
704 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
705
706 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl)))
707 {
708 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
709 "%<weakref%> attribute should be accompanied with"
710 " an %<alias%> attribute");
711 DECL_WEAK (decl) = 0;
712 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
713 DECL_ATTRIBUTES (decl));
714 }
715 }
716
717 /* Look for externally_visible and used attributes and mark cgraph nodes
718 accordingly.
719
720 We cannot mark the nodes at the point the attributes are processed (in
721 handle_*_attribute) because the copy of the declarations available at that
722 point may not be canonical. For example, in:
723
724 void f();
725 void f() __attribute__((used));
726
727 the declaration we see in handle_used_attribute will be the second
728 declaration -- but the front end will subsequently merge that declaration
729 with the original declaration and discard the second declaration.
730
731 Furthermore, we can't mark these nodes in cgraph_finalize_function because:
732
733 void f() {}
734 void f() __attribute__((externally_visible));
735
736 is valid.
737
738 So, we walk the nodes at the end of the translation unit, applying the
739 attributes at that point. */
740
741 static void
742 process_function_and_variable_attributes (struct cgraph_node *first,
743 struct varpool_node *first_var)
744 {
745 struct cgraph_node *node;
746 struct varpool_node *vnode;
747
748 for (node = cgraph_first_function (); node != first;
749 node = cgraph_next_function (node))
750 {
751 tree decl = node->symbol.decl;
752 if (DECL_PRESERVE_P (decl))
753 cgraph_mark_force_output_node (node);
754 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
755 {
756 if (! TREE_PUBLIC (node->symbol.decl))
757 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
758 "%<externally_visible%>"
759 " attribute have effect only on public objects");
760 }
761 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
762 && (node->local.finalized && !node->alias))
763 {
764 warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
765 "%<weakref%> attribute ignored"
766 " because function is defined");
767 DECL_WEAK (decl) = 0;
768 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
769 DECL_ATTRIBUTES (decl));
770 }
771
772 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
773 && !DECL_DECLARED_INLINE_P (decl)
774 /* redefining extern inline function makes it DECL_UNINLINABLE. */
775 && !DECL_UNINLINABLE (decl))
776 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
777 "always_inline function might not be inlinable");
778
779 process_common_attributes (decl);
780 }
781 for (vnode = varpool_first_variable (); vnode != first_var;
782 vnode = varpool_next_variable (vnode))
783 {
784 tree decl = vnode->symbol.decl;
785 if (DECL_PRESERVE_P (decl))
786 vnode->symbol.force_output = true;
787 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
788 {
789 if (! TREE_PUBLIC (vnode->symbol.decl))
790 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
791 "%<externally_visible%>"
792 " attribute have effect only on public objects");
793 }
794 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
795 && vnode->finalized
796 && DECL_INITIAL (decl))
797 {
798 warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
799 "%<weakref%> attribute ignored"
800 " because variable is initialized");
801 DECL_WEAK (decl) = 0;
802 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
803 DECL_ATTRIBUTES (decl));
804 }
805 process_common_attributes (decl);
806 }
807 }
808
809 /* Mark DECL as finalized. By finalizing the declaration, frontend instruct the
810 middle end to output the variable to asm file, if needed or externally
811 visible. */
812
813 void
814 varpool_finalize_decl (tree decl)
815 {
816 struct varpool_node *node = varpool_node (decl);
817
818 gcc_assert (TREE_STATIC (decl));
819
820 if (node->finalized)
821 return;
822 notice_global_symbol (decl);
823 node->finalized = true;
824 if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
825 /* Traditionally we do not eliminate static variables when not
826 optimizing and when not doing toplevel reoder. */
827 || (!flag_toplevel_reorder && !DECL_COMDAT (node->symbol.decl)
828 && !DECL_ARTIFICIAL (node->symbol.decl)))
829 node->symbol.force_output = true;
830
831 if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
832 && (decide_is_variable_needed (node, decl)
833 || referred_to_p ((symtab_node)node)))
834 enqueue_node ((symtab_node)node);
835 if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
836 varpool_analyze_node (node);
837 }
838
839 /* Discover all functions and variables that are trivially needed, analyze
840 them as well as all functions and variables referred by them */
841
842 static void
843 cgraph_analyze_functions (void)
844 {
845 /* Keep track of already processed nodes when called multiple times for
846 intermodule optimization. */
847 static struct cgraph_node *first_analyzed;
848 struct cgraph_node *first_handled = first_analyzed;
849 static struct varpool_node *first_analyzed_var;
850 struct varpool_node *first_handled_var = first_analyzed_var;
851
852 symtab_node node, next;
853 int i;
854 struct ipa_ref *ref;
855 bool changed = true;
856
857 bitmap_obstack_initialize (NULL);
858 cgraph_state = CGRAPH_STATE_CONSTRUCTION;
859
860 /* Analysis adds static variables that in turn adds references to new functions.
861 So we need to iterate the process until it stabilize. */
862 while (changed)
863 {
864 changed = false;
865 process_function_and_variable_attributes (first_analyzed,
866 first_analyzed_var);
867
868 /* First identify the trivially needed symbols. */
869 for (node = symtab_nodes;
870 node != (symtab_node)first_analyzed
871 && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
872 {
873 if ((symtab_function_p (node)
874 && cgraph (node)->local.finalized
875 && cgraph_decide_is_function_needed (cgraph (node), node->symbol.decl))
876 || (symtab_variable_p (node)
877 && varpool (node)->finalized
878 && !DECL_EXTERNAL (node->symbol.decl)
879 && decide_is_variable_needed (varpool (node), node->symbol.decl)))
880 {
881 enqueue_node (node);
882 if (!changed && cgraph_dump_file)
883 fprintf (cgraph_dump_file, "Trivially needed symbols:");
884 changed = true;
885 if (cgraph_dump_file)
886 fprintf (cgraph_dump_file, " %s", symtab_node_asm_name (node));
887 }
888 if (node == (symtab_node)first_analyzed
889 || node == (symtab_node)first_analyzed_var)
890 break;
891 }
892 cgraph_process_new_functions ();
893 first_analyzed_var = varpool_first_variable ();
894 first_analyzed = cgraph_first_function ();
895
896 if (changed && dump_file)
897 fprintf (cgraph_dump_file, "\n");
898
899 /* Lower representation, build callgraph edges and references for all trivially
900 needed symbols and all symbols referred by them. */
901 while (first != (symtab_node)(void *)1)
902 {
903 changed = true;
904 node = first;
905 first = (symtab_node)first->symbol.aux;
906 if (symtab_function_p (node) && cgraph (node)->local.finalized)
907 {
908 struct cgraph_edge *edge;
909 struct cgraph_node *cnode;
910 tree decl;
911
912 cnode = cgraph (node);
913 decl = cnode->symbol.decl;
914
915 /* ??? It is possible to create extern inline function and later using
916 weak alias attribute to kill its body. See
917 gcc.c-torture/compile/20011119-1.c */
918 if (!DECL_STRUCT_FUNCTION (decl)
919 && (!cnode->alias || !cnode->thunk.alias)
920 && !cnode->thunk.thunk_p)
921 {
922 cgraph_reset_node (cnode);
923 cnode->local.redefined_extern_inline = true;
924 continue;
925 }
926
927 if (!cnode->analyzed)
928 cgraph_analyze_function (cnode);
929
930 for (edge = cnode->callees; edge; edge = edge->next_callee)
931 if (edge->callee->local.finalized)
932 enqueue_node ((symtab_node)edge->callee);
933
934 /* If decl is a clone of an abstract function, mark that abstract
935 function so that we don't release its body. The DECL_INITIAL() of that
936 abstract function declaration will be later needed to output debug
937 info. */
938 if (DECL_ABSTRACT_ORIGIN (decl))
939 {
940 struct cgraph_node *origin_node;
941 origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
942 origin_node->abstract_and_needed = true;
943 }
944
945 }
946 else if (symtab_variable_p (node)
947 && varpool (node)->finalized)
948 varpool_analyze_node (varpool (node));
949
950 if (node->symbol.same_comdat_group)
951 {
952 symtab_node next;
953 for (next = node->symbol.same_comdat_group;
954 next != node;
955 next = next->symbol.same_comdat_group)
956 enqueue_node (next);
957 }
958 for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
959 if ((symtab_function_p (ref->referred) && cgraph (ref->referred)->local.finalized)
960 || (symtab_variable_p (ref->referred) && varpool (ref->referred)->finalized))
961 enqueue_node (ref->referred);
962 cgraph_process_new_functions ();
963 }
964 }
965
966 /* Collect entry points to the unit. */
967 if (cgraph_dump_file)
968 {
969 fprintf (cgraph_dump_file, "\n\nInitial ");
970 dump_symtab (cgraph_dump_file);
971 }
972
973 if (cgraph_dump_file)
974 fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
975
976 for (node = symtab_nodes;
977 node != (symtab_node)first_handled
978 && node != (symtab_node)first_handled_var; node = next)
979 {
980 next = node->symbol.next;
981 if (!node->symbol.aux && !referred_to_p (node))
982 {
983 if (cgraph_dump_file)
984 fprintf (cgraph_dump_file, " %s", symtab_node_name (node));
985 symtab_remove_node (node);
986 continue;
987 }
988 if (symtab_function_p (node))
989 {
990 tree decl = node->symbol.decl;
991 struct cgraph_node *cnode = cgraph (node);
992
993 if (cnode->local.finalized && !gimple_has_body_p (decl)
994 && (!cnode->alias || !cnode->thunk.alias)
995 && !cnode->thunk.thunk_p)
996 cgraph_reset_node (cnode);
997
998 gcc_assert (!cnode->local.finalized || cnode->thunk.thunk_p
999 || cnode->alias
1000 || gimple_has_body_p (decl));
1001 gcc_assert (cnode->analyzed == cnode->local.finalized);
1002 }
1003 node->symbol.aux = NULL;
1004 }
1005 first_analyzed = cgraph_first_function ();
1006 first_analyzed_var = varpool_first_variable ();
1007 if (cgraph_dump_file)
1008 {
1009 fprintf (cgraph_dump_file, "\n\nReclaimed ");
1010 dump_symtab (cgraph_dump_file);
1011 }
1012 bitmap_obstack_release (NULL);
1013 ggc_collect ();
1014 }
1015
1016 /* Translate the ugly representation of aliases as alias pairs into nice
1017 representation in callgraph. We don't handle all cases yet,
1018 unforutnately. */
1019
1020 static void
1021 handle_alias_pairs (void)
1022 {
1023 alias_pair *p;
1024 unsigned i;
1025 struct cgraph_node *target_node;
1026 struct cgraph_node *src_node;
1027 struct varpool_node *target_vnode;
1028
1029 for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
1030 {
1031 if (TREE_CODE (p->decl) == FUNCTION_DECL
1032 && (target_node = cgraph_node_for_asm (p->target)) != NULL)
1033 {
1034 src_node = cgraph_get_node (p->decl);
1035 if (src_node && src_node->local.finalized)
1036 cgraph_reset_node (src_node);
1037 /* Normally EXTERNAL flag is used to mark external inlines,
1038 however for aliases it seems to be allowed to use it w/o
1039 any meaning. See gcc.dg/attr-alias-3.c
1040 However for weakref we insist on EXTERNAL flag being set.
1041 See gcc.dg/attr-alias-5.c */
1042 if (DECL_EXTERNAL (p->decl))
1043 DECL_EXTERNAL (p->decl)
1044 = lookup_attribute ("weakref",
1045 DECL_ATTRIBUTES (p->decl)) != NULL;
1046 cgraph_create_function_alias (p->decl, target_node->symbol.decl);
1047 VEC_unordered_remove (alias_pair, alias_pairs, i);
1048 }
1049 else if (TREE_CODE (p->decl) == VAR_DECL
1050 && (target_vnode = varpool_node_for_asm (p->target)) != NULL)
1051 {
1052 /* Normally EXTERNAL flag is used to mark external inlines,
1053 however for aliases it seems to be allowed to use it w/o
1054 any meaning. See gcc.dg/attr-alias-3.c
1055 However for weakref we insist on EXTERNAL flag being set.
1056 See gcc.dg/attr-alias-5.c */
1057 if (DECL_EXTERNAL (p->decl))
1058 DECL_EXTERNAL (p->decl)
1059 = lookup_attribute ("weakref",
1060 DECL_ATTRIBUTES (p->decl)) != NULL;
1061 varpool_create_variable_alias (p->decl, target_vnode->symbol.decl);
1062 VEC_unordered_remove (alias_pair, alias_pairs, i);
1063 }
1064 /* Weakrefs with target not defined in current unit are easy to handle; they
1065 behave just as external variables except we need to note the alias flag
1066 to later output the weakref pseudo op into asm file. */
1067 else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL
1068 && (TREE_CODE (p->decl) == FUNCTION_DECL
1069 ? (varpool_node_for_asm (p->target) == NULL)
1070 : (cgraph_node_for_asm (p->target) == NULL)))
1071 {
1072 if (TREE_CODE (p->decl) == FUNCTION_DECL)
1073 cgraph_get_create_node (p->decl)->alias = true;
1074 else
1075 varpool_get_node (p->decl)->alias = true;
1076 DECL_EXTERNAL (p->decl) = 1;
1077 VEC_unordered_remove (alias_pair, alias_pairs, i);
1078 }
1079 else
1080 {
1081 if (dump_file)
1082 fprintf (dump_file, "Unhandled alias %s->%s\n",
1083 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)),
1084 IDENTIFIER_POINTER (p->target));
1085
1086 i++;
1087 }
1088 }
1089 }
1090
1091
1092 /* Figure out what functions we want to assemble. */
1093
1094 static void
1095 mark_functions_to_output (void)
1096 {
1097 struct cgraph_node *node;
1098 #ifdef ENABLE_CHECKING
1099 bool check_same_comdat_groups = false;
1100
1101 FOR_EACH_FUNCTION (node)
1102 gcc_assert (!node->process);
1103 #endif
1104
1105 FOR_EACH_FUNCTION (node)
1106 {
1107 tree decl = node->symbol.decl;
1108
1109 gcc_assert (!node->process || node->symbol.same_comdat_group);
1110 if (node->process)
1111 continue;
1112
1113 /* We need to output all local functions that are used and not
1114 always inlined, as well as those that are reachable from
1115 outside the current compilation unit. */
1116 if (node->analyzed
1117 && !node->thunk.thunk_p
1118 && !node->alias
1119 && !node->global.inlined_to
1120 && !TREE_ASM_WRITTEN (decl)
1121 && !DECL_EXTERNAL (decl))
1122 {
1123 node->process = 1;
1124 if (node->symbol.same_comdat_group)
1125 {
1126 struct cgraph_node *next;
1127 for (next = cgraph (node->symbol.same_comdat_group);
1128 next != node;
1129 next = cgraph (next->symbol.same_comdat_group))
1130 if (!next->thunk.thunk_p && !next->alias)
1131 next->process = 1;
1132 }
1133 }
1134 else if (node->symbol.same_comdat_group)
1135 {
1136 #ifdef ENABLE_CHECKING
1137 check_same_comdat_groups = true;
1138 #endif
1139 }
1140 else
1141 {
1142 /* We should've reclaimed all functions that are not needed. */
1143 #ifdef ENABLE_CHECKING
1144 if (!node->global.inlined_to
1145 && gimple_has_body_p (decl)
1146 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1147 are inside partition, we can end up not removing the body since we no longer
1148 have analyzed node pointing to it. */
1149 && !node->symbol.in_other_partition
1150 && !node->alias
1151 && !DECL_EXTERNAL (decl))
1152 {
1153 dump_cgraph_node (stderr, node);
1154 internal_error ("failed to reclaim unneeded function");
1155 }
1156 #endif
1157 gcc_assert (node->global.inlined_to
1158 || !gimple_has_body_p (decl)
1159 || node->symbol.in_other_partition
1160 || DECL_EXTERNAL (decl));
1161
1162 }
1163
1164 }
1165 #ifdef ENABLE_CHECKING
1166 if (check_same_comdat_groups)
1167 FOR_EACH_FUNCTION (node)
1168 if (node->symbol.same_comdat_group && !node->process)
1169 {
1170 tree decl = node->symbol.decl;
1171 if (!node->global.inlined_to
1172 && gimple_has_body_p (decl)
1173 /* FIXME: in an ltrans unit when the offline copy is outside a
1174 partition but inline copies are inside a partition, we can
1175 end up not removing the body since we no longer have an
1176 analyzed node pointing to it. */
1177 && !node->symbol.in_other_partition
1178 && !DECL_EXTERNAL (decl))
1179 {
1180 dump_cgraph_node (stderr, node);
1181 internal_error ("failed to reclaim unneeded function in same "
1182 "comdat group");
1183 }
1184 }
1185 #endif
1186 }
1187
1188 /* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
1189 in lowered gimple form.
1190
1191 Set current_function_decl and cfun to newly constructed empty function body.
1192 return basic block in the function body. */
1193
1194 static basic_block
1195 init_lowered_empty_function (tree decl)
1196 {
1197 basic_block bb;
1198
1199 current_function_decl = decl;
1200 allocate_struct_function (decl, false);
1201 gimple_register_cfg_hooks ();
1202 init_empty_tree_cfg ();
1203 init_tree_ssa (cfun);
1204 init_ssa_operands ();
1205 cfun->gimple_df->in_ssa_p = true;
1206 DECL_INITIAL (decl) = make_node (BLOCK);
1207
1208 DECL_SAVED_TREE (decl) = error_mark_node;
1209 cfun->curr_properties |=
1210 (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_referenced_vars |
1211 PROP_ssa | PROP_gimple_any);
1212
1213 /* Create BB for body of the function and connect it properly. */
1214 bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR);
1215 make_edge (ENTRY_BLOCK_PTR, bb, 0);
1216 make_edge (bb, EXIT_BLOCK_PTR, 0);
1217
1218 return bb;
1219 }
1220
1221 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
1222 offset indicated by VIRTUAL_OFFSET, if that is
1223 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
1224 zero for a result adjusting thunk. */
1225
1226 static tree
1227 thunk_adjust (gimple_stmt_iterator * bsi,
1228 tree ptr, bool this_adjusting,
1229 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1230 {
1231 gimple stmt;
1232 tree ret;
1233
1234 if (this_adjusting
1235 && fixed_offset != 0)
1236 {
1237 stmt = gimple_build_assign
1238 (ptr, fold_build_pointer_plus_hwi_loc (input_location,
1239 ptr,
1240 fixed_offset));
1241 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1242 }
1243
1244 /* If there's a virtual offset, look up that value in the vtable and
1245 adjust the pointer again. */
1246 if (virtual_offset)
1247 {
1248 tree vtabletmp;
1249 tree vtabletmp2;
1250 tree vtabletmp3;
1251
1252 if (!vtable_entry_type)
1253 {
1254 tree vfunc_type = make_node (FUNCTION_TYPE);
1255 TREE_TYPE (vfunc_type) = integer_type_node;
1256 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
1257 layout_type (vfunc_type);
1258
1259 vtable_entry_type = build_pointer_type (vfunc_type);
1260 }
1261
1262 vtabletmp =
1263 create_tmp_var (build_pointer_type
1264 (build_pointer_type (vtable_entry_type)), "vptr");
1265
1266 /* The vptr is always at offset zero in the object. */
1267 stmt = gimple_build_assign (vtabletmp,
1268 build1 (NOP_EXPR, TREE_TYPE (vtabletmp),
1269 ptr));
1270 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1271 mark_symbols_for_renaming (stmt);
1272 find_referenced_vars_in (stmt);
1273
1274 /* Form the vtable address. */
1275 vtabletmp2 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp)),
1276 "vtableaddr");
1277 stmt = gimple_build_assign (vtabletmp2,
1278 build_simple_mem_ref (vtabletmp));
1279 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1280 mark_symbols_for_renaming (stmt);
1281 find_referenced_vars_in (stmt);
1282
1283 /* Find the entry with the vcall offset. */
1284 stmt = gimple_build_assign (vtabletmp2,
1285 fold_build_pointer_plus_loc (input_location,
1286 vtabletmp2,
1287 virtual_offset));
1288 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1289
1290 /* Get the offset itself. */
1291 vtabletmp3 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp2)),
1292 "vcalloffset");
1293 stmt = gimple_build_assign (vtabletmp3,
1294 build_simple_mem_ref (vtabletmp2));
1295 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1296 mark_symbols_for_renaming (stmt);
1297 find_referenced_vars_in (stmt);
1298
1299 /* Adjust the `this' pointer. */
1300 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3);
1301 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false,
1302 GSI_CONTINUE_LINKING);
1303 }
1304
1305 if (!this_adjusting
1306 && fixed_offset != 0)
1307 /* Adjust the pointer by the constant. */
1308 {
1309 tree ptrtmp;
1310
1311 if (TREE_CODE (ptr) == VAR_DECL)
1312 ptrtmp = ptr;
1313 else
1314 {
1315 ptrtmp = create_tmp_var (TREE_TYPE (ptr), "ptr");
1316 stmt = gimple_build_assign (ptrtmp, ptr);
1317 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1318 mark_symbols_for_renaming (stmt);
1319 find_referenced_vars_in (stmt);
1320 }
1321 ptr = fold_build_pointer_plus_hwi_loc (input_location,
1322 ptrtmp, fixed_offset);
1323 }
1324
1325 /* Emit the statement and gimplify the adjustment expression. */
1326 ret = create_tmp_var (TREE_TYPE (ptr), "adjusted_this");
1327 stmt = gimple_build_assign (ret, ptr);
1328 mark_symbols_for_renaming (stmt);
1329 find_referenced_vars_in (stmt);
1330 gsi_insert_after (bsi, stmt, GSI_NEW_STMT);
1331
1332 return ret;
1333 }
1334
1335 /* Produce assembler for thunk NODE. */
1336
1337 static void
1338 assemble_thunk (struct cgraph_node *node)
1339 {
1340 bool this_adjusting = node->thunk.this_adjusting;
1341 HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
1342 HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
1343 tree virtual_offset = NULL;
1344 tree alias = node->thunk.alias;
1345 tree thunk_fndecl = node->symbol.decl;
1346 tree a = DECL_ARGUMENTS (thunk_fndecl);
1347
1348 current_function_decl = thunk_fndecl;
1349
1350 /* Ensure thunks are emitted in their correct sections. */
1351 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
1352
1353 if (this_adjusting
1354 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
1355 virtual_value, alias))
1356 {
1357 const char *fnname;
1358 tree fn_block;
1359 tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1360
1361 DECL_RESULT (thunk_fndecl)
1362 = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
1363 RESULT_DECL, 0, restype);
1364 fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
1365
1366 /* The back end expects DECL_INITIAL to contain a BLOCK, so we
1367 create one. */
1368 fn_block = make_node (BLOCK);
1369 BLOCK_VARS (fn_block) = a;
1370 DECL_INITIAL (thunk_fndecl) = fn_block;
1371 init_function_start (thunk_fndecl);
1372 cfun->is_thunk = 1;
1373 assemble_start_function (thunk_fndecl, fnname);
1374
1375 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
1376 fixed_offset, virtual_value, alias);
1377
1378 assemble_end_function (thunk_fndecl, fnname);
1379 init_insn_lengths ();
1380 free_after_compilation (cfun);
1381 set_cfun (NULL);
1382 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1383 node->thunk.thunk_p = false;
1384 node->analyzed = false;
1385 }
1386 else
1387 {
1388 tree restype;
1389 basic_block bb, then_bb, else_bb, return_bb;
1390 gimple_stmt_iterator bsi;
1391 int nargs = 0;
1392 tree arg;
1393 int i;
1394 tree resdecl;
1395 tree restmp = NULL;
1396 VEC(tree, heap) *vargs;
1397
1398 gimple call;
1399 gimple ret;
1400
1401 DECL_IGNORED_P (thunk_fndecl) = 1;
1402 bitmap_obstack_initialize (NULL);
1403
1404 if (node->thunk.virtual_offset_p)
1405 virtual_offset = size_int (virtual_value);
1406
1407 /* Build the return declaration for the function. */
1408 restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
1409 if (DECL_RESULT (thunk_fndecl) == NULL_TREE)
1410 {
1411 resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
1412 DECL_ARTIFICIAL (resdecl) = 1;
1413 DECL_IGNORED_P (resdecl) = 1;
1414 DECL_RESULT (thunk_fndecl) = resdecl;
1415 }
1416 else
1417 resdecl = DECL_RESULT (thunk_fndecl);
1418
1419 bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
1420
1421 bsi = gsi_start_bb (bb);
1422
1423 /* Build call to the function being thunked. */
1424 if (!VOID_TYPE_P (restype))
1425 {
1426 if (!is_gimple_reg_type (restype))
1427 {
1428 restmp = resdecl;
1429 add_local_decl (cfun, restmp);
1430 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
1431 }
1432 else
1433 restmp = create_tmp_var_raw (restype, "retval");
1434 }
1435
1436 for (arg = a; arg; arg = DECL_CHAIN (arg))
1437 nargs++;
1438 vargs = VEC_alloc (tree, heap, nargs);
1439 if (this_adjusting)
1440 VEC_quick_push (tree, vargs,
1441 thunk_adjust (&bsi,
1442 a, 1, fixed_offset,
1443 virtual_offset));
1444 else
1445 VEC_quick_push (tree, vargs, a);
1446 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
1447 VEC_quick_push (tree, vargs, arg);
1448 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
1449 VEC_free (tree, heap, vargs);
1450 gimple_call_set_from_thunk (call, true);
1451 if (restmp)
1452 gimple_call_set_lhs (call, restmp);
1453 gsi_insert_after (&bsi, call, GSI_NEW_STMT);
1454 mark_symbols_for_renaming (call);
1455 find_referenced_vars_in (call);
1456 update_stmt (call);
1457
1458 if (restmp && !this_adjusting)
1459 {
1460 tree true_label = NULL_TREE;
1461
1462 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1463 {
1464 gimple stmt;
1465 /* If the return type is a pointer, we need to
1466 protect against NULL. We know there will be an
1467 adjustment, because that's why we're emitting a
1468 thunk. */
1469 then_bb = create_basic_block (NULL, (void *) 0, bb);
1470 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1471 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1472 remove_edge (single_succ_edge (bb));
1473 true_label = gimple_block_label (then_bb);
1474 stmt = gimple_build_cond (NE_EXPR, restmp,
1475 build_zero_cst (TREE_TYPE (restmp)),
1476 NULL_TREE, NULL_TREE);
1477 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1478 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
1479 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
1480 make_edge (return_bb, EXIT_BLOCK_PTR, 0);
1481 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
1482 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
1483 bsi = gsi_last_bb (then_bb);
1484 }
1485
1486 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
1487 fixed_offset, virtual_offset);
1488 if (true_label)
1489 {
1490 gimple stmt;
1491 bsi = gsi_last_bb (else_bb);
1492 stmt = gimple_build_assign (restmp,
1493 build_zero_cst (TREE_TYPE (restmp)));
1494 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1495 bsi = gsi_last_bb (return_bb);
1496 }
1497 }
1498 else
1499 gimple_call_set_tail (call, true);
1500
1501 /* Build return value. */
1502 ret = gimple_build_return (restmp);
1503 gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
1504
1505 delete_unreachable_blocks ();
1506 update_ssa (TODO_update_ssa);
1507
1508 /* Since we want to emit the thunk, we explicitly mark its name as
1509 referenced. */
1510 node->thunk.thunk_p = false;
1511 cgraph_node_remove_callees (node);
1512 cgraph_add_new_function (thunk_fndecl, true);
1513 bitmap_obstack_release (NULL);
1514 }
1515 current_function_decl = NULL;
1516 }
1517
1518
1519
1520 /* Assemble thunks and aliases asociated to NODE. */
1521
1522 static void
1523 assemble_thunks_and_aliases (struct cgraph_node *node)
1524 {
1525 struct cgraph_edge *e;
1526 int i;
1527 struct ipa_ref *ref;
1528
1529 for (e = node->callers; e;)
1530 if (e->caller->thunk.thunk_p)
1531 {
1532 struct cgraph_node *thunk = e->caller;
1533
1534 e = e->next_caller;
1535 assemble_thunks_and_aliases (thunk);
1536 assemble_thunk (thunk);
1537 }
1538 else
1539 e = e->next_caller;
1540 for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
1541 i, ref); i++)
1542 if (ref->use == IPA_REF_ALIAS)
1543 {
1544 struct cgraph_node *alias = ipa_ref_referring_node (ref);
1545 bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias);
1546
1547 /* Force assemble_alias to really output the alias this time instead
1548 of buffering it in same alias pairs. */
1549 TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
1550 assemble_alias (alias->symbol.decl,
1551 DECL_ASSEMBLER_NAME (alias->thunk.alias));
1552 assemble_thunks_and_aliases (alias);
1553 TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
1554 }
1555 }
1556
1557 /* Expand function specified by NODE. */
1558
1559 static void
1560 expand_function (struct cgraph_node *node)
1561 {
1562 tree decl = node->symbol.decl;
1563 location_t saved_loc;
1564
1565 /* We ought to not compile any inline clones. */
1566 gcc_assert (!node->global.inlined_to);
1567
1568 announce_function (decl);
1569 node->process = 0;
1570 gcc_assert (node->lowered);
1571
1572 /* Generate RTL for the body of DECL. */
1573
1574 timevar_push (TV_REST_OF_COMPILATION);
1575
1576 gcc_assert (cgraph_global_info_ready);
1577
1578 /* Initialize the default bitmap obstack. */
1579 bitmap_obstack_initialize (NULL);
1580
1581 /* Initialize the RTL code for the function. */
1582 current_function_decl = decl;
1583 saved_loc = input_location;
1584 input_location = DECL_SOURCE_LOCATION (decl);
1585 init_function_start (decl);
1586
1587 gimple_register_cfg_hooks ();
1588
1589 bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
1590
1591 execute_all_ipa_transforms ();
1592
1593 /* Perform all tree transforms and optimizations. */
1594
1595 /* Signal the start of passes. */
1596 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
1597
1598 execute_pass_list (all_passes);
1599
1600 /* Signal the end of passes. */
1601 invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
1602
1603 bitmap_obstack_release (&reg_obstack);
1604
1605 /* Release the default bitmap obstack. */
1606 bitmap_obstack_release (NULL);
1607
1608 set_cfun (NULL);
1609
1610 /* If requested, warn about function definitions where the function will
1611 return a value (usually of some struct or union type) which itself will
1612 take up a lot of stack space. */
1613 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl))
1614 {
1615 tree ret_type = TREE_TYPE (TREE_TYPE (decl));
1616
1617 if (ret_type && TYPE_SIZE_UNIT (ret_type)
1618 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
1619 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
1620 larger_than_size))
1621 {
1622 unsigned int size_as_int
1623 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
1624
1625 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
1626 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes",
1627 decl, size_as_int);
1628 else
1629 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
1630 decl, larger_than_size);
1631 }
1632 }
1633
1634 gimple_set_body (decl, NULL);
1635 if (DECL_STRUCT_FUNCTION (decl) == 0
1636 && !cgraph_get_node (decl)->origin)
1637 {
1638 /* Stop pointing to the local nodes about to be freed.
1639 But DECL_INITIAL must remain nonzero so we know this
1640 was an actual function definition.
1641 For a nested function, this is done in c_pop_function_context.
1642 If rest_of_compilation set this to 0, leave it 0. */
1643 if (DECL_INITIAL (decl) != 0)
1644 DECL_INITIAL (decl) = error_mark_node;
1645 }
1646
1647 input_location = saved_loc;
1648
1649 ggc_collect ();
1650 timevar_pop (TV_REST_OF_COMPILATION);
1651
1652 /* Make sure that BE didn't give up on compiling. */
1653 gcc_assert (TREE_ASM_WRITTEN (decl));
1654 current_function_decl = NULL;
1655
1656 /* It would make a lot more sense to output thunks before function body to get more
1657 forward and lest backwarding jumps. This however would need solving problem
1658 with comdats. See PR48668. Also aliases must come after function itself to
1659 make one pass assemblers, like one on AIX, happy. See PR 50689.
1660 FIXME: Perhaps thunks should be move before function IFF they are not in comdat
1661 groups. */
1662 assemble_thunks_and_aliases (node);
1663 cgraph_release_function_body (node);
1664 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
1665 points to the dead function body. */
1666 cgraph_node_remove_callees (node);
1667 }
1668
1669
1670 /* Expand all functions that must be output.
1671
1672 Attempt to topologically sort the nodes so function is output when
1673 all called functions are already assembled to allow data to be
1674 propagated across the callgraph. Use a stack to get smaller distance
1675 between a function and its callees (later we may choose to use a more
1676 sophisticated algorithm for function reordering; we will likely want
1677 to use subsections to make the output functions appear in top-down
1678 order). */
1679
1680 static void
1681 expand_all_functions (void)
1682 {
1683 struct cgraph_node *node;
1684 struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1685 int order_pos, new_order_pos = 0;
1686 int i;
1687
1688 order_pos = ipa_reverse_postorder (order);
1689 gcc_assert (order_pos == cgraph_n_nodes);
1690
1691 /* Garbage collector may remove inline clones we eliminate during
1692 optimization. So we must be sure to not reference them. */
1693 for (i = 0; i < order_pos; i++)
1694 if (order[i]->process)
1695 order[new_order_pos++] = order[i];
1696
1697 for (i = new_order_pos - 1; i >= 0; i--)
1698 {
1699 node = order[i];
1700 if (node->process)
1701 {
1702 node->process = 0;
1703 expand_function (node);
1704 }
1705 }
1706 cgraph_process_new_functions ();
1707
1708 free (order);
1709
1710 }
1711
1712 /* This is used to sort the node types by the cgraph order number. */
1713
1714 enum cgraph_order_sort_kind
1715 {
1716 ORDER_UNDEFINED = 0,
1717 ORDER_FUNCTION,
1718 ORDER_VAR,
1719 ORDER_ASM
1720 };
1721
1722 struct cgraph_order_sort
1723 {
1724 enum cgraph_order_sort_kind kind;
1725 union
1726 {
1727 struct cgraph_node *f;
1728 struct varpool_node *v;
1729 struct asm_node *a;
1730 } u;
1731 };
1732
1733 /* Output all functions, variables, and asm statements in the order
1734 according to their order fields, which is the order in which they
1735 appeared in the file. This implements -fno-toplevel-reorder. In
1736 this mode we may output functions and variables which don't really
1737 need to be output. */
1738
1739 static void
1740 output_in_order (void)
1741 {
1742 int max;
1743 struct cgraph_order_sort *nodes;
1744 int i;
1745 struct cgraph_node *pf;
1746 struct varpool_node *pv;
1747 struct asm_node *pa;
1748
1749 max = symtab_order;
1750 nodes = XCNEWVEC (struct cgraph_order_sort, max);
1751
1752 FOR_EACH_DEFINED_FUNCTION (pf)
1753 {
1754 if (pf->process && !pf->thunk.thunk_p && !pf->alias)
1755 {
1756 i = pf->symbol.order;
1757 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1758 nodes[i].kind = ORDER_FUNCTION;
1759 nodes[i].u.f = pf;
1760 }
1761 }
1762
1763 FOR_EACH_DEFINED_VARIABLE (pv)
1764 {
1765 i = pv->symbol.order;
1766 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1767 nodes[i].kind = ORDER_VAR;
1768 nodes[i].u.v = pv;
1769 }
1770
1771 for (pa = asm_nodes; pa; pa = pa->next)
1772 {
1773 i = pa->order;
1774 gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
1775 nodes[i].kind = ORDER_ASM;
1776 nodes[i].u.a = pa;
1777 }
1778
1779 /* In toplevel reorder mode we output all statics; mark them as needed. */
1780
1781 for (i = 0; i < max; ++i)
1782 if (nodes[i].kind == ORDER_VAR)
1783 varpool_finalize_named_section_flags (nodes[i].u.v);
1784
1785 for (i = 0; i < max; ++i)
1786 {
1787 switch (nodes[i].kind)
1788 {
1789 case ORDER_FUNCTION:
1790 nodes[i].u.f->process = 0;
1791 expand_function (nodes[i].u.f);
1792 break;
1793
1794 case ORDER_VAR:
1795 varpool_assemble_decl (nodes[i].u.v);
1796 break;
1797
1798 case ORDER_ASM:
1799 assemble_asm (nodes[i].u.a->asm_str);
1800 break;
1801
1802 case ORDER_UNDEFINED:
1803 break;
1804
1805 default:
1806 gcc_unreachable ();
1807 }
1808 }
1809
1810 asm_nodes = NULL;
1811 free (nodes);
1812 }
1813
1814 static void
1815 ipa_passes (void)
1816 {
1817 set_cfun (NULL);
1818 current_function_decl = NULL;
1819 gimple_register_cfg_hooks ();
1820 bitmap_obstack_initialize (NULL);
1821
1822 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
1823
1824 if (!in_lto_p)
1825 {
1826 execute_ipa_pass_list (all_small_ipa_passes);
1827 if (seen_error ())
1828 return;
1829 }
1830
1831 /* We never run removal of unreachable nodes after early passes. This is
1832 because TODO is run before the subpasses. It is important to remove
1833 the unreachable functions to save works at IPA level and to get LTO
1834 symbol tables right. */
1835 cgraph_remove_unreachable_nodes (true, cgraph_dump_file);
1836
1837 /* If pass_all_early_optimizations was not scheduled, the state of
1838 the cgraph will not be properly updated. Update it now. */
1839 if (cgraph_state < CGRAPH_STATE_IPA_SSA)
1840 cgraph_state = CGRAPH_STATE_IPA_SSA;
1841
1842 if (!in_lto_p)
1843 {
1844 /* Generate coverage variables and constructors. */
1845 coverage_finish ();
1846
1847 /* Process new functions added. */
1848 set_cfun (NULL);
1849 current_function_decl = NULL;
1850 cgraph_process_new_functions ();
1851
1852 execute_ipa_summary_passes
1853 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
1854 }
1855
1856 /* Some targets need to handle LTO assembler output specially. */
1857 if (flag_generate_lto)
1858 targetm.asm_out.lto_start ();
1859
1860 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
1861
1862 if (!in_lto_p)
1863 ipa_write_summaries ();
1864
1865 if (flag_generate_lto)
1866 targetm.asm_out.lto_end ();
1867
1868 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
1869 execute_ipa_pass_list (all_regular_ipa_passes);
1870 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
1871
1872 bitmap_obstack_release (NULL);
1873 }
1874
1875
1876 /* Return string alias is alias of. */
1877
1878 static tree
1879 get_alias_symbol (tree decl)
1880 {
1881 tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
1882 return get_identifier (TREE_STRING_POINTER
1883 (TREE_VALUE (TREE_VALUE (alias))));
1884 }
1885
1886
1887 /* Weakrefs may be associated to external decls and thus not output
1888 at expansion time. Emit all neccesary aliases. */
1889
1890 static void
1891 output_weakrefs (void)
1892 {
1893 struct cgraph_node *node;
1894 struct varpool_node *vnode;
1895 FOR_EACH_FUNCTION (node)
1896 if (node->alias && DECL_EXTERNAL (node->symbol.decl)
1897 && !TREE_ASM_WRITTEN (node->symbol.decl)
1898 && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
1899 assemble_alias (node->symbol.decl,
1900 node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
1901 : get_alias_symbol (node->symbol.decl));
1902 FOR_EACH_VARIABLE (vnode)
1903 if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
1904 && !TREE_ASM_WRITTEN (vnode->symbol.decl)
1905 && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
1906 assemble_alias (vnode->symbol.decl,
1907 vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
1908 : get_alias_symbol (vnode->symbol.decl));
1909 }
1910
1911 /* Initialize callgraph dump file. */
1912
1913 void
1914 init_cgraph (void)
1915 {
1916 if (!cgraph_dump_file)
1917 cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
1918 }
1919
1920 /* The edges representing the callers of the NEW_VERSION node were
1921 fixed by cgraph_function_versioning (), now the call_expr in their
1922 respective tree code should be updated to call the NEW_VERSION. */
1923
1924 static void
1925 update_call_expr (struct cgraph_node *new_version)
1926 {
1927 struct cgraph_edge *e;
1928
1929 gcc_assert (new_version);
1930
1931 /* Update the call expr on the edges to call the new version. */
1932 for (e = new_version->callers; e; e = e->next_caller)
1933 {
1934 struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->symbol.decl);
1935 gimple_call_set_fndecl (e->call_stmt, new_version->symbol.decl);
1936 maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
1937 }
1938 }
1939
1940
1941 /* Create a new cgraph node which is the new version of
1942 OLD_VERSION node. REDIRECT_CALLERS holds the callers
1943 edges which should be redirected to point to
1944 NEW_VERSION. ALL the callees edges of OLD_VERSION
1945 are cloned to the new version node. Return the new
1946 version node.
1947
1948 If non-NULL BLOCK_TO_COPY determine what basic blocks
1949 was copied to prevent duplications of calls that are dead
1950 in the clone. */
1951
1952 struct cgraph_node *
1953 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
1954 tree new_decl,
1955 VEC(cgraph_edge_p,heap) *redirect_callers,
1956 bitmap bbs_to_copy)
1957 {
1958 struct cgraph_node *new_version;
1959 struct cgraph_edge *e;
1960 unsigned i;
1961
1962 gcc_assert (old_version);
1963
1964 new_version = cgraph_create_node (new_decl);
1965
1966 new_version->analyzed = old_version->analyzed;
1967 new_version->local = old_version->local;
1968 new_version->symbol.externally_visible = false;
1969 new_version->local.local = old_version->analyzed;
1970 new_version->global = old_version->global;
1971 new_version->rtl = old_version->rtl;
1972 new_version->count = old_version->count;
1973
1974 for (e = old_version->callees; e; e=e->next_callee)
1975 if (!bbs_to_copy
1976 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
1977 cgraph_clone_edge (e, new_version, e->call_stmt,
1978 e->lto_stmt_uid, REG_BR_PROB_BASE,
1979 CGRAPH_FREQ_BASE,
1980 true);
1981 for (e = old_version->indirect_calls; e; e=e->next_callee)
1982 if (!bbs_to_copy
1983 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
1984 cgraph_clone_edge (e, new_version, e->call_stmt,
1985 e->lto_stmt_uid, REG_BR_PROB_BASE,
1986 CGRAPH_FREQ_BASE,
1987 true);
1988 FOR_EACH_VEC_ELT (cgraph_edge_p, redirect_callers, i, e)
1989 {
1990 /* Redirect calls to the old version node to point to its new
1991 version. */
1992 cgraph_redirect_edge_callee (e, new_version);
1993 }
1994
1995 cgraph_call_node_duplication_hooks (old_version, new_version);
1996
1997 return new_version;
1998 }
1999
2000 /* Perform function versioning.
2001 Function versioning includes copying of the tree and
2002 a callgraph update (creating a new cgraph node and updating
2003 its callees and callers).
2004
2005 REDIRECT_CALLERS varray includes the edges to be redirected
2006 to the new version.
2007
2008 TREE_MAP is a mapping of tree nodes we want to replace with
2009 new ones (according to results of prior analysis).
2010 OLD_VERSION_NODE is the node that is versioned.
2011
2012 If non-NULL ARGS_TO_SKIP determine function parameters to remove
2013 from new version.
2014 If SKIP_RETURN is true, the new version will return void.
2015 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
2016 If non_NULL NEW_ENTRY determine new entry BB of the clone.
2017
2018 Return the new version's cgraph node. */
2019
2020 struct cgraph_node *
2021 cgraph_function_versioning (struct cgraph_node *old_version_node,
2022 VEC(cgraph_edge_p,heap) *redirect_callers,
2023 VEC (ipa_replace_map_p,gc)* tree_map,
2024 bitmap args_to_skip,
2025 bool skip_return,
2026 bitmap bbs_to_copy,
2027 basic_block new_entry_block,
2028 const char *clone_name)
2029 {
2030 tree old_decl = old_version_node->symbol.decl;
2031 struct cgraph_node *new_version_node = NULL;
2032 tree new_decl;
2033
2034 if (!tree_versionable_function_p (old_decl))
2035 return NULL;
2036
2037 gcc_assert (old_version_node->local.can_change_signature || !args_to_skip);
2038
2039 /* Make a new FUNCTION_DECL tree node for the new version. */
2040 if (!args_to_skip && !skip_return)
2041 new_decl = copy_node (old_decl);
2042 else
2043 new_decl
2044 = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
2045
2046 /* Generate a new name for the new version. */
2047 DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
2048 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
2049 SET_DECL_RTL (new_decl, NULL);
2050
2051 /* When the old decl was a con-/destructor make sure the clone isn't. */
2052 DECL_STATIC_CONSTRUCTOR(new_decl) = 0;
2053 DECL_STATIC_DESTRUCTOR(new_decl) = 0;
2054
2055 /* Create the new version's call-graph node.
2056 and update the edges of the new node. */
2057 new_version_node =
2058 cgraph_copy_node_for_versioning (old_version_node, new_decl,
2059 redirect_callers, bbs_to_copy);
2060
2061 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2062 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip,
2063 skip_return, bbs_to_copy, new_entry_block);
2064
2065 /* Update the new version's properties.
2066 Make The new version visible only within this translation unit. Make sure
2067 that is not weak also.
2068 ??? We cannot use COMDAT linkage because there is no
2069 ABI support for this. */
2070 symtab_make_decl_local (new_version_node->symbol.decl);
2071 DECL_VIRTUAL_P (new_version_node->symbol.decl) = 0;
2072 new_version_node->symbol.externally_visible = 0;
2073 new_version_node->local.local = 1;
2074 new_version_node->lowered = true;
2075
2076 /* Update the call_expr on the edges to call the new version node. */
2077 update_call_expr (new_version_node);
2078
2079 cgraph_call_function_insertion_hooks (new_version_node);
2080 return new_version_node;
2081 }
2082
2083 /* Given virtual clone, turn it into actual clone. */
2084 static void
2085 cgraph_materialize_clone (struct cgraph_node *node)
2086 {
2087 bitmap_obstack_initialize (NULL);
2088 node->former_clone_of = node->clone_of->symbol.decl;
2089 if (node->clone_of->former_clone_of)
2090 node->former_clone_of = node->clone_of->former_clone_of;
2091 /* Copy the OLD_VERSION_NODE function tree to the new version. */
2092 tree_function_versioning (node->clone_of->symbol.decl, node->symbol.decl,
2093 node->clone.tree_map, true,
2094 node->clone.args_to_skip, false,
2095 NULL, NULL);
2096 if (cgraph_dump_file)
2097 {
2098 dump_function_to_file (node->clone_of->symbol.decl, cgraph_dump_file, dump_flags);
2099 dump_function_to_file (node->symbol.decl, cgraph_dump_file, dump_flags);
2100 }
2101
2102 /* Function is no longer clone. */
2103 if (node->next_sibling_clone)
2104 node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
2105 if (node->prev_sibling_clone)
2106 node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
2107 else
2108 node->clone_of->clones = node->next_sibling_clone;
2109 node->next_sibling_clone = NULL;
2110 node->prev_sibling_clone = NULL;
2111 if (!node->clone_of->analyzed && !node->clone_of->clones)
2112 {
2113 cgraph_release_function_body (node->clone_of);
2114 cgraph_node_remove_callees (node->clone_of);
2115 ipa_remove_all_references (&node->clone_of->symbol.ref_list);
2116 }
2117 node->clone_of = NULL;
2118 bitmap_obstack_release (NULL);
2119 }
2120
2121 /* If necessary, change the function declaration in the call statement
2122 associated with E so that it corresponds to the edge callee. */
2123
2124 gimple
2125 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
2126 {
2127 tree decl = gimple_call_fndecl (e->call_stmt);
2128 gimple new_stmt;
2129 gimple_stmt_iterator gsi;
2130 #ifdef ENABLE_CHECKING
2131 struct cgraph_node *node;
2132 #endif
2133
2134 if (e->indirect_unknown_callee
2135 || decl == e->callee->symbol.decl)
2136 return e->call_stmt;
2137
2138 #ifdef ENABLE_CHECKING
2139 if (decl)
2140 {
2141 node = cgraph_get_node (decl);
2142 gcc_assert (!node || !node->clone.combined_args_to_skip);
2143 }
2144 #endif
2145
2146 if (cgraph_dump_file)
2147 {
2148 fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ",
2149 xstrdup (cgraph_node_name (e->caller)), e->caller->uid,
2150 xstrdup (cgraph_node_name (e->callee)), e->callee->uid);
2151 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2152 if (e->callee->clone.combined_args_to_skip)
2153 {
2154 fprintf (cgraph_dump_file, " combined args to skip: ");
2155 dump_bitmap (cgraph_dump_file,
2156 e->callee->clone.combined_args_to_skip);
2157 }
2158 }
2159
2160 if (e->callee->clone.combined_args_to_skip)
2161 {
2162 int lp_nr;
2163
2164 new_stmt
2165 = gimple_call_copy_skip_args (e->call_stmt,
2166 e->callee->clone.combined_args_to_skip);
2167 gimple_call_set_fndecl (new_stmt, e->callee->symbol.decl);
2168
2169 if (gimple_vdef (new_stmt)
2170 && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
2171 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
2172
2173 gsi = gsi_for_stmt (e->call_stmt);
2174 gsi_replace (&gsi, new_stmt, false);
2175 /* We need to defer cleaning EH info on the new statement to
2176 fixup-cfg. We may not have dominator information at this point
2177 and thus would end up with unreachable blocks and have no way
2178 to communicate that we need to run CFG cleanup then. */
2179 lp_nr = lookup_stmt_eh_lp (e->call_stmt);
2180 if (lp_nr != 0)
2181 {
2182 remove_stmt_from_eh_lp (e->call_stmt);
2183 add_stmt_to_eh_lp (new_stmt, lp_nr);
2184 }
2185 }
2186 else
2187 {
2188 new_stmt = e->call_stmt;
2189 gimple_call_set_fndecl (new_stmt, e->callee->symbol.decl);
2190 update_stmt (new_stmt);
2191 }
2192
2193 cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt);
2194
2195 if (cgraph_dump_file)
2196 {
2197 fprintf (cgraph_dump_file, " updated to:");
2198 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2199 }
2200 return new_stmt;
2201 }
2202
2203 /* Once all functions from compilation unit are in memory, produce all clones
2204 and update all calls. We might also do this on demand if we don't want to
2205 bring all functions to memory prior compilation, but current WHOPR
2206 implementation does that and it is is bit easier to keep everything right in
2207 this order. */
2208 static void
2209 cgraph_materialize_all_clones (void)
2210 {
2211 struct cgraph_node *node;
2212 bool stabilized = false;
2213
2214 if (cgraph_dump_file)
2215 fprintf (cgraph_dump_file, "Materializing clones\n");
2216 #ifdef ENABLE_CHECKING
2217 verify_cgraph ();
2218 #endif
2219
2220 /* We can also do topological order, but number of iterations should be
2221 bounded by number of IPA passes since single IPA pass is probably not
2222 going to create clones of clones it created itself. */
2223 while (!stabilized)
2224 {
2225 stabilized = true;
2226 FOR_EACH_FUNCTION (node)
2227 {
2228 if (node->clone_of && node->symbol.decl != node->clone_of->symbol.decl
2229 && !gimple_has_body_p (node->symbol.decl))
2230 {
2231 if (gimple_has_body_p (node->clone_of->symbol.decl))
2232 {
2233 if (cgraph_dump_file)
2234 {
2235 fprintf (cgraph_dump_file, "cloning %s to %s\n",
2236 xstrdup (cgraph_node_name (node->clone_of)),
2237 xstrdup (cgraph_node_name (node)));
2238 if (node->clone.tree_map)
2239 {
2240 unsigned int i;
2241 fprintf (cgraph_dump_file, " replace map: ");
2242 for (i = 0; i < VEC_length (ipa_replace_map_p,
2243 node->clone.tree_map);
2244 i++)
2245 {
2246 struct ipa_replace_map *replace_info;
2247 replace_info = VEC_index (ipa_replace_map_p,
2248 node->clone.tree_map,
2249 i);
2250 print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
2251 fprintf (cgraph_dump_file, " -> ");
2252 print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
2253 fprintf (cgraph_dump_file, "%s%s;",
2254 replace_info->replace_p ? "(replace)":"",
2255 replace_info->ref_p ? "(ref)":"");
2256 }
2257 fprintf (cgraph_dump_file, "\n");
2258 }
2259 if (node->clone.args_to_skip)
2260 {
2261 fprintf (cgraph_dump_file, " args_to_skip: ");
2262 dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
2263 }
2264 if (node->clone.args_to_skip)
2265 {
2266 fprintf (cgraph_dump_file, " combined_args_to_skip:");
2267 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
2268 }
2269 }
2270 cgraph_materialize_clone (node);
2271 stabilized = false;
2272 }
2273 }
2274 }
2275 }
2276 FOR_EACH_FUNCTION (node)
2277 if (!node->analyzed && node->callees)
2278 cgraph_node_remove_callees (node);
2279 if (cgraph_dump_file)
2280 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
2281 #ifdef ENABLE_CHECKING
2282 verify_cgraph ();
2283 #endif
2284 cgraph_remove_unreachable_nodes (false, cgraph_dump_file);
2285 }
2286
2287
2288 /* Perform simple optimizations based on callgraph. */
2289
2290 void
2291 compile (void)
2292 {
2293 if (seen_error ())
2294 return;
2295
2296 #ifdef ENABLE_CHECKING
2297 verify_symtab ();
2298 #endif
2299
2300 timevar_push (TV_CGRAPHOPT);
2301 if (pre_ipa_mem_report)
2302 {
2303 fprintf (stderr, "Memory consumption before IPA\n");
2304 dump_memory_report (false);
2305 }
2306 if (!quiet_flag)
2307 fprintf (stderr, "Performing interprocedural optimizations\n");
2308 cgraph_state = CGRAPH_STATE_IPA;
2309
2310 /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
2311 if (flag_lto)
2312 lto_streamer_hooks_init ();
2313
2314 /* Don't run the IPA passes if there was any error or sorry messages. */
2315 if (!seen_error ())
2316 ipa_passes ();
2317
2318 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
2319 if (seen_error ()
2320 || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
2321 {
2322 timevar_pop (TV_CGRAPHOPT);
2323 return;
2324 }
2325
2326 /* This pass remove bodies of extern inline functions we never inlined.
2327 Do this later so other IPA passes see what is really going on. */
2328 cgraph_remove_unreachable_nodes (false, dump_file);
2329 cgraph_global_info_ready = true;
2330 if (cgraph_dump_file)
2331 {
2332 fprintf (cgraph_dump_file, "Optimized ");
2333 dump_symtab (cgraph_dump_file);
2334 }
2335 if (post_ipa_mem_report)
2336 {
2337 fprintf (stderr, "Memory consumption after IPA\n");
2338 dump_memory_report (false);
2339 }
2340 timevar_pop (TV_CGRAPHOPT);
2341
2342 /* Output everything. */
2343 (*debug_hooks->assembly_start) ();
2344 if (!quiet_flag)
2345 fprintf (stderr, "Assembling functions:\n");
2346 #ifdef ENABLE_CHECKING
2347 verify_symtab ();
2348 #endif
2349
2350 cgraph_materialize_all_clones ();
2351 bitmap_obstack_initialize (NULL);
2352 execute_ipa_pass_list (all_late_ipa_passes);
2353 cgraph_remove_unreachable_nodes (true, dump_file);
2354 #ifdef ENABLE_CHECKING
2355 verify_symtab ();
2356 #endif
2357 bitmap_obstack_release (NULL);
2358 mark_functions_to_output ();
2359 output_weakrefs ();
2360
2361 cgraph_state = CGRAPH_STATE_EXPANSION;
2362 if (!flag_toplevel_reorder)
2363 output_in_order ();
2364 else
2365 {
2366 output_asm_statements ();
2367
2368 expand_all_functions ();
2369 varpool_output_variables ();
2370 }
2371
2372 cgraph_process_new_functions ();
2373 cgraph_state = CGRAPH_STATE_FINISHED;
2374
2375 if (cgraph_dump_file)
2376 {
2377 fprintf (cgraph_dump_file, "\nFinal ");
2378 dump_symtab (cgraph_dump_file);
2379 }
2380 #ifdef ENABLE_CHECKING
2381 verify_symtab ();
2382 /* Double check that all inline clones are gone and that all
2383 function bodies have been released from memory. */
2384 if (!seen_error ())
2385 {
2386 struct cgraph_node *node;
2387 bool error_found = false;
2388
2389 FOR_EACH_DEFINED_FUNCTION (node)
2390 if (node->global.inlined_to
2391 || gimple_has_body_p (node->symbol.decl))
2392 {
2393 error_found = true;
2394 dump_cgraph_node (stderr, node);
2395 }
2396 if (error_found)
2397 internal_error ("nodes with unreleased memory found");
2398 }
2399 #endif
2400 }
2401
2402
2403 /* Analyze the whole compilation unit once it is parsed completely. */
2404
2405 void
2406 finalize_compilation_unit (void)
2407 {
2408 timevar_push (TV_CGRAPH);
2409
2410 /* If we're here there's no current function anymore. Some frontends
2411 are lazy in clearing these. */
2412 current_function_decl = NULL;
2413 set_cfun (NULL);
2414
2415 /* Do not skip analyzing the functions if there were errors, we
2416 miss diagnostics for following functions otherwise. */
2417
2418 /* Emit size functions we didn't inline. */
2419 finalize_size_functions ();
2420
2421 /* Mark alias targets necessary and emit diagnostics. */
2422 finish_aliases_1 ();
2423 handle_alias_pairs ();
2424
2425 if (!quiet_flag)
2426 {
2427 fprintf (stderr, "\nAnalyzing compilation unit\n");
2428 fflush (stderr);
2429 }
2430
2431 if (flag_dump_passes)
2432 dump_passes ();
2433
2434 /* Gimplify and lower all functions, compute reachability and
2435 remove unreachable nodes. */
2436 cgraph_analyze_functions ();
2437
2438 /* Mark alias targets necessary and emit diagnostics. */
2439 finish_aliases_1 ();
2440 handle_alias_pairs ();
2441
2442 /* Gimplify and lower thunks. */
2443 cgraph_analyze_functions ();
2444
2445 /* Finally drive the pass manager. */
2446 compile ();
2447
2448 timevar_pop (TV_CGRAPH);
2449 }
2450
2451
2452 #include "gt-cgraphunit.h"