1/* Callgraph handling code.
2 Copyright (C) 2003-2024 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21/* This file contains basic routines manipulating call graph
22
23 The call-graph is a data structure designed for inter-procedural
24 optimization. It represents a multi-graph where nodes are functions
25 (symbols within symbol table) and edges are call sites. */
26
27#include "config.h"
28#include "system.h"
29#include "coretypes.h"
30#include "backend.h"
31#include "target.h"
32#include "rtl.h"
33#include "tree.h"
34#include "gimple.h"
35#include "predict.h"
36#include "alloc-pool.h"
37#include "gimple-ssa.h"
38#include "cgraph.h"
39#include "lto-streamer.h"
40#include "fold-const.h"
41#include "varasm.h"
42#include "calls.h"
43#include "print-tree.h"
44#include "langhooks.h"
45#include "intl.h"
46#include "tree-eh.h"
47#include "gimple-iterator.h"
48#include "tree-cfg.h"
49#include "tree-ssa.h"
50#include "value-prof.h"
51#include "ipa-utils.h"
52#include "symbol-summary.h"
53#include "tree-vrp.h"
54#include "sreal.h"
55#include "ipa-cp.h"
56#include "ipa-prop.h"
57#include "ipa-fnsummary.h"
58#include "cfgloop.h"
59#include "gimple-pretty-print.h"
60#include "tree-dfa.h"
61#include "profile.h"
62#include "context.h"
63#include "gimplify.h"
64#include "stringpool.h"
65#include "attribs.h"
66#include "selftest.h"
67#include "tree-into-ssa.h"
68#include "ipa-inline.h"
69#include "tree-nested.h"
70#include "symtab-thunks.h"
71#include "symtab-clones.h"
72
73/* FIXME: Only for PROP_loops, but cgraph shouldn't have to know about this. */
74#include "tree-pass.h"
75
76/* Queue of cgraph nodes scheduled to be lowered. */
77symtab_node *x_cgraph_nodes_queue;
78#define cgraph_nodes_queue ((cgraph_node *)x_cgraph_nodes_queue)
79
80/* Symbol table global context. */
81symbol_table *symtab;
82
83/* List of hooks triggered on cgraph_edge events. */
84struct cgraph_edge_hook_list {
85 cgraph_edge_hook hook;
86 void *data;
87 struct cgraph_edge_hook_list *next;
88};
89
90/* List of hooks triggered on cgraph_node events. */
91struct cgraph_node_hook_list {
92 cgraph_node_hook hook;
93 void *data;
94 struct cgraph_node_hook_list *next;
95};
96
97/* List of hooks triggered on events involving two cgraph_edges. */
98struct cgraph_2edge_hook_list {
99 cgraph_2edge_hook hook;
100 void *data;
101 struct cgraph_2edge_hook_list *next;
102};
103
104/* List of hooks triggered on events involving two cgraph_nodes. */
105struct cgraph_2node_hook_list {
106 cgraph_2node_hook hook;
107 void *data;
108 struct cgraph_2node_hook_list *next;
109};
110
111/* Hash descriptor for cgraph_function_version_info. */
112
113struct function_version_hasher : ggc_ptr_hash<cgraph_function_version_info>
114{
115 static hashval_t hash (cgraph_function_version_info *);
116 static bool equal (cgraph_function_version_info *,
117 cgraph_function_version_info *);
118};
119
120/* Map a cgraph_node to cgraph_function_version_info using this htab.
121 The cgraph_function_version_info has a THIS_NODE field that is the
122 corresponding cgraph_node.. */
123
124static GTY(()) hash_table<function_version_hasher> *cgraph_fnver_htab = NULL;
125
126/* Hash function for cgraph_fnver_htab. */
127hashval_t
128function_version_hasher::hash (cgraph_function_version_info *ptr)
129{
130 int uid = ptr->this_node->get_uid ();
131 return (hashval_t)(uid);
132}
133
134/* eq function for cgraph_fnver_htab. */
135bool
136function_version_hasher::equal (cgraph_function_version_info *n1,
137 cgraph_function_version_info *n2)
138{
139 return n1->this_node->get_uid () == n2->this_node->get_uid ();
140}
141
142/* Mark as GC root all allocated nodes. */
143static GTY(()) struct cgraph_function_version_info *
144 version_info_node = NULL;
145
146/* Return true if NODE's address can be compared. */
147
148bool
149symtab_node::address_can_be_compared_p ()
150{
151 /* Address of virtual tables and functions is never compared. */
152 if (DECL_VIRTUAL_P (decl))
153 return false;
154 /* Address of C++ cdtors is never compared. */
155 if (is_a <cgraph_node *> (p: this)
156 && (DECL_CXX_CONSTRUCTOR_P (decl)
157 || DECL_CXX_DESTRUCTOR_P (decl)))
158 return false;
159 /* Constant pool symbols addresses are never compared.
160 flag_merge_constants permits us to assume the same on readonly vars. */
161 if (is_a <varpool_node *> (p: this)
162 && (DECL_IN_CONSTANT_POOL (decl)
163 || ((flag_merge_constants >= 2 || DECL_MERGEABLE (decl))
164 && TREE_READONLY (decl) && !TREE_THIS_VOLATILE (decl))))
165 return false;
166 return true;
167}
168
169/* Get the cgraph_function_version_info node corresponding to node. */
170cgraph_function_version_info *
171cgraph_node::function_version (void)
172{
173 cgraph_function_version_info key;
174 key.this_node = this;
175
176 if (cgraph_fnver_htab == NULL)
177 return NULL;
178
179 return cgraph_fnver_htab->find (value: &key);
180}
181
182/* Insert a new cgraph_function_version_info node into cgraph_fnver_htab
183 corresponding to cgraph_node NODE. */
184cgraph_function_version_info *
185cgraph_node::insert_new_function_version (void)
186{
187 version_info_node = NULL;
188 version_info_node = ggc_cleared_alloc<cgraph_function_version_info> ();
189 version_info_node->this_node = this;
190
191 if (cgraph_fnver_htab == NULL)
192 cgraph_fnver_htab = hash_table<function_version_hasher>::create_ggc (n: 2);
193
194 *cgraph_fnver_htab->find_slot (value: version_info_node, insert: INSERT)
195 = version_info_node;
196 return version_info_node;
197}
198
199/* Remove the cgraph_function_version_info node given by DECL_V. */
200static void
201delete_function_version (cgraph_function_version_info *decl_v)
202{
203 if (decl_v == NULL)
204 return;
205
206 if (version_info_node == decl_v)
207 version_info_node = NULL;
208
209 if (decl_v->prev != NULL)
210 decl_v->prev->next = decl_v->next;
211
212 if (decl_v->next != NULL)
213 decl_v->next->prev = decl_v->prev;
214
215 if (cgraph_fnver_htab != NULL)
216 cgraph_fnver_htab->remove_elt (value: decl_v);
217}
218
219/* Remove the cgraph_function_version_info and cgraph_node for DECL. This
220 DECL is a duplicate declaration. */
221void
222cgraph_node::delete_function_version_by_decl (tree decl)
223{
224 cgraph_node *decl_node = cgraph_node::get (decl);
225
226 if (decl_node == NULL)
227 return;
228
229 delete_function_version (decl_v: decl_node->function_version ());
230
231 decl_node->remove ();
232}
233
234/* Record that DECL1 and DECL2 are semantically identical function
235 versions. */
236void
237cgraph_node::record_function_versions (tree decl1, tree decl2)
238{
239 cgraph_node *decl1_node = cgraph_node::get_create (decl1);
240 cgraph_node *decl2_node = cgraph_node::get_create (decl2);
241 cgraph_function_version_info *decl1_v = NULL;
242 cgraph_function_version_info *decl2_v = NULL;
243 cgraph_function_version_info *before;
244 cgraph_function_version_info *after;
245
246 gcc_assert (decl1_node != NULL && decl2_node != NULL);
247 decl1_v = decl1_node->function_version ();
248 decl2_v = decl2_node->function_version ();
249
250 if (decl1_v != NULL && decl2_v != NULL)
251 return;
252
253 if (decl1_v == NULL)
254 decl1_v = decl1_node->insert_new_function_version ();
255
256 if (decl2_v == NULL)
257 decl2_v = decl2_node->insert_new_function_version ();
258
259 /* Chain decl2_v and decl1_v. All semantically identical versions
260 will be chained together. */
261
262 before = decl1_v;
263 after = decl2_v;
264
265 while (before->next != NULL)
266 before = before->next;
267
268 while (after->prev != NULL)
269 after= after->prev;
270
271 before->next = after;
272 after->prev = before;
273}
274
275/* Initialize callgraph dump file. */
276
277void
278symbol_table::initialize (void)
279{
280 if (!dump_file)
281 dump_file = dump_begin (TDI_cgraph, NULL);
282
283 if (!ipa_clones_dump_file)
284 ipa_clones_dump_file = dump_begin (TDI_clones, NULL);
285}
286
287/* Allocate new callgraph node and insert it into basic data structures. */
288
289cgraph_node *
290symbol_table::create_empty (void)
291{
292 cgraph_count++;
293 return new (ggc_alloc<cgraph_node> ()) cgraph_node (cgraph_max_uid++);
294}
295
296/* Register HOOK to be called with DATA on each removed edge. */
297cgraph_edge_hook_list *
298symbol_table::add_edge_removal_hook (cgraph_edge_hook hook, void *data)
299{
300 cgraph_edge_hook_list *entry;
301 cgraph_edge_hook_list **ptr = &m_first_edge_removal_hook;
302
303 entry = (cgraph_edge_hook_list *) xmalloc (sizeof (*entry));
304 entry->hook = hook;
305 entry->data = data;
306 entry->next = NULL;
307 while (*ptr)
308 ptr = &(*ptr)->next;
309 *ptr = entry;
310 return entry;
311}
312
313/* Remove ENTRY from the list of hooks called on removing edges. */
314void
315symbol_table::remove_edge_removal_hook (cgraph_edge_hook_list *entry)
316{
317 cgraph_edge_hook_list **ptr = &m_first_edge_removal_hook;
318
319 while (*ptr != entry)
320 ptr = &(*ptr)->next;
321 *ptr = entry->next;
322 free (ptr: entry);
323}
324
325/* Call all edge removal hooks. */
326void
327symbol_table::call_edge_removal_hooks (cgraph_edge *e)
328{
329 cgraph_edge_hook_list *entry = m_first_edge_removal_hook;
330 while (entry)
331 {
332 entry->hook (e, entry->data);
333 entry = entry->next;
334 }
335}
336
337/* Register HOOK to be called with DATA on each removed node. */
338cgraph_node_hook_list *
339symbol_table::add_cgraph_removal_hook (cgraph_node_hook hook, void *data)
340{
341 cgraph_node_hook_list *entry;
342 cgraph_node_hook_list **ptr = &m_first_cgraph_removal_hook;
343
344 entry = (cgraph_node_hook_list *) xmalloc (sizeof (*entry));
345 entry->hook = hook;
346 entry->data = data;
347 entry->next = NULL;
348 while (*ptr)
349 ptr = &(*ptr)->next;
350 *ptr = entry;
351 return entry;
352}
353
354/* Remove ENTRY from the list of hooks called on removing nodes. */
355void
356symbol_table::remove_cgraph_removal_hook (cgraph_node_hook_list *entry)
357{
358 cgraph_node_hook_list **ptr = &m_first_cgraph_removal_hook;
359
360 while (*ptr != entry)
361 ptr = &(*ptr)->next;
362 *ptr = entry->next;
363 free (ptr: entry);
364}
365
366/* Call all node removal hooks. */
367void
368symbol_table::call_cgraph_removal_hooks (cgraph_node *node)
369{
370 cgraph_node_hook_list *entry = m_first_cgraph_removal_hook;
371 while (entry)
372 {
373 entry->hook (node, entry->data);
374 entry = entry->next;
375 }
376}
377
378/* Call all node removal hooks. */
379void
380symbol_table::call_cgraph_insertion_hooks (cgraph_node *node)
381{
382 cgraph_node_hook_list *entry = m_first_cgraph_insertion_hook;
383 while (entry)
384 {
385 entry->hook (node, entry->data);
386 entry = entry->next;
387 }
388}
389
390
391/* Register HOOK to be called with DATA on each inserted node. */
392cgraph_node_hook_list *
393symbol_table::add_cgraph_insertion_hook (cgraph_node_hook hook, void *data)
394{
395 cgraph_node_hook_list *entry;
396 cgraph_node_hook_list **ptr = &m_first_cgraph_insertion_hook;
397
398 entry = (cgraph_node_hook_list *) xmalloc (sizeof (*entry));
399 entry->hook = hook;
400 entry->data = data;
401 entry->next = NULL;
402 while (*ptr)
403 ptr = &(*ptr)->next;
404 *ptr = entry;
405 return entry;
406}
407
408/* Remove ENTRY from the list of hooks called on inserted nodes. */
409void
410symbol_table::remove_cgraph_insertion_hook (cgraph_node_hook_list *entry)
411{
412 cgraph_node_hook_list **ptr = &m_first_cgraph_insertion_hook;
413
414 while (*ptr != entry)
415 ptr = &(*ptr)->next;
416 *ptr = entry->next;
417 free (ptr: entry);
418}
419
420/* Register HOOK to be called with DATA on each duplicated edge. */
421cgraph_2edge_hook_list *
422symbol_table::add_edge_duplication_hook (cgraph_2edge_hook hook, void *data)
423{
424 cgraph_2edge_hook_list *entry;
425 cgraph_2edge_hook_list **ptr = &m_first_edge_duplicated_hook;
426
427 entry = (cgraph_2edge_hook_list *) xmalloc (sizeof (*entry));
428 entry->hook = hook;
429 entry->data = data;
430 entry->next = NULL;
431 while (*ptr)
432 ptr = &(*ptr)->next;
433 *ptr = entry;
434 return entry;
435}
436
437/* Remove ENTRY from the list of hooks called on duplicating edges. */
438void
439symbol_table::remove_edge_duplication_hook (cgraph_2edge_hook_list *entry)
440{
441 cgraph_2edge_hook_list **ptr = &m_first_edge_duplicated_hook;
442
443 while (*ptr != entry)
444 ptr = &(*ptr)->next;
445 *ptr = entry->next;
446 free (ptr: entry);
447}
448
449/* Call all edge duplication hooks. */
450void
451symbol_table::call_edge_duplication_hooks (cgraph_edge *cs1, cgraph_edge *cs2)
452{
453 cgraph_2edge_hook_list *entry = m_first_edge_duplicated_hook;
454 while (entry)
455 {
456 entry->hook (cs1, cs2, entry->data);
457 entry = entry->next;
458 }
459}
460
461/* Register HOOK to be called with DATA on each duplicated node. */
462cgraph_2node_hook_list *
463symbol_table::add_cgraph_duplication_hook (cgraph_2node_hook hook, void *data)
464{
465 cgraph_2node_hook_list *entry;
466 cgraph_2node_hook_list **ptr = &m_first_cgraph_duplicated_hook;
467
468 entry = (cgraph_2node_hook_list *) xmalloc (sizeof (*entry));
469 entry->hook = hook;
470 entry->data = data;
471 entry->next = NULL;
472 while (*ptr)
473 ptr = &(*ptr)->next;
474 *ptr = entry;
475 return entry;
476}
477
478/* Remove ENTRY from the list of hooks called on duplicating nodes. */
479void
480symbol_table::remove_cgraph_duplication_hook (cgraph_2node_hook_list *entry)
481{
482 cgraph_2node_hook_list **ptr = &m_first_cgraph_duplicated_hook;
483
484 while (*ptr != entry)
485 ptr = &(*ptr)->next;
486 *ptr = entry->next;
487 free (ptr: entry);
488}
489
490/* Call all node duplication hooks. */
491void
492symbol_table::call_cgraph_duplication_hooks (cgraph_node *node,
493 cgraph_node *node2)
494{
495 cgraph_2node_hook_list *entry = m_first_cgraph_duplicated_hook;
496 while (entry)
497 {
498 entry->hook (node, node2, entry->data);
499 entry = entry->next;
500 }
501}
502
503/* Return cgraph node assigned to DECL. Create new one when needed. */
504
505cgraph_node *
506cgraph_node::create (tree decl)
507{
508 cgraph_node *node = symtab->create_empty ();
509 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
510
511 node->decl = decl;
512 node->semantic_interposition = opt_for_fn (decl, flag_semantic_interposition);
513
514 if ((flag_openacc || flag_openmp)
515 && lookup_attribute (attr_name: "omp declare target", DECL_ATTRIBUTES (decl)))
516 {
517 node->offloadable = 1;
518 if (ENABLE_OFFLOADING)
519 g->have_offload = true;
520 }
521
522 if (lookup_attribute (attr_name: "ifunc", DECL_ATTRIBUTES (decl)))
523 node->ifunc_resolver = true;
524
525 node->register_symbol ();
526 maybe_record_nested_function (node);
527
528 return node;
529}
530
531/* Try to find a call graph node for declaration DECL and if it does not exist
532 or if it corresponds to an inline clone, create a new one. */
533
534cgraph_node *
535cgraph_node::get_create (tree decl)
536{
537 cgraph_node *first_clone = cgraph_node::get (decl);
538
539 if (first_clone && !first_clone->inlined_to)
540 return first_clone;
541
542 cgraph_node *node = cgraph_node::create (decl);
543 if (first_clone)
544 {
545 first_clone->clone_of = node;
546 node->clones = first_clone;
547 node->order = first_clone->order;
548 symtab->symtab_prevail_in_asm_name_hash (node);
549 node->decl->decl_with_vis.symtab_node = node;
550 if (dump_file && symtab->state != PARSING)
551 fprintf (stream: dump_file, format: "Introduced new external node "
552 "(%s) and turned into root of the clone tree.\n",
553 node->dump_name ());
554 }
555 else if (dump_file && symtab->state != PARSING)
556 fprintf (stream: dump_file, format: "Introduced new external node "
557 "(%s).\n", node->dump_name ());
558 return node;
559}
560
561/* Mark ALIAS as an alias to DECL. DECL_NODE is cgraph node representing
562 the function body is associated with
563 (not necessarily cgraph_node (DECL)). */
564
565cgraph_node *
566cgraph_node::create_alias (tree alias, tree target)
567{
568 cgraph_node *alias_node;
569
570 gcc_assert (TREE_CODE (target) == FUNCTION_DECL
571 || TREE_CODE (target) == IDENTIFIER_NODE);
572 gcc_assert (TREE_CODE (alias) == FUNCTION_DECL);
573 alias_node = cgraph_node::get_create (decl: alias);
574 gcc_assert (!alias_node->definition);
575 alias_node->alias_target = target;
576 alias_node->definition = true;
577 alias_node->alias = true;
578 if (lookup_attribute (attr_name: "weakref", DECL_ATTRIBUTES (alias)) != NULL)
579 alias_node->transparent_alias = alias_node->weakref = true;
580 if (lookup_attribute (attr_name: "ifunc", DECL_ATTRIBUTES (alias)))
581 alias_node->ifunc_resolver = true;
582 return alias_node;
583}
584
585/* Attempt to mark ALIAS as an alias to DECL. Return alias node if successful
586 and NULL otherwise.
587 Same body aliases are output whenever the body of DECL is output,
588 and cgraph_node::get (ALIAS) transparently returns
589 cgraph_node::get (DECL). */
590
591cgraph_node *
592cgraph_node::create_same_body_alias (tree alias, tree decl)
593{
594 cgraph_node *n;
595
596 /* If aliases aren't supported by the assembler, fail. */
597 if (!TARGET_SUPPORTS_ALIASES)
598 return NULL;
599
600 /* Langhooks can create same body aliases of symbols not defined.
601 Those are useless. Drop them on the floor. */
602 if (symtab->global_info_ready)
603 return NULL;
604
605 n = cgraph_node::create_alias (alias, target: decl);
606 n->cpp_implicit_alias = true;
607 if (symtab->cpp_implicit_aliases_done)
608 n->resolve_alias (target: cgraph_node::get (decl));
609 return n;
610}
611
612/* Add thunk alias into callgraph. The alias declaration is ALIAS and it
613 aliases DECL with an adjustments made into the first parameter.
614 See comments in struct cgraph_thunk_info for detail on the parameters. */
615
616cgraph_node *
617cgraph_node::create_thunk (tree alias, tree, bool this_adjusting,
618 HOST_WIDE_INT fixed_offset,
619 HOST_WIDE_INT virtual_value,
620 HOST_WIDE_INT indirect_offset,
621 tree virtual_offset,
622 tree real_alias)
623{
624 cgraph_node *node;
625
626 node = cgraph_node::get (decl: alias);
627 if (node)
628 node->reset ();
629 else
630 node = cgraph_node::create (decl: alias);
631
632 /* Make sure that if VIRTUAL_OFFSET is in sync with VIRTUAL_VALUE. */
633 gcc_checking_assert (virtual_offset
634 ? virtual_value == wi::to_wide (virtual_offset)
635 : virtual_value == 0);
636
637 node->thunk = true;
638 node->definition = true;
639
640 thunk_info *i;
641 thunk_info local_info;
642 if (symtab->state < CONSTRUCTION)
643 i = &local_info;
644 else
645 i = thunk_info::get_create (node);
646 i->fixed_offset = fixed_offset;
647 i->virtual_value = virtual_value;
648 i->indirect_offset = indirect_offset;
649 i->alias = real_alias;
650 i->this_adjusting = this_adjusting;
651 i->virtual_offset_p = virtual_offset != NULL;
652 if (symtab->state < CONSTRUCTION)
653 i->register_early (node);
654
655 return node;
656}
657
658/* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
659 Return NULL if there's no such node. */
660
661cgraph_node *
662cgraph_node::get_for_asmname (tree asmname)
663{
664 /* We do not want to look at inline clones. */
665 for (symtab_node *node = symtab_node::get_for_asmname (asmname);
666 node;
667 node = node->next_sharing_asm_name)
668 {
669 cgraph_node *cn = dyn_cast <cgraph_node *> (p: node);
670 if (cn && !cn->inlined_to)
671 return cn;
672 }
673 return NULL;
674}
675
676/* Returns a hash value for X (which really is a cgraph_edge). */
677
678hashval_t
679cgraph_edge_hasher::hash (cgraph_edge *e)
680{
681 /* This is a really poor hash function, but it is what htab_hash_pointer
682 uses. */
683 return (hashval_t) ((intptr_t)e->call_stmt >> 3);
684}
685
686/* Returns a hash value for X (which really is a cgraph_edge). */
687
688hashval_t
689cgraph_edge_hasher::hash (gimple *call_stmt)
690{
691 /* This is a really poor hash function, but it is what htab_hash_pointer
692 uses. */
693 return (hashval_t) ((intptr_t)call_stmt >> 3);
694}
695
696/* Return nonzero if the call_stmt of cgraph_edge X is stmt *Y. */
697
698inline bool
699cgraph_edge_hasher::equal (cgraph_edge *x, gimple *y)
700{
701 return x->call_stmt == y;
702}
703
704/* Add call graph edge E to call site hash of its caller. */
705
706static inline void
707cgraph_update_edge_in_call_site_hash (cgraph_edge *e)
708{
709 gimple *call = e->call_stmt;
710 *e->caller->call_site_hash->find_slot_with_hash
711 (comparable: call, hash: cgraph_edge_hasher::hash (call_stmt: call), insert: INSERT) = e;
712}
713
714/* Add call graph edge E to call site hash of its caller. */
715
716static inline void
717cgraph_add_edge_to_call_site_hash (cgraph_edge *e)
718{
719 /* There are two speculative edges for every statement (one direct,
720 one indirect); always hash the direct one. */
721 if (e->speculative && e->indirect_unknown_callee)
722 return;
723 cgraph_edge **slot = e->caller->call_site_hash->find_slot_with_hash
724 (comparable: e->call_stmt, hash: cgraph_edge_hasher::hash (call_stmt: e->call_stmt), insert: INSERT);
725 if (*slot)
726 {
727 gcc_assert (((cgraph_edge *)*slot)->speculative);
728 if (e->callee && (!e->prev_callee
729 || !e->prev_callee->speculative
730 || e->prev_callee->call_stmt != e->call_stmt))
731 *slot = e;
732 return;
733 }
734 gcc_assert (!*slot || e->speculative);
735 *slot = e;
736}
737
738/* Return the callgraph edge representing the GIMPLE_CALL statement
739 CALL_STMT. */
740
741cgraph_edge *
742cgraph_node::get_edge (gimple *call_stmt)
743{
744 cgraph_edge *e, *e2;
745 int n = 0;
746
747 if (call_site_hash)
748 return call_site_hash->find_with_hash
749 (comparable: call_stmt, hash: cgraph_edge_hasher::hash (call_stmt));
750
751 /* This loop may turn out to be performance problem. In such case adding
752 hashtables into call nodes with very many edges is probably best
753 solution. It is not good idea to add pointer into CALL_EXPR itself
754 because we want to make possible having multiple cgraph nodes representing
755 different clones of the same body before the body is actually cloned. */
756 for (e = callees; e; e = e->next_callee)
757 {
758 if (e->call_stmt == call_stmt)
759 break;
760 n++;
761 }
762
763 if (!e)
764 for (e = indirect_calls; e; e = e->next_callee)
765 {
766 if (e->call_stmt == call_stmt)
767 break;
768 n++;
769 }
770
771 if (n > 100)
772 {
773 call_site_hash = hash_table<cgraph_edge_hasher>::create_ggc (n: 120);
774 for (e2 = callees; e2; e2 = e2->next_callee)
775 cgraph_add_edge_to_call_site_hash (e: e2);
776 for (e2 = indirect_calls; e2; e2 = e2->next_callee)
777 cgraph_add_edge_to_call_site_hash (e: e2);
778 }
779
780 return e;
781}
782
783
784/* Change field call_stmt of edge E to NEW_STMT. If UPDATE_SPECULATIVE and E
785 is any component of speculative edge, then update all components.
786 Speculations can be resolved in the process and EDGE can be removed and
787 deallocated. Return the edge that now represents the call. */
788
789cgraph_edge *
790cgraph_edge::set_call_stmt (cgraph_edge *e, gcall *new_stmt,
791 bool update_speculative)
792{
793 tree decl;
794
795 cgraph_node *new_direct_callee = NULL;
796 if ((e->indirect_unknown_callee || e->speculative)
797 && (decl = gimple_call_fndecl (gs: new_stmt)))
798 {
799 /* Constant propagation and especially inlining can turn an indirect call
800 into a direct one. */
801 new_direct_callee = cgraph_node::get (decl);
802 gcc_checking_assert (new_direct_callee);
803 }
804
805 /* Speculative edges has three component, update all of them
806 when asked to. */
807 if (update_speculative && e->speculative
808 /* If we are about to resolve the speculation by calling make_direct
809 below, do not bother going over all the speculative edges now. */
810 && !new_direct_callee)
811 {
812 cgraph_edge *direct, *indirect, *next;
813 ipa_ref *ref;
814 bool e_indirect = e->indirect_unknown_callee;
815 int n = 0;
816
817 direct = e->first_speculative_call_target ();
818 indirect = e->speculative_call_indirect_edge ();
819
820 gcall *old_stmt = direct->call_stmt;
821 for (cgraph_edge *d = direct; d; d = next)
822 {
823 next = d->next_speculative_call_target ();
824 cgraph_edge *d2 = set_call_stmt (e: d, new_stmt, update_speculative: false);
825 gcc_assert (d2 == d);
826 n++;
827 }
828 gcc_checking_assert (indirect->num_speculative_call_targets_p () == n);
829 for (unsigned int i = 0; e->caller->iterate_reference (i, ref); i++)
830 if (ref->speculative && ref->stmt == old_stmt)
831 {
832 ref->stmt = new_stmt;
833 n--;
834 }
835
836 indirect = set_call_stmt (e: indirect, new_stmt, update_speculative: false);
837 return e_indirect ? indirect : direct;
838 }
839
840 if (new_direct_callee)
841 e = make_direct (edge: e, callee: new_direct_callee);
842
843 /* Only direct speculative edges go to call_site_hash. */
844 if (e->caller->call_site_hash
845 && (!e->speculative || !e->indirect_unknown_callee)
846 /* It is possible that edge was previously speculative. In this case
847 we have different value in call stmt hash which needs preserving. */
848 && e->caller->get_edge (call_stmt: e->call_stmt) == e)
849 e->caller->call_site_hash->remove_elt_with_hash
850 (comparable: e->call_stmt, hash: cgraph_edge_hasher::hash (call_stmt: e->call_stmt));
851
852 e->call_stmt = new_stmt;
853
854 function *fun = DECL_STRUCT_FUNCTION (e->caller->decl);
855 e->can_throw_external = stmt_can_throw_external (fun, new_stmt);
856 /* Update call stite hash. For speculative calls we only record the first
857 direct edge. */
858 if (e->caller->call_site_hash
859 && (!e->speculative
860 || (e->callee
861 && (!e->prev_callee || !e->prev_callee->speculative
862 || e->prev_callee->call_stmt != e->call_stmt))
863 || (e->speculative && !e->callee)))
864 cgraph_add_edge_to_call_site_hash (e);
865 return e;
866}
867
868/* Allocate a cgraph_edge structure and fill it with data according to the
869 parameters of which only CALLEE can be NULL (when creating an indirect call
870 edge). CLONING_P should be set if properties that are copied from an
871 original edge should not be calculated. */
872
873cgraph_edge *
874symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
875 gcall *call_stmt, profile_count count,
876 bool indir_unknown_callee, bool cloning_p)
877{
878 cgraph_edge *edge;
879
880 /* LTO does not actually have access to the call_stmt since these
881 have not been loaded yet. */
882 if (call_stmt)
883 {
884 /* This is a rather expensive check possibly triggering
885 construction of call stmt hashtable. */
886 cgraph_edge *e;
887 gcc_checking_assert (!(e = caller->get_edge (call_stmt))
888 || e->speculative);
889
890 gcc_assert (is_gimple_call (call_stmt));
891 }
892
893 edge = ggc_alloc<cgraph_edge> ();
894 edge->m_summary_id = -1;
895 edges_count++;
896
897 gcc_assert (++edges_max_uid != 0);
898 edge->m_uid = edges_max_uid;
899 edge->aux = NULL;
900 edge->caller = caller;
901 edge->callee = callee;
902 edge->prev_caller = NULL;
903 edge->next_caller = NULL;
904 edge->prev_callee = NULL;
905 edge->next_callee = NULL;
906 edge->lto_stmt_uid = 0;
907 edge->speculative_id = 0;
908
909 edge->count = count;
910 edge->call_stmt = call_stmt;
911 edge->indirect_info = NULL;
912 edge->indirect_inlining_edge = 0;
913 edge->speculative = false;
914 edge->indirect_unknown_callee = indir_unknown_callee;
915 if (call_stmt && caller->call_site_hash)
916 cgraph_add_edge_to_call_site_hash (e: edge);
917
918 if (cloning_p)
919 return edge;
920
921 edge->can_throw_external
922 = call_stmt ? stmt_can_throw_external (DECL_STRUCT_FUNCTION (caller->decl),
923 call_stmt) : false;
924 edge->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
925 edge->call_stmt_cannot_inline_p = false;
926
927 if (opt_for_fn (edge->caller->decl, flag_devirtualize)
928 && call_stmt && DECL_STRUCT_FUNCTION (caller->decl))
929 edge->in_polymorphic_cdtor
930 = decl_maybe_in_construction_p (NULL, NULL, call_stmt,
931 caller->decl);
932 else
933 edge->in_polymorphic_cdtor = caller->thunk;
934 if (callee)
935 caller->calls_declare_variant_alt |= callee->declare_variant_alt;
936
937 if (callee && symtab->state != LTO_STREAMING
938 && edge->callee->comdat_local_p ())
939 edge->caller->calls_comdat_local = true;
940
941 return edge;
942}
943
944/* Create edge from a given function to CALLEE in the cgraph. CLONING_P should
945 be set if properties that are copied from an original edge should not be
946 calculated. */
947
948cgraph_edge *
949cgraph_node::create_edge (cgraph_node *callee,
950 gcall *call_stmt, profile_count count, bool cloning_p)
951{
952 cgraph_edge *edge = symtab->create_edge (caller: this, callee, call_stmt, count,
953 indir_unknown_callee: false, cloning_p);
954
955 if (!cloning_p)
956 initialize_inline_failed (edge);
957
958 edge->next_caller = callee->callers;
959 if (callee->callers)
960 callee->callers->prev_caller = edge;
961 edge->next_callee = callees;
962 if (callees)
963 callees->prev_callee = edge;
964 callees = edge;
965 callee->callers = edge;
966
967 return edge;
968}
969
970/* Allocate cgraph_indirect_call_info and set its fields to default values. */
971
972cgraph_indirect_call_info *
973cgraph_allocate_init_indirect_info (void)
974{
975 cgraph_indirect_call_info *ii;
976
977 ii = ggc_cleared_alloc<cgraph_indirect_call_info> ();
978 ii->param_index = -1;
979 return ii;
980}
981
982/* Create an indirect edge with a yet-undetermined callee where the call
983 statement destination is a formal parameter of the caller with index
984 PARAM_INDEX. CLONING_P should be set if properties that are copied from an
985 original edge should not be calculated and indirect_info structure should
986 not be calculated. */
987
988cgraph_edge *
989cgraph_node::create_indirect_edge (gcall *call_stmt, int ecf_flags,
990 profile_count count,
991 bool cloning_p)
992{
993 cgraph_edge *edge = symtab->create_edge (caller: this, NULL, call_stmt, count, indir_unknown_callee: true,
994 cloning_p);
995 tree target;
996
997 if (!cloning_p)
998 initialize_inline_failed (edge);
999
1000 edge->indirect_info = cgraph_allocate_init_indirect_info ();
1001 edge->indirect_info->ecf_flags = ecf_flags;
1002 edge->indirect_info->vptr_changed = true;
1003
1004 /* Record polymorphic call info. */
1005 if (!cloning_p
1006 && call_stmt
1007 && (target = gimple_call_fn (gs: call_stmt))
1008 && virtual_method_call_p (target))
1009 {
1010 ipa_polymorphic_call_context context (decl, target, call_stmt);
1011
1012 /* Only record types can have virtual calls. */
1013 edge->indirect_info->polymorphic = true;
1014 edge->indirect_info->param_index = -1;
1015 edge->indirect_info->otr_token
1016 = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
1017 edge->indirect_info->otr_type = obj_type_ref_class (ref: target);
1018 gcc_assert (TREE_CODE (edge->indirect_info->otr_type) == RECORD_TYPE);
1019 edge->indirect_info->context = context;
1020 }
1021
1022 edge->next_callee = indirect_calls;
1023 if (indirect_calls)
1024 indirect_calls->prev_callee = edge;
1025 indirect_calls = edge;
1026
1027 return edge;
1028}
1029
1030/* Remove the edge from the list of the callees of the caller. */
1031
1032void
1033cgraph_edge::remove_caller (void)
1034{
1035 if (prev_callee)
1036 prev_callee->next_callee = next_callee;
1037 if (next_callee)
1038 next_callee->prev_callee = prev_callee;
1039 if (!prev_callee)
1040 {
1041 if (indirect_unknown_callee)
1042 caller->indirect_calls = next_callee;
1043 else
1044 caller->callees = next_callee;
1045 }
1046 if (caller->call_site_hash
1047 && this == caller->get_edge (call_stmt))
1048 caller->call_site_hash->remove_elt_with_hash
1049 (comparable: call_stmt, hash: cgraph_edge_hasher::hash (call_stmt));
1050}
1051
1052/* Put the edge onto the free list. */
1053
1054void
1055symbol_table::free_edge (cgraph_edge *e)
1056{
1057 edges_count--;
1058 if (e->m_summary_id != -1)
1059 edge_released_summary_ids.safe_push (obj: e->m_summary_id);
1060
1061 if (e->indirect_info)
1062 ggc_free (e->indirect_info);
1063 ggc_free (e);
1064}
1065
1066/* Remove the edge in the cgraph. */
1067
1068void
1069cgraph_edge::remove (cgraph_edge *edge)
1070{
1071 /* Call all edge removal hooks. */
1072 symtab->call_edge_removal_hooks (e: edge);
1073
1074 if (!edge->indirect_unknown_callee)
1075 /* Remove from callers list of the callee. */
1076 edge->remove_callee ();
1077
1078 /* Remove from callees list of the callers. */
1079 edge->remove_caller ();
1080
1081 /* Put the edge onto the free list. */
1082 symtab->free_edge (e: edge);
1083}
1084
1085/* Turn edge into speculative call calling N2. Update
1086 the profile so the direct call is taken COUNT times
1087 with FREQUENCY.
1088
1089 At clone materialization time, the indirect call E will
1090 be expanded as:
1091
1092 if (call_dest == N2)
1093 n2 ();
1094 else
1095 call call_dest
1096
1097 At this time the function just creates the direct call,
1098 the reference representing the if conditional and attaches
1099 them all to the original indirect call statement.
1100
1101 speculative_id is used to link direct calls with their corresponding
1102 IPA_REF_ADDR references when representing speculative calls.
1103
1104 Return direct edge created. */
1105
1106cgraph_edge *
1107cgraph_edge::make_speculative (cgraph_node *n2, profile_count direct_count,
1108 unsigned int speculative_id)
1109{
1110 cgraph_node *n = caller;
1111 ipa_ref *ref = NULL;
1112 cgraph_edge *e2;
1113
1114 if (dump_file)
1115 fprintf (stream: dump_file, format: "Indirect call -> speculative call %s => %s\n",
1116 n->dump_name (), n2->dump_name ());
1117 speculative = true;
1118 e2 = n->create_edge (callee: n2, call_stmt, count: direct_count);
1119 initialize_inline_failed (e2);
1120 e2->speculative = true;
1121 if (TREE_NOTHROW (n2->decl))
1122 e2->can_throw_external = false;
1123 else
1124 e2->can_throw_external = can_throw_external;
1125 e2->lto_stmt_uid = lto_stmt_uid;
1126 e2->speculative_id = speculative_id;
1127 e2->in_polymorphic_cdtor = in_polymorphic_cdtor;
1128 indirect_info->num_speculative_call_targets++;
1129 count -= e2->count;
1130 symtab->call_edge_duplication_hooks (cs1: this, cs2: e2);
1131 ref = n->create_reference (referred_node: n2, use_type: IPA_REF_ADDR, stmt: call_stmt);
1132 ref->lto_stmt_uid = lto_stmt_uid;
1133 ref->speculative_id = speculative_id;
1134 ref->speculative = speculative;
1135 n2->mark_address_taken ();
1136 return e2;
1137}
1138
1139/* Speculative call consists of an indirect edge and one or more
1140 direct edge+ref pairs.
1141
1142 Given an edge which is part of speculative call, return the first
1143 direct call edge in the speculative call sequence. */
1144
1145cgraph_edge *
1146cgraph_edge::first_speculative_call_target ()
1147{
1148 cgraph_edge *e = this;
1149
1150 gcc_checking_assert (e->speculative);
1151 if (e->callee)
1152 {
1153 while (e->prev_callee && e->prev_callee->speculative
1154 && e->prev_callee->call_stmt == e->call_stmt
1155 && e->prev_callee->lto_stmt_uid == e->lto_stmt_uid)
1156 e = e->prev_callee;
1157 return e;
1158 }
1159 /* Call stmt site hash always points to the first target of the
1160 speculative call sequence. */
1161 if (e->call_stmt)
1162 return e->caller->get_edge (call_stmt: e->call_stmt);
1163 for (cgraph_edge *e2 = e->caller->callees; true; e2 = e2->next_callee)
1164 if (e2->speculative
1165 && e->call_stmt == e2->call_stmt
1166 && e->lto_stmt_uid == e2->lto_stmt_uid)
1167 return e2;
1168}
1169
1170/* We always maintain first direct edge in the call site hash, if one
1171 exists. E is going to be removed. See if it is first one and update
1172 hash accordingly. INDIRECT is the indirect edge of speculative call.
1173 We assume that INDIRECT->num_speculative_call_targets_p () is already
1174 updated for removal of E. */
1175static void
1176update_call_stmt_hash_for_removing_direct_edge (cgraph_edge *e,
1177 cgraph_edge *indirect)
1178{
1179 if (e->caller->call_site_hash)
1180 {
1181 if (e->caller->get_edge (call_stmt: e->call_stmt) != e)
1182 ;
1183 else if (!indirect->num_speculative_call_targets_p ())
1184 cgraph_update_edge_in_call_site_hash (e: indirect);
1185 else
1186 {
1187 gcc_checking_assert (e->next_callee && e->next_callee->speculative
1188 && e->next_callee->call_stmt == e->call_stmt);
1189 cgraph_update_edge_in_call_site_hash (e: e->next_callee);
1190 }
1191 }
1192}
1193
1194/* Speculative call EDGE turned out to be direct call to CALLEE_DECL. Remove
1195 the speculative call sequence and return edge representing the call, the
1196 original EDGE can be removed and deallocated. Return the edge that now
1197 represents the call.
1198
1199 For "speculative" indirect call that contains multiple "speculative"
1200 targets (i.e. edge->indirect_info->num_speculative_call_targets > 1),
1201 decrease the count and only remove current direct edge.
1202
1203 If no speculative direct call left to the speculative indirect call, remove
1204 the speculative of both the indirect call and corresponding direct edge.
1205
1206 It is up to caller to iteratively resolve each "speculative" direct call and
1207 redirect the call as appropriate. */
1208
1209cgraph_edge *
1210cgraph_edge::resolve_speculation (cgraph_edge *edge, tree callee_decl)
1211{
1212 cgraph_edge *e2;
1213 ipa_ref *ref;
1214
1215 gcc_assert (edge->speculative && (!callee_decl || edge->callee));
1216 if (!edge->callee)
1217 e2 = edge->first_speculative_call_target ();
1218 else
1219 e2 = edge;
1220 ref = e2->speculative_call_target_ref ();
1221 edge = edge->speculative_call_indirect_edge ();
1222 if (!callee_decl
1223 || !ref->referred->semantically_equivalent_p
1224 (target: symtab_node::get (decl: callee_decl)))
1225 {
1226 if (dump_file)
1227 {
1228 if (callee_decl)
1229 {
1230 fprintf (stream: dump_file, format: "Speculative indirect call %s => %s has "
1231 "turned out to have contradicting known target ",
1232 edge->caller->dump_name (),
1233 e2->callee->dump_name ());
1234 print_generic_expr (dump_file, callee_decl);
1235 fprintf (stream: dump_file, format: "\n");
1236 }
1237 else
1238 {
1239 fprintf (stream: dump_file, format: "Removing speculative call %s => %s\n",
1240 edge->caller->dump_name (),
1241 e2->callee->dump_name ());
1242 }
1243 }
1244 }
1245 else
1246 {
1247 cgraph_edge *tmp = edge;
1248 if (dump_file)
1249 fprintf (stream: dump_file, format: "Speculative call turned into direct call.\n");
1250 edge = e2;
1251 e2 = tmp;
1252 /* FIXME: If EDGE is inlined, we should scale up the frequencies
1253 and counts in the functions inlined through it. */
1254 }
1255 edge->count += e2->count;
1256 if (edge->num_speculative_call_targets_p ())
1257 {
1258 /* The indirect edge has multiple speculative targets, don't remove
1259 speculative until all related direct edges are resolved. */
1260 edge->indirect_info->num_speculative_call_targets--;
1261 if (!edge->indirect_info->num_speculative_call_targets)
1262 edge->speculative = false;
1263 }
1264 else
1265 edge->speculative = false;
1266 e2->speculative = false;
1267 update_call_stmt_hash_for_removing_direct_edge (e: e2, indirect: edge);
1268 ref->remove_reference ();
1269 if (e2->indirect_unknown_callee || e2->inline_failed)
1270 remove (edge: e2);
1271 else
1272 e2->callee->remove_symbol_and_inline_clones ();
1273 return edge;
1274}
1275
1276/* Return edge corresponding to speculative call to a given target.
1277 NULL if speculative call does not have one. */
1278
1279cgraph_edge *
1280cgraph_edge::speculative_call_for_target (cgraph_node *target)
1281{
1282 for (cgraph_edge *direct = first_speculative_call_target ();
1283 direct;
1284 direct = direct->next_speculative_call_target ())
1285 if (direct->speculative_call_target_ref ()
1286 ->referred->semantically_equivalent_p (target))
1287 return direct;
1288 return NULL;
1289}
1290
1291/* Make an indirect or speculative EDGE with an unknown callee an ordinary edge
1292 leading to CALLEE. Speculations can be resolved in the process and EDGE can
1293 be removed and deallocated. Return the edge that now represents the
1294 call. */
1295
1296cgraph_edge *
1297cgraph_edge::make_direct (cgraph_edge *edge, cgraph_node *callee)
1298{
1299 gcc_assert (edge->indirect_unknown_callee || edge->speculative);
1300
1301 /* If we are redirecting speculative call, make it non-speculative. */
1302 if (edge->speculative)
1303 {
1304 cgraph_edge *found = NULL;
1305 cgraph_edge *direct, *next;
1306
1307 edge = edge->speculative_call_indirect_edge ();
1308
1309 /* Look all speculative targets and remove all but one corresponding
1310 to callee (if it exists). */
1311 for (direct = edge->first_speculative_call_target ();
1312 direct;
1313 direct = next)
1314 {
1315 next = direct->next_speculative_call_target ();
1316
1317 /* Compare ref not direct->callee. Direct edge is possibly
1318 inlined or redirected. */
1319 if (!direct->speculative_call_target_ref ()
1320 ->referred->semantically_equivalent_p (target: callee))
1321 edge = direct->resolve_speculation (edge: direct, NULL);
1322 else
1323 {
1324 gcc_checking_assert (!found);
1325 found = direct;
1326 }
1327 }
1328
1329 /* On successful speculation just remove the indirect edge and
1330 return the pre existing direct edge.
1331 It is important to not remove it and redirect because the direct
1332 edge may be inlined or redirected. */
1333 if (found)
1334 {
1335 cgraph_edge *e2 = resolve_speculation (edge: found, callee_decl: callee->decl);
1336 gcc_checking_assert (!found->speculative && e2 == found);
1337 return found;
1338 }
1339 gcc_checking_assert (!edge->speculative);
1340 }
1341
1342 edge->indirect_unknown_callee = 0;
1343 ggc_free (edge->indirect_info);
1344 edge->indirect_info = NULL;
1345
1346 /* Get the edge out of the indirect edge list. */
1347 if (edge->prev_callee)
1348 edge->prev_callee->next_callee = edge->next_callee;
1349 if (edge->next_callee)
1350 edge->next_callee->prev_callee = edge->prev_callee;
1351 if (!edge->prev_callee)
1352 edge->caller->indirect_calls = edge->next_callee;
1353
1354 /* Put it into the normal callee list */
1355 edge->prev_callee = NULL;
1356 edge->next_callee = edge->caller->callees;
1357 if (edge->caller->callees)
1358 edge->caller->callees->prev_callee = edge;
1359 edge->caller->callees = edge;
1360
1361 /* Insert to callers list of the new callee. */
1362 edge->set_callee (callee);
1363
1364 /* We need to re-determine the inlining status of the edge. */
1365 initialize_inline_failed (edge);
1366 return edge;
1367}
1368
1369/* Redirect callee of the edge to N. The function does not update underlying
1370 call expression. */
1371
1372void
1373cgraph_edge::redirect_callee (cgraph_node *n)
1374{
1375 bool loc = callee->comdat_local_p ();
1376 /* Remove from callers list of the current callee. */
1377 remove_callee ();
1378
1379 /* Insert to callers list of the new callee. */
1380 set_callee (n);
1381
1382 if (!inline_failed)
1383 return;
1384 if (!loc && n->comdat_local_p ())
1385 {
1386 cgraph_node *to = caller->inlined_to ? caller->inlined_to : caller;
1387 to->calls_comdat_local = true;
1388 }
1389 else if (loc && !n->comdat_local_p ())
1390 {
1391 cgraph_node *to = caller->inlined_to ? caller->inlined_to : caller;
1392 gcc_checking_assert (to->calls_comdat_local);
1393 to->calls_comdat_local = to->check_calls_comdat_local_p ();
1394 }
1395}
1396
1397/* If necessary, change the function declaration in the call statement
1398 associated with E so that it corresponds to the edge callee. Speculations
1399 can be resolved in the process and EDGE can be removed and deallocated.
1400
1401 The edge could be one of speculative direct call generated from speculative
1402 indirect call. In this circumstance, decrease the speculative targets
1403 count (i.e. num_speculative_call_targets) and redirect call stmt to the
1404 corresponding i-th target. If no speculative direct call left to the
1405 speculative indirect call, remove "speculative" of the indirect call and
1406 also redirect stmt to it's final direct target.
1407
1408 When called from within tree-inline, KILLED_SSAs has to contain the pointer
1409 to killed_new_ssa_names within the copy_body_data structure and SSAs
1410 discovered to be useless (if LHS is removed) will be added to it, otherwise
1411 it needs to be NULL.
1412
1413 It is up to caller to iteratively transform each "speculative"
1414 direct call as appropriate. */
1415
1416gimple *
1417cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge *e,
1418 hash_set <tree> *killed_ssas)
1419{
1420 tree decl = gimple_call_fndecl (gs: e->call_stmt);
1421 gcall *new_stmt;
1422
1423 if (e->speculative)
1424 {
1425 /* If there already is an direct call (i.e. as a result of inliner's
1426 substitution), forget about speculating. */
1427 if (decl)
1428 e = make_direct (edge: e->speculative_call_indirect_edge (),
1429 callee: cgraph_node::get (decl));
1430 else
1431 {
1432 /* Be sure we redirect all speculative targets before poking
1433 about indirect edge. */
1434 gcc_checking_assert (e->callee);
1435 cgraph_edge *indirect = e->speculative_call_indirect_edge ();
1436 gcall *new_stmt;
1437 ipa_ref *ref;
1438
1439 /* Expand speculation into GIMPLE code. */
1440 if (dump_file)
1441 {
1442 fprintf (stream: dump_file,
1443 format: "Expanding speculative call of %s -> %s count: ",
1444 e->caller->dump_name (),
1445 e->callee->dump_name ());
1446 e->count.dump (f: dump_file);
1447 fprintf (stream: dump_file, format: "\n");
1448 }
1449 push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
1450
1451 profile_count all = indirect->count;
1452 for (cgraph_edge *e2 = e->first_speculative_call_target ();
1453 e2;
1454 e2 = e2->next_speculative_call_target ())
1455 all = all + e2->count;
1456 profile_probability prob = e->count.probability_in (overall: all);
1457 if (!prob.initialized_p ())
1458 prob = profile_probability::even ();
1459 ref = e->speculative_call_target_ref ();
1460 new_stmt = gimple_ic (e->call_stmt,
1461 dyn_cast<cgraph_node *> (p: ref->referred),
1462 prob);
1463 e->speculative = false;
1464 if (indirect->num_speculative_call_targets_p ())
1465 {
1466 /* The indirect edge has multiple speculative targets, don't
1467 remove speculative until all related direct edges are
1468 redirected. */
1469 indirect->indirect_info->num_speculative_call_targets--;
1470 if (!indirect->indirect_info->num_speculative_call_targets)
1471 indirect->speculative = false;
1472 }
1473 else
1474 indirect->speculative = false;
1475 /* Indirect edges are not both in the call site hash.
1476 get it updated. */
1477 update_call_stmt_hash_for_removing_direct_edge (e, indirect);
1478 cgraph_edge::set_call_stmt (e, new_stmt, update_speculative: false);
1479 e->count = gimple_bb (g: e->call_stmt)->count;
1480
1481 /* Once we are done with expanding the sequence, update also indirect
1482 call probability. Until then the basic block accounts for the
1483 sum of indirect edge and all non-expanded speculations. */
1484 if (!indirect->speculative)
1485 indirect->count = gimple_bb (g: indirect->call_stmt)->count;
1486 ref->speculative = false;
1487 ref->stmt = NULL;
1488 pop_cfun ();
1489 /* Continue redirecting E to proper target. */
1490 }
1491 }
1492
1493
1494 if (e->indirect_unknown_callee
1495 || decl == e->callee->decl)
1496 return e->call_stmt;
1497
1498 if (decl && ipa_saved_clone_sources)
1499 {
1500 tree *p = ipa_saved_clone_sources->get (node: e->callee);
1501 if (p && decl == *p)
1502 {
1503 gimple_call_set_fndecl (gs: e->call_stmt, decl: e->callee->decl);
1504 return e->call_stmt;
1505 }
1506 }
1507 if (flag_checking && decl)
1508 {
1509 if (cgraph_node *node = cgraph_node::get (decl))
1510 {
1511 clone_info *info = clone_info::get (node);
1512 gcc_assert (!info || !info->param_adjustments);
1513 }
1514 }
1515
1516 clone_info *callee_info = clone_info::get (node: e->callee);
1517 if (symtab->dump_file)
1518 {
1519 fprintf (stream: symtab->dump_file, format: "updating call of %s -> %s: ",
1520 e->caller->dump_name (), e->callee->dump_name ());
1521 print_gimple_stmt (symtab->dump_file, e->call_stmt, 0, dump_flags);
1522 if (callee_info && callee_info->param_adjustments)
1523 callee_info->param_adjustments->dump (f: symtab->dump_file);
1524 }
1525
1526 if (ipa_param_adjustments *padjs
1527 = callee_info ? callee_info->param_adjustments : NULL)
1528 {
1529 /* We need to defer cleaning EH info on the new statement to
1530 fixup-cfg. We may not have dominator information at this point
1531 and thus would end up with unreachable blocks and have no way
1532 to communicate that we need to run CFG cleanup then. */
1533 int lp_nr = lookup_stmt_eh_lp (e->call_stmt);
1534 if (lp_nr != 0)
1535 remove_stmt_from_eh_lp (e->call_stmt);
1536
1537 tree old_fntype = gimple_call_fntype (gs: e->call_stmt);
1538 new_stmt = padjs->modify_call (cs: e, update_references: false, killed_ssas);
1539 cgraph_node *origin = e->callee;
1540 while (origin->clone_of)
1541 origin = origin->clone_of;
1542
1543 if ((origin->former_clone_of
1544 && old_fntype == TREE_TYPE (origin->former_clone_of))
1545 || old_fntype == TREE_TYPE (origin->decl))
1546 gimple_call_set_fntype (call_stmt: new_stmt, TREE_TYPE (e->callee->decl));
1547 else
1548 {
1549 tree new_fntype = padjs->build_new_function_type (old_type: old_fntype, type_is_original_p: true);
1550 gimple_call_set_fntype (call_stmt: new_stmt, fntype: new_fntype);
1551 }
1552
1553 if (lp_nr != 0)
1554 add_stmt_to_eh_lp (new_stmt, lp_nr);
1555 }
1556 else
1557 {
1558 if (flag_checking
1559 && !fndecl_built_in_p (node: e->callee->decl, name1: BUILT_IN_UNREACHABLE,
1560 names: BUILT_IN_UNREACHABLE_TRAP))
1561 ipa_verify_edge_has_no_modifications (cs: e);
1562 new_stmt = e->call_stmt;
1563 gimple_call_set_fndecl (gs: new_stmt, decl: e->callee->decl);
1564 update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), s: new_stmt);
1565 }
1566
1567 /* If changing the call to __cxa_pure_virtual or similar noreturn function,
1568 adjust gimple_call_fntype too. */
1569 if (gimple_call_noreturn_p (s: new_stmt)
1570 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (e->callee->decl)))
1571 && TYPE_ARG_TYPES (TREE_TYPE (e->callee->decl))
1572 && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (e->callee->decl)))
1573 == void_type_node))
1574 gimple_call_set_fntype (call_stmt: new_stmt, TREE_TYPE (e->callee->decl));
1575
1576 /* If the call becomes noreturn, remove the LHS if possible. */
1577 tree lhs = gimple_call_lhs (gs: new_stmt);
1578 if (lhs
1579 && gimple_call_noreturn_p (s: new_stmt)
1580 && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (new_stmt)))
1581 || should_remove_lhs_p (lhs)))
1582 {
1583 gimple_call_set_lhs (gs: new_stmt, NULL_TREE);
1584 /* We need to fix up the SSA name to avoid checking errors. */
1585 if (TREE_CODE (lhs) == SSA_NAME)
1586 {
1587 tree var = create_tmp_reg_fn (DECL_STRUCT_FUNCTION (e->caller->decl),
1588 TREE_TYPE (lhs), NULL);
1589 SET_SSA_NAME_VAR_OR_IDENTIFIER (lhs, var);
1590 SSA_NAME_DEF_STMT (lhs) = gimple_build_nop ();
1591 set_ssa_default_def (DECL_STRUCT_FUNCTION (e->caller->decl),
1592 var, lhs);
1593 }
1594 update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), s: new_stmt);
1595 }
1596
1597 /* If new callee has no static chain, remove it. */
1598 if (gimple_call_chain (gs: new_stmt) && !DECL_STATIC_CHAIN (e->callee->decl))
1599 {
1600 gimple_call_set_chain (call_stmt: new_stmt, NULL);
1601 update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), s: new_stmt);
1602 }
1603
1604 maybe_remove_unused_call_args (DECL_STRUCT_FUNCTION (e->caller->decl),
1605 new_stmt);
1606
1607 e->caller->set_call_stmt_including_clones (old_stmt: e->call_stmt, new_stmt, update_speculative: false);
1608
1609 if (symtab->dump_file)
1610 {
1611 fprintf (stream: symtab->dump_file, format: " updated to:");
1612 print_gimple_stmt (symtab->dump_file, e->call_stmt, 0, dump_flags);
1613 }
1614 return new_stmt;
1615}
1616
1617/* Update or remove the corresponding cgraph edge if a GIMPLE_CALL
1618 OLD_STMT changed into NEW_STMT. OLD_CALL is gimple_call_fndecl
1619 of OLD_STMT if it was previously call statement.
1620 If NEW_STMT is NULL, the call has been dropped without any
1621 replacement. */
1622
1623static void
1624cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
1625 gimple *old_stmt, tree old_call,
1626 gimple *new_stmt)
1627{
1628 tree new_call = (new_stmt && is_gimple_call (gs: new_stmt))
1629 ? gimple_call_fndecl (gs: new_stmt) : 0;
1630
1631 /* We are seeing indirect calls, then there is nothing to update. */
1632 if (!new_call && !old_call)
1633 return;
1634 /* See if we turned indirect call into direct call or folded call to one builtin
1635 into different builtin. */
1636 if (old_call != new_call)
1637 {
1638 cgraph_edge *e = node->get_edge (call_stmt: old_stmt);
1639 cgraph_edge *ne = NULL;
1640 profile_count count;
1641
1642 if (e)
1643 {
1644 /* Keep calls marked as dead dead. */
1645 if (new_stmt && is_gimple_call (gs: new_stmt) && e->callee
1646 && fndecl_built_in_p (node: e->callee->decl, name1: BUILT_IN_UNREACHABLE,
1647 names: BUILT_IN_UNREACHABLE_TRAP))
1648 {
1649 cgraph_edge::set_call_stmt (e: node->get_edge (call_stmt: old_stmt),
1650 new_stmt: as_a <gcall *> (p: new_stmt));
1651 return;
1652 }
1653 /* See if the edge is already there and has the correct callee. It
1654 might be so because of indirect inlining has already updated
1655 it. We also might've cloned and redirected the edge. */
1656 if (new_call && e->callee)
1657 {
1658 cgraph_node *callee = e->callee;
1659 while (callee)
1660 {
1661 if (callee->decl == new_call
1662 || callee->former_clone_of == new_call)
1663 {
1664 cgraph_edge::set_call_stmt (e, new_stmt: as_a <gcall *> (p: new_stmt));
1665 return;
1666 }
1667 callee = callee->clone_of;
1668 }
1669 }
1670
1671 /* Otherwise remove edge and create new one; we can't simply redirect
1672 since function has changed, so inline plan and other information
1673 attached to edge is invalid. */
1674 count = e->count;
1675 if (e->indirect_unknown_callee || e->inline_failed)
1676 cgraph_edge::remove (edge: e);
1677 else
1678 e->callee->remove_symbol_and_inline_clones ();
1679 }
1680 else if (new_call)
1681 {
1682 /* We are seeing new direct call; compute profile info based on BB. */
1683 basic_block bb = gimple_bb (g: new_stmt);
1684 count = bb->count;
1685 }
1686
1687 if (new_call)
1688 {
1689 ne = node->create_edge (callee: cgraph_node::get_create (decl: new_call),
1690 call_stmt: as_a <gcall *> (p: new_stmt), count);
1691 gcc_assert (ne->inline_failed);
1692 }
1693 }
1694 /* We only updated the call stmt; update pointer in cgraph edge.. */
1695 else if (old_stmt != new_stmt)
1696 cgraph_edge::set_call_stmt (e: node->get_edge (call_stmt: old_stmt),
1697 new_stmt: as_a <gcall *> (p: new_stmt));
1698}
1699
1700/* Update or remove the corresponding cgraph edge if a GIMPLE_CALL
1701 OLD_STMT changed into NEW_STMT. OLD_DECL is gimple_call_fndecl
1702 of OLD_STMT before it was updated (updating can happen inplace). */
1703
1704void
1705cgraph_update_edges_for_call_stmt (gimple *old_stmt, tree old_decl,
1706 gimple *new_stmt)
1707{
1708 cgraph_node *orig = cgraph_node::get (cfun->decl);
1709 cgraph_node *node;
1710
1711 gcc_checking_assert (orig);
1712 cgraph_update_edges_for_call_stmt_node (node: orig, old_stmt, old_call: old_decl, new_stmt);
1713 if (orig->clones)
1714 for (node = orig->clones; node != orig;)
1715 {
1716 cgraph_update_edges_for_call_stmt_node (node, old_stmt, old_call: old_decl,
1717 new_stmt);
1718 if (node->clones)
1719 node = node->clones;
1720 else if (node->next_sibling_clone)
1721 node = node->next_sibling_clone;
1722 else
1723 {
1724 while (node != orig && !node->next_sibling_clone)
1725 node = node->clone_of;
1726 if (node != orig)
1727 node = node->next_sibling_clone;
1728 }
1729 }
1730}
1731
1732
1733/* Remove all callees from the node. */
1734
1735void
1736cgraph_node::remove_callees (void)
1737{
1738 cgraph_edge *e, *f;
1739
1740 calls_comdat_local = false;
1741
1742 /* It is sufficient to remove the edges from the lists of callers of
1743 the callees. The callee list of the node can be zapped with one
1744 assignment. */
1745 for (e = callees; e; e = f)
1746 {
1747 f = e->next_callee;
1748 symtab->call_edge_removal_hooks (e);
1749 if (!e->indirect_unknown_callee)
1750 e->remove_callee ();
1751 symtab->free_edge (e);
1752 }
1753 for (e = indirect_calls; e; e = f)
1754 {
1755 f = e->next_callee;
1756 symtab->call_edge_removal_hooks (e);
1757 if (!e->indirect_unknown_callee)
1758 e->remove_callee ();
1759 symtab->free_edge (e);
1760 }
1761 indirect_calls = NULL;
1762 callees = NULL;
1763 if (call_site_hash)
1764 {
1765 call_site_hash->empty ();
1766 call_site_hash = NULL;
1767 }
1768}
1769
1770/* Remove all callers from the node. */
1771
1772void
1773cgraph_node::remove_callers (void)
1774{
1775 cgraph_edge *e, *f;
1776
1777 /* It is sufficient to remove the edges from the lists of callees of
1778 the callers. The caller list of the node can be zapped with one
1779 assignment. */
1780 for (e = callers; e; e = f)
1781 {
1782 f = e->next_caller;
1783 symtab->call_edge_removal_hooks (e);
1784 e->remove_caller ();
1785 symtab->free_edge (e);
1786 }
1787 callers = NULL;
1788}
1789
1790/* Helper function for cgraph_release_function_body and free_lang_data.
1791 It releases body from function DECL without having to inspect its
1792 possibly non-existent symtab node. */
1793
1794void
1795release_function_body (tree decl)
1796{
1797 function *fn = DECL_STRUCT_FUNCTION (decl);
1798 if (fn)
1799 {
1800 if (fn->cfg
1801 && loops_for_fn (fn))
1802 {
1803 fn->curr_properties &= ~PROP_loops;
1804 loop_optimizer_finalize (fn);
1805 }
1806 if (fn->gimple_df)
1807 {
1808 delete_tree_ssa (fn);
1809 fn->eh = NULL;
1810 }
1811 if (fn->cfg)
1812 {
1813 gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS));
1814 gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS));
1815 delete_tree_cfg_annotations (fn);
1816 free_cfg (fn);
1817 fn->cfg = NULL;
1818 }
1819 if (fn->value_histograms)
1820 free_histograms (fn);
1821 gimple_set_body (decl, NULL);
1822 /* Struct function hangs a lot of data that would leak if we didn't
1823 removed all pointers to it. */
1824 ggc_free (fn);
1825 DECL_STRUCT_FUNCTION (decl) = NULL;
1826 }
1827 DECL_SAVED_TREE (decl) = NULL;
1828}
1829
1830/* Release memory used to represent body of function.
1831 Use this only for functions that are released before being translated to
1832 target code (i.e. RTL). Functions that are compiled to RTL and beyond
1833 are free'd in final.cc via free_after_compilation().
1834 KEEP_ARGUMENTS are useful only if you want to rebuild body as thunk. */
1835
1836void
1837cgraph_node::release_body (bool keep_arguments)
1838{
1839 ipa_transforms_to_apply.release ();
1840 if (!used_as_abstract_origin && symtab->state != PARSING)
1841 {
1842 DECL_RESULT (decl) = NULL;
1843
1844 if (!keep_arguments)
1845 DECL_ARGUMENTS (decl) = NULL;
1846 }
1847 /* If the node is abstract and needed, then do not clear
1848 DECL_INITIAL of its associated function declaration because it's
1849 needed to emit debug info later. */
1850 if (!used_as_abstract_origin && DECL_INITIAL (decl))
1851 DECL_INITIAL (decl) = error_mark_node;
1852 release_function_body (decl);
1853 if (lto_file_data)
1854 {
1855 lto_free_function_in_decl_state_for_node (this);
1856 lto_file_data = NULL;
1857 }
1858 if (flag_checking && clones)
1859 {
1860 /* It is invalid to release body before materializing clones except
1861 for thunks that don't really need a body. Verify also that we do
1862 not leak pointers to the call statements. */
1863 for (cgraph_node *node = clones; node;
1864 node = node->next_sibling_clone)
1865 gcc_assert (node->thunk && !node->callees->call_stmt);
1866 }
1867 remove_callees ();
1868 remove_all_references ();
1869}
1870
1871/* Remove function from symbol table. */
1872
1873void
1874cgraph_node::remove (void)
1875{
1876 bool clone_info_set = false;
1877 clone_info *info, saved_info;
1878 if (symtab->ipa_clones_dump_file && symtab->cloned_nodes.contains (k: this))
1879 fprintf (stream: symtab->ipa_clones_dump_file,
1880 format: "Callgraph removal;%s;%d;%s;%d;%d\n", asm_name (), order,
1881 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
1882 DECL_SOURCE_COLUMN (decl));
1883
1884 if ((info = clone_info::get (node: this)) != NULL)
1885 {
1886 saved_info = *info;
1887 clone_info_set = true;
1888 }
1889 symtab->call_cgraph_removal_hooks (node: this);
1890 remove_callers ();
1891 remove_callees ();
1892 ipa_transforms_to_apply.release ();
1893 delete_function_version (decl_v: function_version ());
1894
1895 /* Incremental inlining access removed nodes stored in the postorder list.
1896 */
1897 force_output = false;
1898 forced_by_abi = false;
1899
1900 unregister (clone_info_set ? &saved_info : NULL);
1901 if (prev_sibling_clone)
1902 prev_sibling_clone->next_sibling_clone = next_sibling_clone;
1903 else if (clone_of)
1904 {
1905 clone_of->clones = next_sibling_clone;
1906 if (!clones)
1907 {
1908 bool need_body = false;
1909 for (cgraph_node *n = clone_of; n; n = n->clone_of)
1910 if (n->analyzed || n->clones)
1911 {
1912 need_body = true;
1913 break;
1914 }
1915 if (!need_body)
1916 clone_of->release_body ();
1917 }
1918 }
1919 if (next_sibling_clone)
1920 next_sibling_clone->prev_sibling_clone = prev_sibling_clone;
1921 if (clones)
1922 {
1923 cgraph_node *n, *next;
1924
1925 if (clone_of)
1926 {
1927 for (n = clones; n->next_sibling_clone; n = n->next_sibling_clone)
1928 n->clone_of = clone_of;
1929 n->clone_of = clone_of;
1930 n->next_sibling_clone = clone_of->clones;
1931 if (clone_of->clones)
1932 clone_of->clones->prev_sibling_clone = n;
1933 clone_of->clones = clones;
1934 }
1935 else
1936 {
1937 /* We are removing node with clones. This makes clones inconsistent,
1938 but assume they will be removed subsequently and just keep clone
1939 tree intact. This can happen in unreachable function removal since
1940 we remove unreachable functions in random order, not by bottom-up
1941 walk of clone trees. */
1942 for (n = clones; n; n = next)
1943 {
1944 next = n->next_sibling_clone;
1945 n->next_sibling_clone = NULL;
1946 n->prev_sibling_clone = NULL;
1947 n->clone_of = NULL;
1948 }
1949 }
1950 }
1951
1952 /* While all the clones are removed after being proceeded, the function
1953 itself is kept in the cgraph even after it is compiled. Check whether
1954 we are done with this body and reclaim it proactively if this is the case.
1955 */
1956 if (symtab->state != LTO_STREAMING)
1957 {
1958 cgraph_node *n = cgraph_node::get (decl);
1959 if (!n
1960 || (!n->clones && !n->clone_of && !n->inlined_to
1961 && ((symtab->global_info_ready || in_lto_p)
1962 && (TREE_ASM_WRITTEN (n->decl)
1963 || DECL_EXTERNAL (n->decl)
1964 || !n->analyzed
1965 || (!flag_wpa && n->in_other_partition)))))
1966 release_body ();
1967 }
1968 else
1969 {
1970 lto_free_function_in_decl_state_for_node (this);
1971 lto_file_data = NULL;
1972 }
1973
1974 decl = NULL;
1975 if (call_site_hash)
1976 {
1977 call_site_hash->empty ();
1978 call_site_hash = NULL;
1979 }
1980
1981 symtab->release_symbol (node: this);
1982}
1983
1984/* Likewise indicate that a node is having address taken. */
1985
1986void
1987cgraph_node::mark_address_taken (void)
1988{
1989 /* Indirect inlining can figure out that all uses of the address are
1990 inlined. */
1991 if (inlined_to)
1992 {
1993 gcc_assert (cfun->after_inlining);
1994 gcc_assert (callers->indirect_inlining_edge);
1995 return;
1996 }
1997 /* FIXME: address_taken flag is used both as a shortcut for testing whether
1998 IPA_REF_ADDR reference exists (and thus it should be set on node
1999 representing alias we take address of) and as a test whether address
2000 of the object was taken (and thus it should be set on node alias is
2001 referring to). We should remove the first use and the remove the
2002 following set. */
2003 address_taken = 1;
2004 cgraph_node *node = ultimate_alias_target ();
2005 node->address_taken = 1;
2006}
2007
2008/* Return local info node for the compiled function. */
2009
2010cgraph_node *
2011cgraph_node::local_info_node (tree decl)
2012{
2013 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
2014 cgraph_node *node = get (decl);
2015 if (!node)
2016 return NULL;
2017 return node->ultimate_alias_target ();
2018}
2019
2020/* Return RTL info for the compiled function. */
2021
2022cgraph_rtl_info *
2023cgraph_node::rtl_info (const_tree decl)
2024{
2025 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
2026 cgraph_node *node = get (decl);
2027 if (!node)
2028 return NULL;
2029 enum availability avail;
2030 node = node->ultimate_alias_target (availability: &avail);
2031 if (decl != current_function_decl
2032 && (avail < AVAIL_AVAILABLE
2033 || (node->decl != current_function_decl
2034 && !TREE_ASM_WRITTEN (node->decl))))
2035 return NULL;
2036 /* Allocate if it doesn't exist. */
2037 if (node->rtl == NULL)
2038 {
2039 node->rtl = ggc_cleared_alloc<cgraph_rtl_info> ();
2040 SET_HARD_REG_SET (node->rtl->function_used_regs);
2041 }
2042 return node->rtl;
2043}
2044
2045/* Return a string describing the failure REASON. */
2046
2047const char*
2048cgraph_inline_failed_string (cgraph_inline_failed_t reason)
2049{
2050#undef DEFCIFCODE
2051#define DEFCIFCODE(code, type, string) string,
2052
2053 static const char *cif_string_table[CIF_N_REASONS] = {
2054#include "cif-code.def"
2055 };
2056
2057 /* Signedness of an enum type is implementation defined, so cast it
2058 to unsigned before testing. */
2059 gcc_assert ((unsigned) reason < CIF_N_REASONS);
2060 return cif_string_table[reason];
2061}
2062
2063/* Return a type describing the failure REASON. */
2064
2065cgraph_inline_failed_type_t
2066cgraph_inline_failed_type (cgraph_inline_failed_t reason)
2067{
2068#undef DEFCIFCODE
2069#define DEFCIFCODE(code, type, string) type,
2070
2071 static cgraph_inline_failed_type_t cif_type_table[CIF_N_REASONS] = {
2072#include "cif-code.def"
2073 };
2074
2075 /* Signedness of an enum type is implementation defined, so cast it
2076 to unsigned before testing. */
2077 gcc_assert ((unsigned) reason < CIF_N_REASONS);
2078 return cif_type_table[reason];
2079}
2080
2081/* Names used to print out the availability enum. */
2082const char * const cgraph_availability_names[] =
2083 {"unset", "not_available", "overwritable", "available", "local"};
2084
2085/* Output flags of edge to a file F. */
2086
2087void
2088cgraph_edge::dump_edge_flags (FILE *f)
2089{
2090 if (speculative)
2091 fprintf (stream: f, format: "(speculative) ");
2092 if (!inline_failed)
2093 fprintf (stream: f, format: "(inlined) ");
2094 if (call_stmt_cannot_inline_p)
2095 fprintf (stream: f, format: "(call_stmt_cannot_inline_p) ");
2096 if (indirect_inlining_edge)
2097 fprintf (stream: f, format: "(indirect_inlining) ");
2098 if (count.initialized_p ())
2099 {
2100 fprintf (stream: f, format: "(");
2101 count.dump (f);
2102 fprintf (stream: f, format: ",");
2103 fprintf (stream: f, format: "%.2f per call) ", sreal_frequency ().to_double ());
2104 }
2105 if (can_throw_external)
2106 fprintf (stream: f, format: "(can throw external) ");
2107}
2108
2109/* Dump edge to stderr. */
2110
2111void
2112cgraph_edge::debug (void)
2113{
2114 fprintf (stderr, format: "%s -> %s ", caller->dump_asm_name (),
2115 callee == NULL ? "(null)" : callee->dump_asm_name ());
2116 dump_edge_flags (stderr);
2117 fprintf (stderr, format: "\n\n");
2118 caller->debug ();
2119 if (callee != NULL)
2120 callee->debug ();
2121}
2122
2123/* Dump call graph node to file F. */
2124
2125void
2126cgraph_node::dump (FILE *f)
2127{
2128 cgraph_edge *edge;
2129
2130 dump_base (f);
2131
2132 if (inlined_to)
2133 fprintf (stream: f, format: " Function %s is inline copy in %s\n",
2134 dump_name (),
2135 inlined_to->dump_name ());
2136 if (clone_of)
2137 fprintf (stream: f, format: " Clone of %s\n", clone_of->dump_asm_name ());
2138 if (symtab->function_flags_ready)
2139 fprintf (stream: f, format: " Availability: %s\n",
2140 cgraph_availability_names [get_availability ()]);
2141
2142 if (profile_id)
2143 fprintf (stream: f, format: " Profile id: %i\n",
2144 profile_id);
2145 if (unit_id)
2146 fprintf (stream: f, format: " Unit id: %i\n",
2147 unit_id);
2148 cgraph_function_version_info *vi = function_version ();
2149 if (vi != NULL)
2150 {
2151 fprintf (stream: f, format: " Version info: ");
2152 if (vi->prev != NULL)
2153 {
2154 fprintf (stream: f, format: "prev: ");
2155 fprintf (stream: f, format: "%s ", vi->prev->this_node->dump_asm_name ());
2156 }
2157 if (vi->next != NULL)
2158 {
2159 fprintf (stream: f, format: "next: ");
2160 fprintf (stream: f, format: "%s ", vi->next->this_node->dump_asm_name ());
2161 }
2162 if (vi->dispatcher_resolver != NULL_TREE)
2163 fprintf (stream: f, format: "dispatcher: %s",
2164 lang_hooks.decl_printable_name (vi->dispatcher_resolver, 2));
2165
2166 fprintf (stream: f, format: "\n");
2167 }
2168 fprintf (stream: f, format: " Function flags:");
2169 if (count.initialized_p ())
2170 {
2171 fprintf (stream: f, format: " count:");
2172 count.dump (f);
2173 }
2174 if (tp_first_run > 0)
2175 fprintf (stream: f, format: " first_run:%" PRId64, (int64_t) tp_first_run);
2176 if (cgraph_node *origin = nested_function_origin (node: this))
2177 fprintf (stream: f, format: " nested in:%s", origin->dump_asm_name ());
2178 if (gimple_has_body_p (decl))
2179 fprintf (stream: f, format: " body");
2180 if (process)
2181 fprintf (stream: f, format: " process");
2182 if (local)
2183 fprintf (stream: f, format: " local");
2184 if (redefined_extern_inline)
2185 fprintf (stream: f, format: " redefined_extern_inline");
2186 if (only_called_at_startup)
2187 fprintf (stream: f, format: " only_called_at_startup");
2188 if (only_called_at_exit)
2189 fprintf (stream: f, format: " only_called_at_exit");
2190 if (tm_clone)
2191 fprintf (stream: f, format: " tm_clone");
2192 if (calls_comdat_local)
2193 fprintf (stream: f, format: " calls_comdat_local");
2194 if (icf_merged)
2195 fprintf (stream: f, format: " icf_merged");
2196 if (merged_comdat)
2197 fprintf (stream: f, format: " merged_comdat");
2198 if (merged_extern_inline)
2199 fprintf (stream: f, format: " merged_extern_inline");
2200 if (split_part)
2201 fprintf (stream: f, format: " split_part");
2202 if (indirect_call_target)
2203 fprintf (stream: f, format: " indirect_call_target");
2204 if (nonfreeing_fn)
2205 fprintf (stream: f, format: " nonfreeing_fn");
2206 if (DECL_STATIC_CONSTRUCTOR (decl))
2207 fprintf (stream: f,format: " static_constructor (priority:%i)", get_init_priority ());
2208 if (DECL_STATIC_DESTRUCTOR (decl))
2209 fprintf (stream: f,format: " static_destructor (priority:%i)", get_fini_priority ());
2210 if (frequency == NODE_FREQUENCY_HOT)
2211 fprintf (stream: f, format: " hot");
2212 if (frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
2213 fprintf (stream: f, format: " unlikely_executed");
2214 if (frequency == NODE_FREQUENCY_EXECUTED_ONCE)
2215 fprintf (stream: f, format: " executed_once");
2216 if (opt_for_fn (decl, optimize_size))
2217 fprintf (stream: f, format: " optimize_size");
2218 if (parallelized_function)
2219 fprintf (stream: f, format: " parallelized_function");
2220 if (DECL_IS_MALLOC (decl))
2221 fprintf (stream: f, format: " decl_is_malloc");
2222 if (DECL_IS_OPERATOR_NEW_P (decl))
2223 fprintf (stream: f, format: " %soperator_new",
2224 DECL_IS_REPLACEABLE_OPERATOR (decl) ? "replaceable_" : "");
2225 if (DECL_IS_OPERATOR_DELETE_P (decl))
2226 fprintf (stream: f, format: " %soperator_delete",
2227 DECL_IS_REPLACEABLE_OPERATOR (decl) ? "replaceable_" : "");
2228
2229 if (DECL_STATIC_CHAIN (decl))
2230 fprintf (stream: f, format: " static_chain");
2231
2232 fprintf (stream: f, format: "\n");
2233
2234 if (thunk)
2235 {
2236 fprintf (stream: f, format: " Thunk");
2237 thunk_info::get (node: this)->dump (f);
2238 }
2239 else if (former_thunk_p ())
2240 {
2241 fprintf (stream: f, format: " Former thunk ");
2242 thunk_info::get (node: this)->dump (f);
2243 }
2244 else gcc_checking_assert (!thunk_info::get (this));
2245
2246 fprintf (stream: f, format: " Called by: ");
2247
2248 profile_count sum = profile_count::zero ();
2249 for (edge = callers; edge; edge = edge->next_caller)
2250 {
2251 fprintf (stream: f, format: "%s ", edge->caller->dump_asm_name ());
2252 edge->dump_edge_flags (f);
2253 if (edge->count.initialized_p ())
2254 sum += edge->count.ipa ();
2255 }
2256
2257 fprintf (stream: f, format: "\n Calls: ");
2258 for (edge = callees; edge; edge = edge->next_callee)
2259 {
2260 fprintf (stream: f, format: "%s ", edge->callee->dump_asm_name ());
2261 edge->dump_edge_flags (f);
2262 }
2263 fprintf (stream: f, format: "\n");
2264
2265 if (!body_removed && count.ipa ().initialized_p ())
2266 {
2267 bool ok = true;
2268 bool min = false;
2269 ipa_ref *ref;
2270
2271 FOR_EACH_ALIAS (this, ref)
2272 if (dyn_cast <cgraph_node *> (p: ref->referring)->count.initialized_p ())
2273 sum += dyn_cast <cgraph_node *> (p: ref->referring)->count.ipa ();
2274
2275 if (inlined_to
2276 || (symtab->state < EXPANSION
2277 && ultimate_alias_target () == this && only_called_directly_p ()))
2278 ok = !count.ipa ().differs_from_p (other: sum);
2279 else if (count.ipa () > profile_count::from_gcov_type (v: 100)
2280 && count.ipa () < sum.apply_scale (num: 99, den: 100))
2281 ok = false, min = true;
2282 if (!ok)
2283 {
2284 fprintf (stream: f, format: " Invalid sum of caller counts ");
2285 sum.dump (f);
2286 if (min)
2287 fprintf (stream: f, format: ", should be at most ");
2288 else
2289 fprintf (stream: f, format: ", should be ");
2290 count.ipa ().dump (f);
2291 fprintf (stream: f, format: "\n");
2292 }
2293 }
2294
2295 for (edge = indirect_calls; edge; edge = edge->next_callee)
2296 {
2297 if (edge->indirect_info->polymorphic)
2298 {
2299 fprintf (stream: f, format: " Polymorphic indirect call of type ");
2300 print_generic_expr (f, edge->indirect_info->otr_type, TDF_SLIM);
2301 fprintf (stream: f, format: " token:%i", (int) edge->indirect_info->otr_token);
2302 }
2303 else
2304 fprintf (stream: f, format: " Indirect call");
2305 edge->dump_edge_flags (f);
2306 if (edge->indirect_info->param_index != -1)
2307 {
2308 fprintf (stream: f, format: "of param:%i ", edge->indirect_info->param_index);
2309 if (edge->indirect_info->agg_contents)
2310 fprintf (stream: f, format: "loaded from %s %s at offset %i ",
2311 edge->indirect_info->member_ptr ? "member ptr" : "aggregate",
2312 edge->indirect_info->by_ref ? "passed by reference":"",
2313 (int)edge->indirect_info->offset);
2314 if (edge->indirect_info->vptr_changed)
2315 fprintf (stream: f, format: "(vptr maybe changed) ");
2316 }
2317 fprintf (stream: f, format: "num speculative call targets: %i\n",
2318 edge->indirect_info->num_speculative_call_targets);
2319 if (edge->indirect_info->polymorphic)
2320 edge->indirect_info->context.dump (f);
2321 }
2322}
2323
2324/* Dump call graph node to file F in graphviz format. */
2325
2326void
2327cgraph_node::dump_graphviz (FILE *f)
2328{
2329 cgraph_edge *edge;
2330
2331 for (edge = callees; edge; edge = edge->next_callee)
2332 {
2333 cgraph_node *callee = edge->callee;
2334
2335 fprintf (stream: f, format: "\t\"%s\" -> \"%s\"\n", dump_name (), callee->dump_name ());
2336 }
2337}
2338
2339
2340/* Dump call graph node NODE to stderr. */
2341
2342DEBUG_FUNCTION void
2343cgraph_node::debug (void)
2344{
2345 dump (stderr);
2346}
2347
2348/* Dump the callgraph to file F. */
2349
2350void
2351cgraph_node::dump_cgraph (FILE *f)
2352{
2353 cgraph_node *node;
2354
2355 fprintf (stream: f, format: "callgraph:\n\n");
2356 FOR_EACH_FUNCTION (node)
2357 node->dump (f);
2358}
2359
2360/* Return true when the DECL can possibly be inlined. */
2361
2362bool
2363cgraph_function_possibly_inlined_p (tree decl)
2364{
2365 if (!symtab->global_info_ready)
2366 return !DECL_UNINLINABLE (decl);
2367 return DECL_POSSIBLY_INLINED (decl);
2368}
2369
2370/* Return function availability. See cgraph.h for description of individual
2371 return values. */
2372enum availability
2373cgraph_node::get_availability (symtab_node *ref)
2374{
2375 if (ref)
2376 {
2377 cgraph_node *cref = dyn_cast <cgraph_node *> (p: ref);
2378 if (cref)
2379 ref = cref->inlined_to;
2380 }
2381 enum availability avail;
2382 if (!analyzed && !in_other_partition)
2383 avail = AVAIL_NOT_AVAILABLE;
2384 else if (local)
2385 avail = AVAIL_LOCAL;
2386 else if (inlined_to)
2387 avail = AVAIL_AVAILABLE;
2388 else if (transparent_alias)
2389 ultimate_alias_target (availability: &avail, ref);
2390 else if (ifunc_resolver
2391 || lookup_attribute (attr_name: "noipa", DECL_ATTRIBUTES (decl)))
2392 avail = AVAIL_INTERPOSABLE;
2393 else if (!externally_visible)
2394 avail = AVAIL_AVAILABLE;
2395 /* If this is a reference from symbol itself and there are no aliases, we
2396 may be sure that the symbol was not interposed by something else because
2397 the symbol itself would be unreachable otherwise.
2398
2399 Also comdat groups are always resolved in groups. */
2400 else if ((this == ref && !has_aliases_p ())
2401 || (ref && get_comdat_group ()
2402 && get_comdat_group () == ref->get_comdat_group ()))
2403 avail = AVAIL_AVAILABLE;
2404 /* Inline functions are safe to be analyzed even if their symbol can
2405 be overwritten at runtime. It is not meaningful to enforce any sane
2406 behavior on replacing inline function by different body. */
2407 else if (DECL_DECLARED_INLINE_P (decl))
2408 avail = AVAIL_AVAILABLE;
2409
2410 /* If the function can be overwritten, return OVERWRITABLE. Take
2411 care at least of two notable extensions - the COMDAT functions
2412 used to share template instantiations in C++ (this is symmetric
2413 to code cp_cannot_inline_tree_fn and probably shall be shared and
2414 the inlinability hooks completely eliminated). */
2415
2416 else if (decl_replaceable_p (decl, semantic_interposition)
2417 && !DECL_EXTERNAL (decl))
2418 avail = AVAIL_INTERPOSABLE;
2419 else avail = AVAIL_AVAILABLE;
2420
2421 return avail;
2422}
2423
2424/* Worker for cgraph_node_can_be_local_p. */
2425static bool
2426cgraph_node_cannot_be_local_p_1 (cgraph_node *node, void *)
2427{
2428 return !(!node->force_output
2429 && !node->ifunc_resolver
2430 /* Limitation of gas requires us to output targets of symver aliases
2431 as global symbols. This is binutils PR 25295. */
2432 && !node->symver
2433 && ((DECL_COMDAT (node->decl)
2434 && !node->forced_by_abi
2435 && !node->used_from_object_file_p ()
2436 && !node->same_comdat_group)
2437 || !node->externally_visible));
2438}
2439
2440/* Return true if cgraph_node can be made local for API change.
2441 Extern inline functions and C++ COMDAT functions can be made local
2442 at the expense of possible code size growth if function is used in multiple
2443 compilation units. */
2444bool
2445cgraph_node::can_be_local_p (void)
2446{
2447 return (!address_taken
2448 && !call_for_symbol_thunks_and_aliases (callback: cgraph_node_cannot_be_local_p_1,
2449 NULL, include_overwritable: true));
2450}
2451
2452/* Call callback on cgraph_node, thunks and aliases associated to cgraph_node.
2453 When INCLUDE_OVERWRITABLE is false, overwritable symbols are
2454 skipped. When EXCLUDE_VIRTUAL_THUNKS is true, virtual thunks are
2455 skipped. */
2456bool
2457cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
2458 (cgraph_node *, void *),
2459 void *data,
2460 bool include_overwritable,
2461 bool exclude_virtual_thunks)
2462{
2463 cgraph_edge *e;
2464 ipa_ref *ref;
2465 enum availability avail = AVAIL_AVAILABLE;
2466
2467 if (include_overwritable
2468 || (avail = get_availability ()) > AVAIL_INTERPOSABLE)
2469 {
2470 if (callback (this, data))
2471 return true;
2472 }
2473 FOR_EACH_ALIAS (this, ref)
2474 {
2475 cgraph_node *alias = dyn_cast <cgraph_node *> (p: ref->referring);
2476 if (include_overwritable
2477 || alias->get_availability () > AVAIL_INTERPOSABLE)
2478 if (alias->call_for_symbol_thunks_and_aliases (callback, data,
2479 include_overwritable,
2480 exclude_virtual_thunks))
2481 return true;
2482 }
2483 if (avail <= AVAIL_INTERPOSABLE)
2484 return false;
2485 for (e = callers; e; e = e->next_caller)
2486 if (e->caller->thunk
2487 && (include_overwritable
2488 || e->caller->get_availability () > AVAIL_INTERPOSABLE)
2489 && !(exclude_virtual_thunks
2490 && thunk_info::get (node: e->caller)->virtual_offset_p))
2491 if (e->caller->call_for_symbol_thunks_and_aliases (callback, data,
2492 include_overwritable,
2493 exclude_virtual_thunks))
2494 return true;
2495
2496 return false;
2497}
2498
2499/* Worker to bring NODE local. */
2500
2501bool
2502cgraph_node::make_local (cgraph_node *node, void *)
2503{
2504 gcc_checking_assert (node->can_be_local_p ());
2505 if (DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
2506 {
2507 node->make_decl_local ();
2508 node->set_section (NULL);
2509 node->set_comdat_group (NULL);
2510 node->externally_visible = false;
2511 node->forced_by_abi = false;
2512 node->local = true;
2513 node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
2514 || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
2515 && !flag_incremental_link);
2516 node->resolution = LDPR_PREVAILING_DEF_IRONLY;
2517 gcc_assert (node->get_availability () == AVAIL_LOCAL);
2518 }
2519 return false;
2520}
2521
2522/* Bring cgraph node local. */
2523
2524void
2525cgraph_node::make_local (void)
2526{
2527 call_for_symbol_thunks_and_aliases (callback: cgraph_node::make_local, NULL, include_overwritable: true);
2528}
2529
2530/* Worker to set nothrow flag. */
2531
2532static void
2533set_nothrow_flag_1 (cgraph_node *node, bool nothrow, bool non_call,
2534 bool *changed)
2535{
2536 cgraph_edge *e;
2537
2538 if (nothrow && !TREE_NOTHROW (node->decl))
2539 {
2540 /* With non-call exceptions we can't say for sure if other function body
2541 was not possibly optimized to still throw. */
2542 if (!non_call || node->binds_to_current_def_p ())
2543 {
2544 TREE_NOTHROW (node->decl) = true;
2545 *changed = true;
2546 for (e = node->callers; e; e = e->next_caller)
2547 e->can_throw_external = false;
2548 }
2549 }
2550 else if (!nothrow && TREE_NOTHROW (node->decl))
2551 {
2552 TREE_NOTHROW (node->decl) = false;
2553 *changed = true;
2554 }
2555 ipa_ref *ref;
2556 FOR_EACH_ALIAS (node, ref)
2557 {
2558 cgraph_node *alias = dyn_cast <cgraph_node *> (p: ref->referring);
2559 if (!nothrow || alias->get_availability () > AVAIL_INTERPOSABLE)
2560 set_nothrow_flag_1 (node: alias, nothrow, non_call, changed);
2561 }
2562 for (cgraph_edge *e = node->callers; e; e = e->next_caller)
2563 if (e->caller->thunk
2564 && (!nothrow || e->caller->get_availability () > AVAIL_INTERPOSABLE))
2565 set_nothrow_flag_1 (node: e->caller, nothrow, non_call, changed);
2566}
2567
2568/* Set TREE_NOTHROW on NODE's decl and on aliases of NODE
2569 if any to NOTHROW. */
2570
2571bool
2572cgraph_node::set_nothrow_flag (bool nothrow)
2573{
2574 bool changed = false;
2575 bool non_call = opt_for_fn (decl, flag_non_call_exceptions);
2576
2577 if (!nothrow || get_availability () > AVAIL_INTERPOSABLE)
2578 set_nothrow_flag_1 (node: this, nothrow, non_call, changed: &changed);
2579 else
2580 {
2581 ipa_ref *ref;
2582
2583 FOR_EACH_ALIAS (this, ref)
2584 {
2585 cgraph_node *alias = dyn_cast <cgraph_node *> (p: ref->referring);
2586 if (!nothrow || alias->get_availability () > AVAIL_INTERPOSABLE)
2587 set_nothrow_flag_1 (node: alias, nothrow, non_call, changed: &changed);
2588 }
2589 }
2590 return changed;
2591}
2592
2593/* Worker to set malloc flag. */
2594static void
2595set_malloc_flag_1 (cgraph_node *node, bool malloc_p, bool *changed)
2596{
2597 if (malloc_p && !DECL_IS_MALLOC (node->decl))
2598 {
2599 DECL_IS_MALLOC (node->decl) = true;
2600 *changed = true;
2601 }
2602
2603 ipa_ref *ref;
2604 FOR_EACH_ALIAS (node, ref)
2605 {
2606 cgraph_node *alias = dyn_cast<cgraph_node *> (p: ref->referring);
2607 if (!malloc_p || alias->get_availability () > AVAIL_INTERPOSABLE)
2608 set_malloc_flag_1 (node: alias, malloc_p, changed);
2609 }
2610
2611 for (cgraph_edge *e = node->callers; e; e = e->next_caller)
2612 if (e->caller->thunk
2613 && (!malloc_p || e->caller->get_availability () > AVAIL_INTERPOSABLE))
2614 set_malloc_flag_1 (node: e->caller, malloc_p, changed);
2615}
2616
2617/* Set DECL_IS_MALLOC on NODE's decl and on NODE's aliases if any. */
2618
2619bool
2620cgraph_node::set_malloc_flag (bool malloc_p)
2621{
2622 bool changed = false;
2623
2624 if (!malloc_p || get_availability () > AVAIL_INTERPOSABLE)
2625 set_malloc_flag_1 (node: this, malloc_p, changed: &changed);
2626 else
2627 {
2628 ipa_ref *ref;
2629
2630 FOR_EACH_ALIAS (this, ref)
2631 {
2632 cgraph_node *alias = dyn_cast<cgraph_node *> (p: ref->referring);
2633 if (!malloc_p || alias->get_availability () > AVAIL_INTERPOSABLE)
2634 set_malloc_flag_1 (node: alias, malloc_p, changed: &changed);
2635 }
2636 }
2637 return changed;
2638}
2639
2640/* Worker to set malloc flag. */
2641static void
2642add_detected_attribute_1 (cgraph_node *node, const char *attr, bool *changed)
2643{
2644 if (!lookup_attribute (attr_name: attr, DECL_ATTRIBUTES (node->decl)))
2645 {
2646 DECL_ATTRIBUTES (node->decl) = tree_cons (get_identifier (attr),
2647 NULL_TREE, DECL_ATTRIBUTES (node->decl));
2648 *changed = true;
2649 }
2650
2651 ipa_ref *ref;
2652 FOR_EACH_ALIAS (node, ref)
2653 {
2654 cgraph_node *alias = dyn_cast<cgraph_node *> (p: ref->referring);
2655 if (alias->get_availability () > AVAIL_INTERPOSABLE)
2656 add_detected_attribute_1 (node: alias, attr, changed);
2657 }
2658
2659 for (cgraph_edge *e = node->callers; e; e = e->next_caller)
2660 if (e->caller->thunk
2661 && (e->caller->get_availability () > AVAIL_INTERPOSABLE))
2662 add_detected_attribute_1 (node: e->caller, attr, changed);
2663}
2664
2665/* Add attribyte ATTR to function and its aliases. */
2666
2667bool
2668cgraph_node::add_detected_attribute (const char *attr)
2669{
2670 bool changed = false;
2671
2672 if (get_availability () > AVAIL_INTERPOSABLE)
2673 add_detected_attribute_1 (node: this, attr, changed: &changed);
2674 else
2675 {
2676 ipa_ref *ref;
2677
2678 FOR_EACH_ALIAS (this, ref)
2679 {
2680 cgraph_node *alias = dyn_cast<cgraph_node *> (p: ref->referring);
2681 if (alias->get_availability () > AVAIL_INTERPOSABLE)
2682 add_detected_attribute_1 (node: alias, attr, changed: &changed);
2683 }
2684 }
2685 return changed;
2686}
2687
2688/* Worker to set noreturng flag. */
2689static void
2690set_noreturn_flag_1 (cgraph_node *node, bool noreturn_p, bool *changed)
2691{
2692 if (noreturn_p && !TREE_THIS_VOLATILE (node->decl))
2693 {
2694 TREE_THIS_VOLATILE (node->decl) = true;
2695 *changed = true;
2696 }
2697
2698 ipa_ref *ref;
2699 FOR_EACH_ALIAS (node, ref)
2700 {
2701 cgraph_node *alias = dyn_cast<cgraph_node *> (p: ref->referring);
2702 if (!noreturn_p || alias->get_availability () > AVAIL_INTERPOSABLE)
2703 set_noreturn_flag_1 (node: alias, noreturn_p, changed);
2704 }
2705
2706 for (cgraph_edge *e = node->callers; e; e = e->next_caller)
2707 if (e->caller->thunk
2708 && (!noreturn_p || e->caller->get_availability () > AVAIL_INTERPOSABLE))
2709 set_noreturn_flag_1 (node: e->caller, noreturn_p, changed);
2710}
2711
2712/* Set TREE_THIS_VOLATILE on NODE's decl and on NODE's aliases if any. */
2713
2714bool
2715cgraph_node::set_noreturn_flag (bool noreturn_p)
2716{
2717 bool changed = false;
2718
2719 if (!noreturn_p || get_availability () > AVAIL_INTERPOSABLE)
2720 set_noreturn_flag_1 (node: this, noreturn_p, changed: &changed);
2721 else
2722 {
2723 ipa_ref *ref;
2724
2725 FOR_EACH_ALIAS (this, ref)
2726 {
2727 cgraph_node *alias = dyn_cast<cgraph_node *> (p: ref->referring);
2728 if (!noreturn_p || alias->get_availability () > AVAIL_INTERPOSABLE)
2729 set_noreturn_flag_1 (node: alias, noreturn_p, changed: &changed);
2730 }
2731 }
2732 return changed;
2733}
2734
2735/* Worker to set_const_flag. */
2736
2737static void
2738set_const_flag_1 (cgraph_node *node, bool set_const, bool looping,
2739 bool *changed)
2740{
2741 /* Static constructors and destructors without a side effect can be
2742 optimized out. */
2743 if (set_const && !looping)
2744 {
2745 if (DECL_STATIC_CONSTRUCTOR (node->decl))
2746 {
2747 DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
2748 *changed = true;
2749 }
2750 if (DECL_STATIC_DESTRUCTOR (node->decl))
2751 {
2752 DECL_STATIC_DESTRUCTOR (node->decl) = 0;
2753 *changed = true;
2754 }
2755 }
2756 if (!set_const)
2757 {
2758 if (TREE_READONLY (node->decl))
2759 {
2760 TREE_READONLY (node->decl) = 0;
2761 DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
2762 *changed = true;
2763 }
2764 }
2765 else
2766 {
2767 /* Consider function:
2768
2769 bool a(int *p)
2770 {
2771 return *p==*p;
2772 }
2773
2774 During early optimization we will turn this into:
2775
2776 bool a(int *p)
2777 {
2778 return true;
2779 }
2780
2781 Now if this function will be detected as CONST however when interposed
2782 it may end up being just pure. We always must assume the worst
2783 scenario here. */
2784 if (TREE_READONLY (node->decl))
2785 {
2786 if (!looping && DECL_LOOPING_CONST_OR_PURE_P (node->decl))
2787 {
2788 DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
2789 *changed = true;
2790 }
2791 }
2792 else if (node->binds_to_current_def_p ())
2793 {
2794 TREE_READONLY (node->decl) = true;
2795 DECL_LOOPING_CONST_OR_PURE_P (node->decl) = looping;
2796 DECL_PURE_P (node->decl) = false;
2797 *changed = true;
2798 }
2799 else
2800 {
2801 if (dump_file && (dump_flags & TDF_DETAILS))
2802 fprintf (stream: dump_file, format: "Dropping state to PURE because function does "
2803 "not bind to current def.\n");
2804 if (!DECL_PURE_P (node->decl))
2805 {
2806 DECL_PURE_P (node->decl) = true;
2807 DECL_LOOPING_CONST_OR_PURE_P (node->decl) = looping;
2808 *changed = true;
2809 }
2810 else if (!looping && DECL_LOOPING_CONST_OR_PURE_P (node->decl))
2811 {
2812 DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
2813 *changed = true;
2814 }
2815 }
2816 }
2817
2818 ipa_ref *ref;
2819 FOR_EACH_ALIAS (node, ref)
2820 {
2821 cgraph_node *alias = dyn_cast <cgraph_node *> (p: ref->referring);
2822 if (!set_const || alias->get_availability () > AVAIL_INTERPOSABLE)
2823 set_const_flag_1 (node: alias, set_const, looping, changed);
2824 }
2825 for (struct cgraph_node *n = node->simd_clones; n != NULL;
2826 n = n->simdclone->next_clone)
2827 set_const_flag_1 (node: n, set_const, looping, changed);
2828 for (cgraph_edge *e = node->callers; e; e = e->next_caller)
2829 if (e->caller->thunk
2830 && (!set_const || e->caller->get_availability () > AVAIL_INTERPOSABLE))
2831 {
2832 /* Virtual thunks access virtual offset in the vtable, so they can
2833 only be pure, never const. */
2834 if (set_const
2835 && (thunk_info::get (node: e->caller)->virtual_offset_p
2836 || !node->binds_to_current_def_p (ref: e->caller)))
2837 *changed |= e->caller->set_pure_flag (pure: true, looping);
2838 else
2839 set_const_flag_1 (node: e->caller, set_const, looping, changed);
2840 }
2841}
2842
2843/* If SET_CONST is true, mark function, aliases and thunks to be ECF_CONST.
2844 If SET_CONST if false, clear the flag.
2845
2846 When setting the flag be careful about possible interposition and
2847 do not set the flag for functions that can be interposed and set pure
2848 flag for functions that can bind to other definition.
2849
2850 Return true if any change was done. */
2851
2852bool
2853cgraph_node::set_const_flag (bool set_const, bool looping)
2854{
2855 bool changed = false;
2856 if (!set_const || get_availability () > AVAIL_INTERPOSABLE)
2857 set_const_flag_1 (node: this, set_const, looping, changed: &changed);
2858 else
2859 {
2860 ipa_ref *ref;
2861
2862 FOR_EACH_ALIAS (this, ref)
2863 {
2864 cgraph_node *alias = dyn_cast <cgraph_node *> (p: ref->referring);
2865 if (!set_const || alias->get_availability () > AVAIL_INTERPOSABLE)
2866 set_const_flag_1 (node: alias, set_const, looping, changed: &changed);
2867 }
2868 }
2869 return changed;
2870}
2871
2872/* Info used by set_pure_flag_1. */
2873
2874struct set_pure_flag_info
2875{
2876 bool pure;
2877 bool looping;
2878 bool changed;
2879};
2880
2881/* Worker to set_pure_flag. */
2882
2883static bool
2884set_pure_flag_1 (cgraph_node *node, void *data)
2885{
2886 struct set_pure_flag_info *info = (struct set_pure_flag_info *)data;
2887 /* Static constructors and destructors without a side effect can be
2888 optimized out. */
2889 if (info->pure && !info->looping)
2890 {
2891 if (DECL_STATIC_CONSTRUCTOR (node->decl))
2892 {
2893 DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
2894 info->changed = true;
2895 }
2896 if (DECL_STATIC_DESTRUCTOR (node->decl))
2897 {
2898 DECL_STATIC_DESTRUCTOR (node->decl) = 0;
2899 info->changed = true;
2900 }
2901 }
2902 if (info->pure)
2903 {
2904 if (!DECL_PURE_P (node->decl) && !TREE_READONLY (node->decl))
2905 {
2906 DECL_PURE_P (node->decl) = true;
2907 DECL_LOOPING_CONST_OR_PURE_P (node->decl) = info->looping;
2908 info->changed = true;
2909 }
2910 else if (DECL_LOOPING_CONST_OR_PURE_P (node->decl)
2911 && !info->looping)
2912 {
2913 DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
2914 info->changed = true;
2915 }
2916 }
2917 else
2918 {
2919 if (DECL_PURE_P (node->decl))
2920 {
2921 DECL_PURE_P (node->decl) = false;
2922 DECL_LOOPING_CONST_OR_PURE_P (node->decl) = false;
2923 info->changed = true;
2924 }
2925 }
2926 return false;
2927}
2928
2929/* Set DECL_PURE_P on cgraph_node's decl and on aliases of the node
2930 if any to PURE.
2931
2932 When setting the flag, be careful about possible interposition.
2933 Return true if any change was done. */
2934
2935bool
2936cgraph_node::set_pure_flag (bool pure, bool looping)
2937{
2938 struct set_pure_flag_info info = {.pure: pure, .looping: looping, .changed: false};
2939 call_for_symbol_thunks_and_aliases (callback: set_pure_flag_1, data: &info, include_overwritable: !pure, exclude_virtual_thunks: true);
2940 for (struct cgraph_node *n = simd_clones; n != NULL;
2941 n = n->simdclone->next_clone)
2942 set_pure_flag_1 (node: n, data: &info);
2943 return info.changed;
2944}
2945
2946/* Return true when cgraph_node cannot return or throw and thus
2947 it is safe to ignore its side effects for IPA analysis. */
2948
2949bool
2950cgraph_node::cannot_return_p (void)
2951{
2952 int flags = flags_from_decl_or_type (decl);
2953 if (!opt_for_fn (decl, flag_exceptions))
2954 return (flags & ECF_NORETURN) != 0;
2955 else
2956 return ((flags & (ECF_NORETURN | ECF_NOTHROW))
2957 == (ECF_NORETURN | ECF_NOTHROW));
2958}
2959
2960/* Return true when call of edge cannot lead to return from caller
2961 and thus it is safe to ignore its side effects for IPA analysis
2962 when computing side effects of the caller.
2963 FIXME: We could actually mark all edges that have no reaching
2964 patch to the exit block or throw to get better results. */
2965bool
2966cgraph_edge::cannot_lead_to_return_p (void)
2967{
2968 if (caller->cannot_return_p ())
2969 return true;
2970 if (indirect_unknown_callee)
2971 {
2972 int flags = indirect_info->ecf_flags;
2973 if (!opt_for_fn (caller->decl, flag_exceptions))
2974 return (flags & ECF_NORETURN) != 0;
2975 else
2976 return ((flags & (ECF_NORETURN | ECF_NOTHROW))
2977 == (ECF_NORETURN | ECF_NOTHROW));
2978 }
2979 else
2980 return callee->cannot_return_p ();
2981}
2982
2983/* Return true if the edge may be considered hot. */
2984
2985bool
2986cgraph_edge::maybe_hot_p (void)
2987{
2988 if (!maybe_hot_count_p (NULL, count.ipa ()))
2989 return false;
2990 if (caller->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
2991 || (callee
2992 && callee->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED))
2993 return false;
2994 if (caller->frequency > NODE_FREQUENCY_UNLIKELY_EXECUTED
2995 && (callee
2996 && callee->frequency <= NODE_FREQUENCY_EXECUTED_ONCE))
2997 return false;
2998 if (opt_for_fn (caller->decl, optimize_size))
2999 return false;
3000 if (caller->frequency == NODE_FREQUENCY_HOT)
3001 return true;
3002 if (!count.initialized_p ())
3003 return true;
3004 cgraph_node *where = caller->inlined_to ? caller->inlined_to : caller;
3005 if (!where->count.initialized_p ())
3006 return false;
3007 if (caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE)
3008 {
3009 if (count * 2 < where->count * 3)
3010 return false;
3011 }
3012 else if (count * param_hot_bb_frequency_fraction < where->count)
3013 return false;
3014 return true;
3015}
3016
3017/* Worker for cgraph_can_remove_if_no_direct_calls_p. */
3018
3019static bool
3020nonremovable_p (cgraph_node *node, void *)
3021{
3022 return !node->can_remove_if_no_direct_calls_and_refs_p ();
3023}
3024
3025/* Return true if whole comdat group can be removed if there are no direct
3026 calls to THIS. */
3027
3028bool
3029cgraph_node::can_remove_if_no_direct_calls_p (bool will_inline)
3030{
3031 struct ipa_ref *ref;
3032
3033 /* For local symbols or non-comdat group it is the same as
3034 can_remove_if_no_direct_calls_p. */
3035 if (!externally_visible || !same_comdat_group)
3036 {
3037 if (DECL_EXTERNAL (decl))
3038 return true;
3039 if (address_taken)
3040 return false;
3041 return !call_for_symbol_and_aliases (callback: nonremovable_p, NULL, include_overwritable: true);
3042 }
3043
3044 if (will_inline && address_taken)
3045 return false;
3046
3047 /* Otherwise check if we can remove the symbol itself and then verify
3048 that only uses of the comdat groups are direct call to THIS
3049 or its aliases. */
3050 if (!can_remove_if_no_direct_calls_and_refs_p ())
3051 return false;
3052
3053 /* Check that all refs come from within the comdat group. */
3054 for (int i = 0; iterate_referring (i, ref); i++)
3055 if (ref->referring->get_comdat_group () != get_comdat_group ())
3056 return false;
3057
3058 struct cgraph_node *target = ultimate_alias_target ();
3059 for (cgraph_node *next = dyn_cast<cgraph_node *> (p: same_comdat_group);
3060 next != this; next = dyn_cast<cgraph_node *> (p: next->same_comdat_group))
3061 {
3062 if (!externally_visible)
3063 continue;
3064 if (!next->alias
3065 && !next->can_remove_if_no_direct_calls_and_refs_p ())
3066 return false;
3067
3068 /* If we see different symbol than THIS, be sure to check calls. */
3069 if (next->ultimate_alias_target () != target)
3070 for (cgraph_edge *e = next->callers; e; e = e->next_caller)
3071 if (e->caller->get_comdat_group () != get_comdat_group ()
3072 || will_inline)
3073 return false;
3074
3075 /* If function is not being inlined, we care only about
3076 references outside of the comdat group. */
3077 if (!will_inline)
3078 for (int i = 0; next->iterate_referring (i, ref); i++)
3079 if (ref->referring->get_comdat_group () != get_comdat_group ())
3080 return false;
3081 }
3082 return true;
3083}
3084
3085/* Return true when function cgraph_node can be expected to be removed
3086 from program when direct calls in this compilation unit are removed.
3087
3088 As a special case COMDAT functions are
3089 cgraph_can_remove_if_no_direct_calls_p while the are not
3090 cgraph_only_called_directly_p (it is possible they are called from other
3091 unit)
3092
3093 This function behaves as cgraph_only_called_directly_p because eliminating
3094 all uses of COMDAT function does not make it necessarily disappear from
3095 the program unless we are compiling whole program or we do LTO. In this
3096 case we know we win since dynamic linking will not really discard the
3097 linkonce section. */
3098
3099bool
3100cgraph_node::will_be_removed_from_program_if_no_direct_calls_p
3101 (bool will_inline)
3102{
3103 gcc_assert (!inlined_to);
3104 if (DECL_EXTERNAL (decl))
3105 return true;
3106
3107 if (!in_lto_p && !flag_whole_program)
3108 {
3109 /* If the symbol is in comdat group, we need to verify that whole comdat
3110 group becomes unreachable. Technically we could skip references from
3111 within the group, too. */
3112 if (!only_called_directly_p ())
3113 return false;
3114 if (same_comdat_group && externally_visible)
3115 {
3116 struct cgraph_node *target = ultimate_alias_target ();
3117
3118 if (will_inline && address_taken)
3119 return true;
3120 for (cgraph_node *next = dyn_cast<cgraph_node *> (p: same_comdat_group);
3121 next != this;
3122 next = dyn_cast<cgraph_node *> (p: next->same_comdat_group))
3123 {
3124 if (!externally_visible)
3125 continue;
3126 if (!next->alias
3127 && !next->only_called_directly_p ())
3128 return false;
3129
3130 /* If we see different symbol than THIS,
3131 be sure to check calls. */
3132 if (next->ultimate_alias_target () != target)
3133 for (cgraph_edge *e = next->callers; e; e = e->next_caller)
3134 if (e->caller->get_comdat_group () != get_comdat_group ()
3135 || will_inline)
3136 return false;
3137 }
3138 }
3139 return true;
3140 }
3141 else
3142 return can_remove_if_no_direct_calls_p (will_inline);
3143}
3144
3145
3146/* Worker for cgraph_only_called_directly_p. */
3147
3148static bool
3149cgraph_not_only_called_directly_p_1 (cgraph_node *node, void *)
3150{
3151 return !node->only_called_directly_or_aliased_p ();
3152}
3153
3154/* Return true when function cgraph_node and all its aliases are only called
3155 directly.
3156 i.e. it is not externally visible, address was not taken and
3157 it is not used in any other non-standard way. */
3158
3159bool
3160cgraph_node::only_called_directly_p (void)
3161{
3162 gcc_assert (ultimate_alias_target () == this);
3163 return !call_for_symbol_and_aliases (callback: cgraph_not_only_called_directly_p_1,
3164 NULL, include_overwritable: true);
3165}
3166
3167
3168/* Collect all callers of NODE. Worker for collect_callers_of_node. */
3169
3170static bool
3171collect_callers_of_node_1 (cgraph_node *node, void *data)
3172{
3173 vec<cgraph_edge *> *redirect_callers = (vec<cgraph_edge *> *)data;
3174 cgraph_edge *cs;
3175 enum availability avail;
3176 node->ultimate_alias_target (availability: &avail);
3177
3178 if (avail > AVAIL_INTERPOSABLE)
3179 for (cs = node->callers; cs != NULL; cs = cs->next_caller)
3180 if (!cs->indirect_inlining_edge
3181 && !cs->caller->thunk)
3182 redirect_callers->safe_push (obj: cs);
3183 return false;
3184}
3185
3186/* Collect all callers of cgraph_node and its aliases that are known to lead to
3187 cgraph_node (i.e. are not overwritable). */
3188
3189auto_vec<cgraph_edge *>
3190cgraph_node::collect_callers (void)
3191{
3192 auto_vec<cgraph_edge *> redirect_callers;
3193 call_for_symbol_thunks_and_aliases (callback: collect_callers_of_node_1,
3194 data: &redirect_callers, include_overwritable: false);
3195 return redirect_callers;
3196}
3197
3198
3199/* Return TRUE if NODE2 a clone of NODE or is equivalent to it. Return
3200 optimistically true if this cannot be determined. */
3201
3202static bool
3203clone_of_p (cgraph_node *node, cgraph_node *node2)
3204{
3205 node = node->ultimate_alias_target ();
3206 node2 = node2->ultimate_alias_target ();
3207
3208 if (node2->clone_of == node
3209 || node2->former_clone_of == node->decl)
3210 return true;
3211
3212 if (!node->thunk && !node->former_thunk_p ())
3213 {
3214 while (node2
3215 && node->decl != node2->decl
3216 && node->decl != node2->former_clone_of)
3217 node2 = node2->clone_of;
3218 return node2 != NULL;
3219 }
3220
3221 /* There are no virtual clones of thunks so check former_clone_of or if we
3222 might have skipped thunks because this adjustments are no longer
3223 necessary. */
3224 while (node->thunk || node->former_thunk_p ())
3225 {
3226 if (!thunk_info::get (node)->this_adjusting)
3227 return false;
3228 /* In case of instrumented expanded thunks, which can have multiple calls
3229 in them, we do not know how to continue and just have to be
3230 optimistic. The same applies if all calls have already been inlined
3231 into the thunk. */
3232 if (!node->callees || node->callees->next_callee)
3233 return true;
3234 node = node->callees->callee->ultimate_alias_target ();
3235
3236 clone_info *info = clone_info::get (node: node2);
3237 if (!info || !info->param_adjustments
3238 || info->param_adjustments->first_param_intact_p ())
3239 return false;
3240 if (node2->former_clone_of == node->decl
3241 || node2->former_clone_of == node->former_clone_of)
3242 return true;
3243
3244 cgraph_node *n2 = node2;
3245 while (n2 && node->decl != n2->decl)
3246 n2 = n2->clone_of;
3247 if (n2)
3248 return true;
3249 }
3250
3251 return false;
3252}
3253
3254/* Verify edge count and frequency. */
3255
3256bool
3257cgraph_edge::verify_count ()
3258{
3259 bool error_found = false;
3260 if (!count.verify ())
3261 {
3262 error ("caller edge count invalid");
3263 error_found = true;
3264 }
3265 return error_found;
3266}
3267
3268/* Switch to THIS_CFUN if needed and print STMT to stderr. */
3269static void
3270cgraph_debug_gimple_stmt (function *this_cfun, gimple *stmt)
3271{
3272 bool fndecl_was_null = false;
3273 /* debug_gimple_stmt needs correct cfun */
3274 if (cfun != this_cfun)
3275 set_cfun (new_cfun: this_cfun);
3276 /* ...and an actual current_function_decl */
3277 if (!current_function_decl)
3278 {
3279 current_function_decl = this_cfun->decl;
3280 fndecl_was_null = true;
3281 }
3282 debug_gimple_stmt (stmt);
3283 if (fndecl_was_null)
3284 current_function_decl = NULL;
3285}
3286
3287/* Verify that call graph edge corresponds to DECL from the associated
3288 statement. Return true if the verification should fail. */
3289
3290bool
3291cgraph_edge::verify_corresponds_to_fndecl (tree decl)
3292{
3293 cgraph_node *node;
3294
3295 if (!decl || callee->inlined_to)
3296 return false;
3297 if (symtab->state == LTO_STREAMING)
3298 return false;
3299 node = cgraph_node::get (decl);
3300
3301 /* We do not know if a node from a different partition is an alias or what it
3302 aliases and therefore cannot do the former_clone_of check reliably. When
3303 body_removed is set, we have lost all information about what was alias or
3304 thunk of and also cannot proceed. */
3305 if (!node
3306 || node->body_removed
3307 || node->in_other_partition
3308 || callee->icf_merged
3309 || callee->in_other_partition)
3310 return false;
3311
3312 node = node->ultimate_alias_target ();
3313
3314 /* Optimizers can redirect unreachable calls or calls triggering undefined
3315 behavior to __builtin_unreachable or __builtin_unreachable trap. */
3316
3317 if (fndecl_built_in_p (node: callee->decl, name1: BUILT_IN_UNREACHABLE,
3318 names: BUILT_IN_UNREACHABLE_TRAP))
3319 return false;
3320
3321 if (callee->former_clone_of != node->decl
3322 && (node != callee->ultimate_alias_target ())
3323 && !clone_of_p (node, node2: callee))
3324 return true;
3325 else
3326 return false;
3327}
3328
3329/* Disable warnings about missing quoting in GCC diagnostics for
3330 the verification errors. Their format strings don't follow GCC
3331 diagnostic conventions and the calls are ultimately followed by
3332 one to internal_error. */
3333#if __GNUC__ >= 10
3334# pragma GCC diagnostic push
3335# pragma GCC diagnostic ignored "-Wformat-diag"
3336#endif
3337
3338/* Verify consistency of speculative call in NODE corresponding to STMT
3339 and LTO_STMT_UID. If INDIRECT is set, assume that it is the indirect
3340 edge of call sequence. Return true if error is found.
3341
3342 This function is called to every component of indirect call (direct edges,
3343 indirect edge and refs). To save duplicated work, do full testing only
3344 in that case. */
3345static bool
3346verify_speculative_call (struct cgraph_node *node, gimple *stmt,
3347 unsigned int lto_stmt_uid,
3348 struct cgraph_edge *indirect)
3349{
3350 if (indirect == NULL)
3351 {
3352 for (indirect = node->indirect_calls; indirect;
3353 indirect = indirect->next_callee)
3354 if (indirect->call_stmt == stmt
3355 && indirect->lto_stmt_uid == lto_stmt_uid)
3356 break;
3357 if (!indirect)
3358 {
3359 error ("missing indirect call in speculative call sequence");
3360 return true;
3361 }
3362 if (!indirect->speculative)
3363 {
3364 error ("indirect call in speculative call sequence has no "
3365 "speculative flag");
3366 return true;
3367 }
3368 return false;
3369 }
3370
3371 /* Maximal number of targets. We probably will never want to have more than
3372 this. */
3373 const unsigned int num = 256;
3374 cgraph_edge *direct_calls[num];
3375 ipa_ref *refs[num];
3376
3377 for (unsigned int i = 0; i < num; i++)
3378 {
3379 direct_calls[i] = NULL;
3380 refs[i] = NULL;
3381 }
3382
3383 cgraph_edge *first_call = NULL;
3384 cgraph_edge *prev_call = NULL;
3385
3386 for (cgraph_edge *direct = node->callees; direct;
3387 direct = direct->next_callee)
3388 if (direct->call_stmt == stmt && direct->lto_stmt_uid == lto_stmt_uid)
3389 {
3390 if (!first_call)
3391 first_call = direct;
3392 if (prev_call && direct != prev_call->next_callee)
3393 {
3394 error ("speculative edges are not adjacent");
3395 return true;
3396 }
3397 prev_call = direct;
3398 if (!direct->speculative)
3399 {
3400 error ("direct call to %s in speculative call sequence has no "
3401 "speculative flag", direct->callee->dump_name ());
3402 return true;
3403 }
3404 if (direct->speculative_id >= num)
3405 {
3406 error ("direct call to %s in speculative call sequence has "
3407 "speculative_id %i out of range",
3408 direct->callee->dump_name (), direct->speculative_id);
3409 return true;
3410 }
3411 if (direct_calls[direct->speculative_id])
3412 {
3413 error ("duplicate direct call to %s in speculative call sequence "
3414 "with speculative_id %i",
3415 direct->callee->dump_name (), direct->speculative_id);
3416 return true;
3417 }
3418 direct_calls[direct->speculative_id] = direct;
3419 }
3420
3421 if (first_call->call_stmt
3422 && first_call != node->get_edge (call_stmt: first_call->call_stmt))
3423 {
3424 error ("call stmt hash does not point to first direct edge of "
3425 "speculative call sequence");
3426 return true;
3427 }
3428
3429 ipa_ref *ref;
3430 for (int i = 0; node->iterate_reference (i, ref); i++)
3431 if (ref->speculative
3432 && ref->stmt == stmt && ref->lto_stmt_uid == lto_stmt_uid)
3433 {
3434 if (ref->speculative_id >= num)
3435 {
3436 error ("direct call to %s in speculative call sequence has "
3437 "speculative_id %i out of range",
3438 ref->referred->dump_name (), ref->speculative_id);
3439 return true;
3440 }
3441 if (refs[ref->speculative_id])
3442 {
3443 error ("duplicate reference %s in speculative call sequence "
3444 "with speculative_id %i",
3445 ref->referred->dump_name (), ref->speculative_id);
3446 return true;
3447 }
3448 refs[ref->speculative_id] = ref;
3449 }
3450
3451 int num_targets = 0;
3452 for (unsigned int i = 0 ; i < num ; i++)
3453 {
3454 if (refs[i] && !direct_calls[i])
3455 {
3456 error ("missing direct call for speculation %i", i);
3457 return true;
3458 }
3459 if (!refs[i] && direct_calls[i])
3460 {
3461 error ("missing ref for speculation %i", i);
3462 return true;
3463 }
3464 if (refs[i] != NULL)
3465 num_targets++;
3466 }
3467
3468 if (num_targets != indirect->num_speculative_call_targets_p ())
3469 {
3470 error ("number of speculative targets %i mismatched with "
3471 "num_speculative_call_targets %i",
3472 num_targets,
3473 indirect->num_speculative_call_targets_p ());
3474 return true;
3475 }
3476 return false;
3477}
3478
3479/* Verify cgraph nodes of given cgraph node. */
3480DEBUG_FUNCTION void
3481cgraph_node::verify_node (void)
3482{
3483 cgraph_edge *e;
3484 function *this_cfun = DECL_STRUCT_FUNCTION (decl);
3485 basic_block this_block;
3486 gimple_stmt_iterator gsi;
3487 bool error_found = false;
3488 int i;
3489 ipa_ref *ref = NULL;
3490
3491 if (seen_error ())
3492 return;
3493
3494 timevar_push (tv: TV_CGRAPH_VERIFY);
3495 error_found |= verify_base ();
3496 for (e = callees; e; e = e->next_callee)
3497 if (e->aux)
3498 {
3499 error ("aux field set for edge %s->%s",
3500 identifier_to_locale (e->caller->name ()),
3501 identifier_to_locale (e->callee->name ()));
3502 error_found = true;
3503 }
3504 if (!count.verify ())
3505 {
3506 error ("cgraph count invalid");
3507 error_found = true;
3508 }
3509 if (inlined_to && same_comdat_group)
3510 {
3511 error ("inline clone in same comdat group list");
3512 error_found = true;
3513 }
3514 if (inlined_to && !count.compatible_p (other: inlined_to->count))
3515 {
3516 error ("inline clone count is not compatible");
3517 count.debug ();
3518 inlined_to->count.debug ();
3519 error_found = true;
3520 }
3521 if (tp_first_run < 0)
3522 {
3523 error ("tp_first_run must be non-negative");
3524 error_found = true;
3525 }
3526 if (!definition && !in_other_partition && local)
3527 {
3528 error ("local symbols must be defined");
3529 error_found = true;
3530 }
3531 if (inlined_to && externally_visible)
3532 {
3533 error ("externally visible inline clone");
3534 error_found = true;
3535 }
3536 if (inlined_to && address_taken)
3537 {
3538 error ("inline clone with address taken");
3539 error_found = true;
3540 }
3541 if (inlined_to && force_output)
3542 {
3543 error ("inline clone is forced to output");
3544 error_found = true;
3545 }
3546 if (symtab->state != LTO_STREAMING)
3547 {
3548 if (calls_comdat_local && !same_comdat_group)
3549 {
3550 error ("calls_comdat_local is set outside of a comdat group");
3551 error_found = true;
3552 }
3553 if (!inlined_to && calls_comdat_local != check_calls_comdat_local_p ())
3554 {
3555 error ("invalid calls_comdat_local flag");
3556 error_found = true;
3557 }
3558 }
3559 if (DECL_IS_MALLOC (decl)
3560 && !POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
3561 {
3562 error ("malloc attribute should be used for a function that "
3563 "returns a pointer");
3564 error_found = true;
3565 }
3566 if (definition
3567 && externally_visible
3568 /* For aliases in lto1 free_lang_data doesn't guarantee preservation
3569 of opt_for_fn (decl, flag_semantic_interposition). See PR105399. */
3570 && (!alias || !in_lto_p)
3571 && semantic_interposition
3572 != opt_for_fn (decl, flag_semantic_interposition))
3573 {
3574 error ("semantic interposition mismatch");
3575 error_found = true;
3576 }
3577 for (e = indirect_calls; e; e = e->next_callee)
3578 {
3579 if (e->aux)
3580 {
3581 error ("aux field set for indirect edge from %s",
3582 identifier_to_locale (e->caller->name ()));
3583 error_found = true;
3584 }
3585 if (!e->count.compatible_p (other: count))
3586 {
3587 error ("edge count is not compatible with function count");
3588 e->count.debug ();
3589 count.debug ();
3590 error_found = true;
3591 }
3592 if (!e->indirect_unknown_callee
3593 || !e->indirect_info)
3594 {
3595 error ("An indirect edge from %s is not marked as indirect or has "
3596 "associated indirect_info, the corresponding statement is: ",
3597 identifier_to_locale (e->caller->name ()));
3598 cgraph_debug_gimple_stmt (this_cfun, stmt: e->call_stmt);
3599 error_found = true;
3600 }
3601 if (e->call_stmt && e->lto_stmt_uid)
3602 {
3603 error ("edge has both call_stmt and lto_stmt_uid set");
3604 error_found = true;
3605 }
3606 }
3607 bool check_comdat = comdat_local_p ();
3608 for (e = callers; e; e = e->next_caller)
3609 {
3610 if (e->verify_count ())
3611 error_found = true;
3612 if (check_comdat
3613 && !in_same_comdat_group_p (target: e->caller))
3614 {
3615 error ("comdat-local function called by %s outside its comdat",
3616 identifier_to_locale (e->caller->name ()));
3617 error_found = true;
3618 }
3619 if (!e->inline_failed)
3620 {
3621 if (inlined_to
3622 != (e->caller->inlined_to
3623 ? e->caller->inlined_to : e->caller))
3624 {
3625 error ("inlined_to pointer is wrong");
3626 error_found = true;
3627 }
3628 if (callers->next_caller)
3629 {
3630 error ("multiple inline callers");
3631 error_found = true;
3632 }
3633 }
3634 else
3635 if (inlined_to)
3636 {
3637 error ("inlined_to pointer set for noninline callers");
3638 error_found = true;
3639 }
3640 }
3641 for (e = callees; e; e = e->next_callee)
3642 {
3643 if (e->verify_count ())
3644 error_found = true;
3645 if (!e->count.compatible_p (other: count))
3646 {
3647 error ("edge count is not compatible with function count");
3648 e->count.debug ();
3649 count.debug ();
3650 error_found = true;
3651 }
3652 if (gimple_has_body_p (e->caller->decl)
3653 && !e->caller->inlined_to
3654 && !e->speculative
3655 /* Optimized out calls are redirected to __builtin_unreachable. */
3656 && (e->count.nonzero_p ()
3657 || ! e->callee->decl
3658 || !fndecl_built_in_p (node: e->callee->decl, name1: BUILT_IN_UNREACHABLE,
3659 names: BUILT_IN_UNREACHABLE_TRAP))
3660 && count
3661 == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count
3662 && (!e->count.ipa_p ()
3663 && e->count.differs_from_p (other: gimple_bb (g: e->call_stmt)->count)))
3664 {
3665 error ("caller edge count does not match BB count");
3666 fprintf (stderr, format: "edge count: ");
3667 e->count.dump (stderr);
3668 fprintf (stderr, format: "\n bb count: ");
3669 gimple_bb (g: e->call_stmt)->count.dump (stderr);
3670 fprintf (stderr, format: "\n");
3671 error_found = true;
3672 }
3673 if (e->call_stmt && e->lto_stmt_uid)
3674 {
3675 error ("edge has both call_stmt and lto_stmt_uid set");
3676 error_found = true;
3677 }
3678 if (e->speculative
3679 && verify_speculative_call (node: e->caller, stmt: e->call_stmt, lto_stmt_uid: e->lto_stmt_uid,
3680 NULL))
3681 error_found = true;
3682 }
3683 for (e = indirect_calls; e; e = e->next_callee)
3684 {
3685 if (e->verify_count ())
3686 error_found = true;
3687 if (gimple_has_body_p (e->caller->decl)
3688 && !e->caller->inlined_to
3689 && !e->speculative
3690 && e->count.ipa_p ()
3691 && count
3692 == ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (decl))->count
3693 && (!e->count.ipa_p ()
3694 && e->count.differs_from_p (other: gimple_bb (g: e->call_stmt)->count)))
3695 {
3696 error ("indirect call count does not match BB count");
3697 fprintf (stderr, format: "edge count: ");
3698 e->count.dump (stderr);
3699 fprintf (stderr, format: "\n bb count: ");
3700 gimple_bb (g: e->call_stmt)->count.dump (stderr);
3701 fprintf (stderr, format: "\n");
3702 error_found = true;
3703 }
3704 if (e->speculative
3705 && verify_speculative_call (node: e->caller, stmt: e->call_stmt, lto_stmt_uid: e->lto_stmt_uid,
3706 indirect: e))
3707 error_found = true;
3708 }
3709 for (i = 0; iterate_reference (i, ref); i++)
3710 {
3711 if (ref->stmt && ref->lto_stmt_uid)
3712 {
3713 error ("reference has both stmt and lto_stmt_uid set");
3714 error_found = true;
3715 }
3716 if (ref->speculative
3717 && verify_speculative_call (node: this, stmt: ref->stmt,
3718 lto_stmt_uid: ref->lto_stmt_uid, NULL))
3719 error_found = true;
3720 }
3721
3722 if (!callers && inlined_to)
3723 {
3724 error ("inlined_to pointer is set but no predecessors found");
3725 error_found = true;
3726 }
3727 if (inlined_to == this)
3728 {
3729 error ("inlined_to pointer refers to itself");
3730 error_found = true;
3731 }
3732
3733 if (clone_of)
3734 {
3735 cgraph_node *first_clone = clone_of->clones;
3736 if (first_clone != this)
3737 {
3738 if (prev_sibling_clone->clone_of != clone_of)
3739 {
3740 error ("cgraph_node has wrong clone_of");
3741 error_found = true;
3742 }
3743 }
3744 }
3745 if (clones)
3746 {
3747 cgraph_node *n;
3748 for (n = clones; n; n = n->next_sibling_clone)
3749 if (n->clone_of != this)
3750 break;
3751 if (n)
3752 {
3753 error ("cgraph_node has wrong clone list");
3754 error_found = true;
3755 }
3756 }
3757 if ((prev_sibling_clone || next_sibling_clone) && !clone_of)
3758 {
3759 error ("cgraph_node is in clone list but it is not clone");
3760 error_found = true;
3761 }
3762 if (!prev_sibling_clone && clone_of && clone_of->clones != this)
3763 {
3764 error ("cgraph_node has wrong prev_clone pointer");
3765 error_found = true;
3766 }
3767 if (prev_sibling_clone && prev_sibling_clone->next_sibling_clone != this)
3768 {
3769 error ("double linked list of clones corrupted");
3770 error_found = true;
3771 }
3772
3773 if (analyzed && alias)
3774 {
3775 bool ref_found = false;
3776 int i;
3777 ipa_ref *ref = NULL;
3778
3779 if (callees)
3780 {
3781 error ("Alias has call edges");
3782 error_found = true;
3783 }
3784 for (i = 0; iterate_reference (i, ref); i++)
3785 if (ref->use != IPA_REF_ALIAS)
3786 {
3787 error ("Alias has non-alias reference");
3788 error_found = true;
3789 }
3790 else if (ref_found)
3791 {
3792 error ("Alias has more than one alias reference");
3793 error_found = true;
3794 }
3795 else
3796 ref_found = true;
3797 if (!ref_found)
3798 {
3799 error ("Analyzed alias has no reference");
3800 error_found = true;
3801 }
3802 }
3803
3804 if (analyzed && thunk)
3805 {
3806 if (!callees)
3807 {
3808 error ("No edge out of thunk node");
3809 error_found = true;
3810 }
3811 else if (callees->next_callee)
3812 {
3813 error ("More than one edge out of thunk node");
3814 error_found = true;
3815 }
3816 if (gimple_has_body_p (decl) && !inlined_to)
3817 {
3818 error ("Thunk is not supposed to have body");
3819 error_found = true;
3820 }
3821 }
3822 else if (analyzed && gimple_has_body_p (decl)
3823 && !TREE_ASM_WRITTEN (decl)
3824 && (!DECL_EXTERNAL (decl) || inlined_to)
3825 && !flag_wpa)
3826 {
3827 if ((this_cfun->curr_properties & PROP_assumptions_done) != 0)
3828 ;
3829 else if (this_cfun->cfg)
3830 {
3831 hash_set<gimple *> stmts;
3832
3833 /* Reach the trees by walking over the CFG, and note the
3834 enclosing basic-blocks in the call edges. */
3835 FOR_EACH_BB_FN (this_block, this_cfun)
3836 {
3837 for (gsi = gsi_start_phis (this_block);
3838 !gsi_end_p (i: gsi); gsi_next (i: &gsi))
3839 stmts.add (k: gsi_stmt (i: gsi));
3840 for (gsi = gsi_start_bb (bb: this_block);
3841 !gsi_end_p (i: gsi);
3842 gsi_next (i: &gsi))
3843 {
3844 gimple *stmt = gsi_stmt (i: gsi);
3845 stmts.add (k: stmt);
3846 if (is_gimple_call (gs: stmt))
3847 {
3848 cgraph_edge *e = get_edge (call_stmt: stmt);
3849 tree decl = gimple_call_fndecl (gs: stmt);
3850 if (e)
3851 {
3852 if (e->aux)
3853 {
3854 error ("shared call_stmt:");
3855 cgraph_debug_gimple_stmt (this_cfun, stmt);
3856 error_found = true;
3857 }
3858 if (!e->indirect_unknown_callee)
3859 {
3860 if (e->verify_corresponds_to_fndecl (decl))
3861 {
3862 error ("edge points to wrong declaration:");
3863 debug_tree (e->callee->decl);
3864 fprintf (stderr,format: " Instead of:");
3865 debug_tree (decl);
3866 error_found = true;
3867 }
3868 }
3869 else if (decl)
3870 {
3871 error ("an indirect edge with unknown callee "
3872 "corresponding to a call_stmt with "
3873 "a known declaration:");
3874 error_found = true;
3875 cgraph_debug_gimple_stmt (this_cfun, stmt: e->call_stmt);
3876 }
3877 e->aux = (void *)1;
3878 }
3879 else if (decl)
3880 {
3881 error ("missing callgraph edge for call stmt:");
3882 cgraph_debug_gimple_stmt (this_cfun, stmt);
3883 error_found = true;
3884 }
3885 }
3886 }
3887 }
3888 for (i = 0; iterate_reference (i, ref); i++)
3889 if (ref->stmt && !stmts.contains (k: ref->stmt))
3890 {
3891 error ("reference to dead statement");
3892 cgraph_debug_gimple_stmt (this_cfun, stmt: ref->stmt);
3893 error_found = true;
3894 }
3895 }
3896 else
3897 /* No CFG available?! */
3898 gcc_unreachable ();
3899
3900 for (e = callees; e; e = e->next_callee)
3901 {
3902 if (!e->aux && !e->speculative)
3903 {
3904 error ("edge %s->%s has no corresponding call_stmt",
3905 identifier_to_locale (e->caller->name ()),
3906 identifier_to_locale (e->callee->name ()));
3907 cgraph_debug_gimple_stmt (this_cfun, stmt: e->call_stmt);
3908 error_found = true;
3909 }
3910 e->aux = 0;
3911 }
3912 for (e = indirect_calls; e; e = e->next_callee)
3913 {
3914 if (!e->aux && !e->speculative)
3915 {
3916 error ("an indirect edge from %s has no corresponding call_stmt",
3917 identifier_to_locale (e->caller->name ()));
3918 cgraph_debug_gimple_stmt (this_cfun, stmt: e->call_stmt);
3919 error_found = true;
3920 }
3921 e->aux = 0;
3922 }
3923 }
3924
3925 if (nested_function_info *info = nested_function_info::get (node: this))
3926 {
3927 if (info->nested != NULL)
3928 {
3929 for (cgraph_node *n = info->nested; n != NULL;
3930 n = next_nested_function (node: n))
3931 {
3932 nested_function_info *ninfo = nested_function_info::get (node: n);
3933 if (ninfo->origin == NULL)
3934 {
3935 error ("missing origin for a node in a nested list");
3936 error_found = true;
3937 }
3938 else if (ninfo->origin != this)
3939 {
3940 error ("origin points to a different parent");
3941 error_found = true;
3942 break;
3943 }
3944 }
3945 }
3946 if (info->next_nested != NULL && info->origin == NULL)
3947 {
3948 error ("missing origin for a node in a nested list");
3949 error_found = true;
3950 }
3951 }
3952
3953 if (error_found)
3954 {
3955 dump (stderr);
3956 internal_error ("verify_cgraph_node failed");
3957 }
3958 timevar_pop (tv: TV_CGRAPH_VERIFY);
3959}
3960
3961/* Verify whole cgraph structure. */
3962DEBUG_FUNCTION void
3963cgraph_node::verify_cgraph_nodes (void)
3964{
3965 cgraph_node *node;
3966
3967 if (seen_error ())
3968 return;
3969
3970 FOR_EACH_FUNCTION (node)
3971 node->verify ();
3972}
3973
3974#if __GNUC__ >= 10
3975# pragma GCC diagnostic pop
3976#endif
3977
3978/* Walk the alias chain to return the function cgraph_node is alias of.
3979 Walk through thunks, too.
3980 When AVAILABILITY is non-NULL, get minimal availability in the chain.
3981 When REF is non-NULL, assume that reference happens in symbol REF
3982 when determining the availability. */
3983
3984cgraph_node *
3985cgraph_node::function_symbol (enum availability *availability,
3986 struct symtab_node *ref)
3987{
3988 cgraph_node *node = ultimate_alias_target (availability, ref);
3989
3990 while (node->thunk)
3991 {
3992 enum availability a;
3993
3994 ref = node;
3995 node = node->callees->callee;
3996 node = node->ultimate_alias_target (availability: availability ? &a : NULL, ref);
3997 if (availability && a < *availability)
3998 *availability = a;
3999 }
4000 return node;
4001}
4002
4003/* Walk the alias chain to return the function cgraph_node is alias of.
4004 Walk through non virtual thunks, too. Thus we return either a function
4005 or a virtual thunk node.
4006 When AVAILABILITY is non-NULL, get minimal availability in the chain.
4007 When REF is non-NULL, assume that reference happens in symbol REF
4008 when determining the availability. */
4009
4010cgraph_node *
4011cgraph_node::function_or_virtual_thunk_symbol
4012 (enum availability *availability,
4013 struct symtab_node *ref)
4014{
4015 cgraph_node *node = ultimate_alias_target (availability, ref);
4016
4017 while (node->thunk && !thunk_info::get (node)->virtual_offset_p)
4018 {
4019 enum availability a;
4020
4021 ref = node;
4022 node = node->callees->callee;
4023 node = node->ultimate_alias_target (availability: availability ? &a : NULL, ref);
4024 if (availability && a < *availability)
4025 *availability = a;
4026 }
4027 return node;
4028}
4029
4030/* When doing LTO, read cgraph_node's body from disk if it is not already
4031 present. Also perform any necessary clone materializations. */
4032
4033bool
4034cgraph_node::get_untransformed_body ()
4035{
4036 lto_file_decl_data *file_data;
4037 const char *data, *name;
4038 size_t len;
4039 tree decl = this->decl;
4040
4041 /* See if there is clone to be materialized.
4042 (inline clones does not need materialization, but we can be seeing
4043 an inline clone of real clone). */
4044 cgraph_node *p = this;
4045 for (cgraph_node *c = clone_of; c; c = c->clone_of)
4046 {
4047 if (c->decl != decl)
4048 p->materialize_clone ();
4049 p = c;
4050 }
4051
4052 /* Check if body is already there. Either we have gimple body or
4053 the function is thunk and in that case we set DECL_ARGUMENTS. */
4054 if (DECL_ARGUMENTS (decl) || gimple_has_body_p (decl))
4055 return false;
4056
4057 gcc_assert (in_lto_p && !DECL_RESULT (decl));
4058
4059 timevar_push (tv: TV_IPA_LTO_GIMPLE_IN);
4060
4061 file_data = lto_file_data;
4062 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4063
4064 /* We may have renamed the declaration, e.g., a static function. */
4065 name = lto_get_decl_name_mapping (file_data, name);
4066 struct lto_in_decl_state *decl_state
4067 = lto_get_function_in_decl_state (file_data, decl);
4068
4069 cgraph_node *origin = this;
4070 while (origin->clone_of)
4071 origin = origin->clone_of;
4072
4073 int stream_order = origin->order - file_data->order_base;
4074 data = lto_get_section_data (file_data, LTO_section_function_body,
4075 name, stream_order, &len,
4076 decompress: decl_state->compressed);
4077 if (!data)
4078 fatal_error (input_location, "%s: section %s.%d is missing",
4079 file_data->file_name, name, stream_order);
4080
4081 gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
4082
4083 if (!quiet_flag)
4084 fprintf (stderr, format: " in:%s", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
4085 lto_input_function_body (file_data, this, data);
4086 lto_stats.num_function_bodies++;
4087 lto_free_section_data (file_data, LTO_section_function_body, name,
4088 data, len, decompress: decl_state->compressed);
4089 lto_free_function_in_decl_state_for_node (this);
4090 /* Keep lto file data so ipa-inline-analysis knows about cross module
4091 inlining. */
4092
4093 timevar_pop (tv: TV_IPA_LTO_GIMPLE_IN);
4094
4095 return true;
4096}
4097
4098/* Prepare function body. When doing LTO, read cgraph_node's body from disk
4099 if it is not already present. When some IPA transformations are scheduled,
4100 apply them. */
4101
4102bool
4103cgraph_node::get_body (void)
4104{
4105 bool updated;
4106
4107 updated = get_untransformed_body ();
4108
4109 /* Getting transformed body makes no sense for inline clones;
4110 we should never use this on real clones because they are materialized
4111 early.
4112 TODO: Materializing clones here will likely lead to smaller LTRANS
4113 footprint. */
4114 gcc_assert (!inlined_to && !clone_of);
4115 if (ipa_transforms_to_apply.exists ())
4116 {
4117 opt_pass *saved_current_pass = current_pass;
4118 FILE *saved_dump_file = dump_file;
4119 const char *saved_dump_file_name = dump_file_name;
4120 dump_flags_t saved_dump_flags = dump_flags;
4121 dump_file_name = NULL;
4122 set_dump_file (NULL);
4123
4124 push_cfun (DECL_STRUCT_FUNCTION (decl));
4125
4126 update_ssa (TODO_update_ssa_only_virtuals);
4127 execute_all_ipa_transforms (true);
4128 cgraph_edge::rebuild_edges ();
4129 free_dominance_info (CDI_DOMINATORS);
4130 free_dominance_info (CDI_POST_DOMINATORS);
4131 pop_cfun ();
4132 updated = true;
4133
4134 current_pass = saved_current_pass;
4135 set_dump_file (saved_dump_file);
4136 dump_file_name = saved_dump_file_name;
4137 dump_flags = saved_dump_flags;
4138 }
4139 return updated;
4140}
4141
4142/* Return the DECL_STRUCT_FUNCTION of the function. */
4143
4144struct function *
4145cgraph_node::get_fun () const
4146{
4147 const cgraph_node *node = this;
4148 struct function *fun = DECL_STRUCT_FUNCTION (node->decl);
4149
4150 while (!fun && node->clone_of)
4151 {
4152 node = node->clone_of;
4153 fun = DECL_STRUCT_FUNCTION (node->decl);
4154 }
4155
4156 return fun;
4157}
4158
4159/* Reset all state within cgraph.cc so that we can rerun the compiler
4160 within the same process. For use by toplev::finalize. */
4161
4162void
4163cgraph_cc_finalize (void)
4164{
4165 nested_function_info::release ();
4166 thunk_info::release ();
4167 clone_info::release ();
4168 symtab = NULL;
4169
4170 x_cgraph_nodes_queue = NULL;
4171
4172 cgraph_fnver_htab = NULL;
4173 version_info_node = NULL;
4174}
4175
4176/* A worker for call_for_symbol_and_aliases. */
4177
4178bool
4179cgraph_node::call_for_symbol_and_aliases_1 (bool (*callback) (cgraph_node *,
4180 void *),
4181 void *data,
4182 bool include_overwritable)
4183{
4184 ipa_ref *ref;
4185 FOR_EACH_ALIAS (this, ref)
4186 {
4187 cgraph_node *alias = dyn_cast <cgraph_node *> (p: ref->referring);
4188 if (include_overwritable
4189 || alias->get_availability () > AVAIL_INTERPOSABLE)
4190 if (alias->call_for_symbol_and_aliases (callback, data,
4191 include_overwritable))
4192 return true;
4193 }
4194 return false;
4195}
4196
4197/* Return true if NODE has thunk. */
4198
4199bool
4200cgraph_node::has_thunk_p (cgraph_node *node, void *)
4201{
4202 for (cgraph_edge *e = node->callers; e; e = e->next_caller)
4203 if (e->caller->thunk)
4204 return true;
4205 return false;
4206}
4207
4208/* Expected frequency of executions within the function. */
4209
4210sreal
4211cgraph_edge::sreal_frequency ()
4212{
4213 return count.to_sreal_scale (in: caller->inlined_to
4214 ? caller->inlined_to->count
4215 : caller->count);
4216}
4217
4218
4219/* During LTO stream in this can be used to check whether call can possibly
4220 be internal to the current translation unit. */
4221
4222bool
4223cgraph_edge::possibly_call_in_translation_unit_p (void)
4224{
4225 gcc_checking_assert (in_lto_p && caller->prevailing_p ());
4226
4227 /* While incremental linking we may end up getting function body later. */
4228 if (flag_incremental_link == INCREMENTAL_LINK_LTO)
4229 return true;
4230
4231 /* We may be smarter here and avoid streaming in indirect calls we can't
4232 track, but that would require arranging streaming the indirect call
4233 summary first. */
4234 if (!callee)
4235 return true;
4236
4237 /* If callee is local to the original translation unit, it will be
4238 defined. */
4239 if (!TREE_PUBLIC (callee->decl) && !DECL_EXTERNAL (callee->decl))
4240 return true;
4241
4242 /* Otherwise we need to lookup prevailing symbol (symbol table is not merged,
4243 yet) and see if it is a definition. In fact we may also resolve aliases,
4244 but that is probably not too important. */
4245 symtab_node *node = callee;
4246 for (int n = 10; node->previous_sharing_asm_name && n ; n--)
4247 node = node->previous_sharing_asm_name;
4248 if (node->previous_sharing_asm_name)
4249 node = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (callee->decl));
4250 gcc_assert (TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl));
4251 return node->get_availability () >= AVAIL_INTERPOSABLE;
4252}
4253
4254/* Return num_speculative_targets of this edge. */
4255
4256int
4257cgraph_edge::num_speculative_call_targets_p (void)
4258{
4259 return indirect_info ? indirect_info->num_speculative_call_targets : 0;
4260}
4261
4262/* Check if function calls comdat local. This is used to recompute
4263 calls_comdat_local flag after function transformations. */
4264bool
4265cgraph_node::check_calls_comdat_local_p ()
4266{
4267 for (cgraph_edge *e = callees; e; e = e->next_callee)
4268 if (e->inline_failed
4269 ? e->callee->comdat_local_p ()
4270 : e->callee->check_calls_comdat_local_p ())
4271 return true;
4272 return false;
4273}
4274
4275/* Return true if this node represents a former, i.e. an expanded, thunk. */
4276
4277bool
4278cgraph_node::former_thunk_p (void)
4279{
4280 if (thunk)
4281 return false;
4282 thunk_info *i = thunk_info::get (node: this);
4283 if (!i)
4284 return false;
4285 gcc_checking_assert (i->fixed_offset || i->virtual_offset_p
4286 || i->indirect_offset);
4287 return true;
4288}
4289
4290/* A stashed copy of "symtab" for use by selftest::symbol_table_test.
4291 This needs to be a global so that it can be a GC root, and thus
4292 prevent the stashed copy from being garbage-collected if the GC runs
4293 during a symbol_table_test. */
4294
4295symbol_table *saved_symtab;
4296
4297#if CHECKING_P
4298
4299namespace selftest {
4300
4301/* class selftest::symbol_table_test. */
4302
4303/* Constructor. Store the old value of symtab, and create a new one. */
4304
4305symbol_table_test::symbol_table_test ()
4306{
4307 gcc_assert (saved_symtab == NULL);
4308 saved_symtab = symtab;
4309 symtab = new (ggc_alloc<symbol_table> ()) symbol_table ();
4310}
4311
4312/* Destructor. Restore the old value of symtab. */
4313
4314symbol_table_test::~symbol_table_test ()
4315{
4316 gcc_assert (saved_symtab != NULL);
4317 symtab = saved_symtab;
4318 saved_symtab = NULL;
4319}
4320
4321/* Verify that symbol_table_test works. */
4322
4323static void
4324test_symbol_table_test ()
4325{
4326 /* Simulate running two selftests involving symbol tables. */
4327 for (int i = 0; i < 2; i++)
4328 {
4329 symbol_table_test stt;
4330 tree test_decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
4331 get_identifier ("test_decl"),
4332 build_function_type_list (void_type_node,
4333 NULL_TREE));
4334 cgraph_node *node = cgraph_node::get_create (decl: test_decl);
4335 gcc_assert (node);
4336
4337 /* Verify that the node has order 0 on both iterations,
4338 and thus that nodes have predictable dump names in selftests. */
4339 ASSERT_EQ (node->order, 0);
4340 ASSERT_STREQ (node->dump_name (), "test_decl/0");
4341 }
4342}
4343
4344/* Run all of the selftests within this file. */
4345
4346void
4347cgraph_cc_tests ()
4348{
4349 test_symbol_table_test ();
4350}
4351
4352} // namespace selftest
4353
4354#endif /* CHECKING_P */
4355
4356#include "gt-cgraph.h"
4357

source code of gcc/cgraph.cc