]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cgraph.c
c-pragma.c (handle_pragma_message): New function.
[thirdparty/gcc.git] / gcc / cgraph.c
CommitLineData
e72fcfe8 1/* Callgraph handling code.
2bafad93
JJ
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
3 Free Software Foundation, Inc.
e72fcfe8
JH
4 Contributed by Jan Hubicka
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
9dcd6f09 10Software Foundation; either version 3, or (at your option) any later
e72fcfe8
JH
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
9dcd6f09
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
e72fcfe8 21
8a4a83ed 22/* This file contains basic routines manipulating call graph
c22cacf3 23
18c6ada9
JH
24The callgraph:
25
26 The call-graph is data structure designed for intra-procedural optimization
27 but it is also used in non-unit-at-a-time compilation to allow easier code
28 sharing.
29
30 The call-graph consist of nodes and edges represented via linked lists.
0550e7b7 31 Each function (external or not) corresponds to the unique node.
18c6ada9
JH
32
33 The mapping from declarations to call-graph nodes is done using hash table
0550e7b7
JH
34 based on DECL_UID. The call-graph nodes are created lazily using
35 cgraph_node function when called for unknown declaration.
18c6ada9
JH
36
37 The callgraph at the moment does not represent indirect calls or calls
38 from other compilation unit. Flag NEEDED is set for each node that may
1f838355 39 be accessed in such an invisible way and it shall be considered an
18c6ada9
JH
40 entry point to the callgraph.
41
a418679d 42 Interprocedural information:
18c6ada9 43
a418679d 44 Callgraph is place to store data needed for interprocedural optimization.
1ae58c30 45 All data structures are divided into three components: local_info that
18c6ada9 46 is produced while analyzing the function, global_info that is result
1ae58c30 47 of global walking of the callgraph on the end of compilation and
18c6ada9
JH
48 rtl_info used by RTL backend to propagate data from already compiled
49 functions to their callers.
50
51 Inlining plans:
52
53 The function inlining information is decided in advance and maintained
54 in the callgraph as so called inline plan.
1ae58c30 55 For each inlined call, the callee's node is cloned to represent the
1ea7e6ad 56 new function copy produced by inliner.
1ae58c30
KH
57 Each inlined call gets a unique corresponding clone node of the callee
58 and the data structure is updated while inlining is performed, so
59 the clones are eliminated and their callee edges redirected to the
c22cacf3 60 caller.
18c6ada9
JH
61
62 Each edge has "inline_failed" field. When the field is set to NULL,
2b8a92de 63 the call will be inlined. When it is non-NULL it contains a reason
8a4a83ed 64 why inlining wasn't performed. */
18c6ada9 65
e72fcfe8
JH
66#include "config.h"
67#include "system.h"
68#include "coretypes.h"
69#include "tm.h"
70#include "tree.h"
cd9c7bd2 71#include "tree-inline.h"
e72fcfe8
JH
72#include "langhooks.h"
73#include "hashtab.h"
74#include "toplev.h"
75#include "flags.h"
76#include "ggc.h"
77#include "debug.h"
78#include "target.h"
cd9c7bd2 79#include "basic-block.h"
1c4a429a 80#include "cgraph.h"
988d1653 81#include "varray.h"
e69529cd 82#include "output.h"
dc0bfe6a 83#include "intl.h"
e0704a46 84#include "tree-gimple.h"
ef330312 85#include "tree-dump.h"
7a388ee4 86#include "tree-flow.h"
988d1653 87
2563c224
RG
88static void cgraph_node_remove_callers (struct cgraph_node *node);
89static inline void cgraph_edge_remove_caller (struct cgraph_edge *e);
90static inline void cgraph_edge_remove_callee (struct cgraph_edge *e);
91
e72fcfe8 92/* Hash table used to convert declarations into nodes. */
ed2df68b 93static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
266ad5c8
JH
94/* Hash table used to convert assembler names into nodes. */
95static GTY((param_is (struct cgraph_node))) htab_t assembler_name_hash;
e72fcfe8
JH
96
97/* The linked list of cgraph nodes. */
1c4a429a 98struct cgraph_node *cgraph_nodes;
e72fcfe8 99
1668aabc
JH
100/* Queue of cgraph nodes scheduled to be lowered. */
101struct cgraph_node *cgraph_nodes_queue;
102
f45e0ad1 103/* Queue of cgraph nodes scheduled to be added into cgraph. This is a
c0220ea4 104 secondary queue used during optimization to accommodate passes that
50674e96 105 may generate new functions that need to be optimized and expanded. */
f45e0ad1 106struct cgraph_node *cgraph_new_nodes;
953ff289 107
e72fcfe8 108/* Number of nodes in existence. */
1c4a429a 109int cgraph_n_nodes;
e72fcfe8 110
b58b1157
JH
111/* Maximal uid used in cgraph nodes. */
112int cgraph_max_uid;
113
9088c1cc
MJ
114/* Maximal uid used in cgraph edges. */
115int cgraph_edge_max_uid;
116
6bad2617
TB
117/* Maximal pid used for profiling */
118int cgraph_max_pid;
119
dafc5b82
JH
120/* Set when whole unit has been analyzed so we can access global info. */
121bool cgraph_global_info_ready = false;
122
f45e0ad1
JH
123/* What state callgraph is in right now. */
124enum cgraph_state cgraph_state = CGRAPH_STATE_CONSTRUCTION;
125
cd9c7bd2
JH
126/* Set when the cgraph is fully build and the basic flags are computed. */
127bool cgraph_function_flags_ready = false;
128
474eccc6
ILT
129/* Linked list of cgraph asm nodes. */
130struct cgraph_asm_node *cgraph_asm_nodes;
131
132/* Last node in cgraph_asm_nodes. */
133static GTY(()) struct cgraph_asm_node *cgraph_asm_last_node;
134
135/* The order index of the next cgraph node to be created. This is
136 used so that we can sort the cgraph nodes in order by when we saw
137 them, to support -fno-toplevel-reorder. */
138int cgraph_order;
139
9088c1cc
MJ
140/* List of hooks trigerred on cgraph_edge events. */
141struct cgraph_edge_hook_list {
142 cgraph_edge_hook hook;
143 void *data;
144 struct cgraph_edge_hook_list *next;
145};
146
147/* List of hooks trigerred on cgraph_node events. */
148struct cgraph_node_hook_list {
149 cgraph_node_hook hook;
150 void *data;
151 struct cgraph_node_hook_list *next;
152};
153
154/* List of hooks trigerred on events involving two cgraph_edges. */
155struct cgraph_2edge_hook_list {
156 cgraph_2edge_hook hook;
157 void *data;
158 struct cgraph_2edge_hook_list *next;
159};
160
161/* List of hooks trigerred on events involving two cgraph_nodes. */
162struct cgraph_2node_hook_list {
163 cgraph_2node_hook hook;
164 void *data;
165 struct cgraph_2node_hook_list *next;
166};
167
168/* List of hooks triggered when an edge is removed. */
169struct cgraph_edge_hook_list *first_cgraph_edge_removal_hook;
170/* List of hooks triggered when a node is removed. */
171struct cgraph_node_hook_list *first_cgraph_node_removal_hook;
172/* List of hooks triggered when an edge is duplicated. */
173struct cgraph_2edge_hook_list *first_cgraph_edge_duplicated_hook;
174/* List of hooks triggered when a node is duplicated. */
175struct cgraph_2node_hook_list *first_cgraph_node_duplicated_hook;
176
177
178/* Register HOOK to be called with DATA on each removed edge. */
179struct cgraph_edge_hook_list *
180cgraph_add_edge_removal_hook (cgraph_edge_hook hook, void *data)
181{
182 struct cgraph_edge_hook_list *entry;
183 struct cgraph_edge_hook_list **ptr = &first_cgraph_edge_removal_hook;
184
185 entry = (struct cgraph_edge_hook_list *) xmalloc (sizeof (*entry));
186 entry->hook = hook;
187 entry->data = data;
188 entry->next = NULL;
189 while (*ptr)
190 ptr = &(*ptr)->next;
191 *ptr = entry;
192 return entry;
193}
194
195/* Remove ENTRY from the list of hooks called on removing edges. */
196void
197cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *entry)
198{
199 struct cgraph_edge_hook_list **ptr = &first_cgraph_edge_removal_hook;
200
201 while (*ptr != entry)
202 ptr = &(*ptr)->next;
203 *ptr = entry->next;
204}
205
206/* Call all edge removal hooks. */
207static void
208cgraph_call_edge_removal_hooks (struct cgraph_edge *e)
209{
210 struct cgraph_edge_hook_list *entry = first_cgraph_edge_removal_hook;
211 while (entry)
212 {
213 entry->hook (e, entry->data);
214 entry = entry->next;
215 }
216}
217
218/* Register HOOK to be called with DATA on each removed node. */
219struct cgraph_node_hook_list *
220cgraph_add_node_removal_hook (cgraph_node_hook hook, void *data)
221{
222 struct cgraph_node_hook_list *entry;
223 struct cgraph_node_hook_list **ptr = &first_cgraph_node_removal_hook;
224
225 entry = (struct cgraph_node_hook_list *) xmalloc (sizeof (*entry));
226 entry->hook = hook;
227 entry->data = data;
228 entry->next = NULL;
229 while (*ptr)
230 ptr = &(*ptr)->next;
231 *ptr = entry;
232 return entry;
233}
234
235/* Remove ENTRY from the list of hooks called on removing nodes. */
236void
237cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *entry)
238{
239 struct cgraph_node_hook_list **ptr = &first_cgraph_node_removal_hook;
240
241 while (*ptr != entry)
242 ptr = &(*ptr)->next;
243 *ptr = entry->next;
244}
245
246/* Call all node removal hooks. */
247static void
248cgraph_call_node_removal_hooks (struct cgraph_node *node)
249{
250 struct cgraph_node_hook_list *entry = first_cgraph_node_removal_hook;
251 while (entry)
252 {
253 entry->hook (node, entry->data);
254 entry = entry->next;
255 }
256}
257
258/* Register HOOK to be called with DATA on each duplicated edge. */
259struct cgraph_2edge_hook_list *
260cgraph_add_edge_duplication_hook (cgraph_2edge_hook hook, void *data)
261{
262 struct cgraph_2edge_hook_list *entry;
263 struct cgraph_2edge_hook_list **ptr = &first_cgraph_edge_duplicated_hook;
264
265 entry = (struct cgraph_2edge_hook_list *) xmalloc (sizeof (*entry));
266 entry->hook = hook;
267 entry->data = data;
268 entry->next = NULL;
269 while (*ptr)
270 ptr = &(*ptr)->next;
271 *ptr = entry;
272 return entry;
273}
274
275/* Remove ENTRY from the list of hooks called on duplicating edges. */
276void
277cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *entry)
278{
279 struct cgraph_2edge_hook_list **ptr = &first_cgraph_edge_duplicated_hook;
280
281 while (*ptr != entry)
282 ptr = &(*ptr)->next;
283 *ptr = entry->next;
284}
285
286/* Call all edge duplication hooks. */
287static void
288cgraph_call_edge_duplication_hooks (struct cgraph_edge *cs1,
289 struct cgraph_edge *cs2)
290{
291 struct cgraph_2edge_hook_list *entry = first_cgraph_edge_duplicated_hook;
292 while (entry)
293 {
294 entry->hook (cs1, cs2, entry->data);
295 entry = entry->next;
296 }
297}
298
299/* Register HOOK to be called with DATA on each duplicated node. */
300struct cgraph_2node_hook_list *
301cgraph_add_node_duplication_hook (cgraph_2node_hook hook, void *data)
302{
303 struct cgraph_2node_hook_list *entry;
304 struct cgraph_2node_hook_list **ptr = &first_cgraph_node_duplicated_hook;
305
306 entry = (struct cgraph_2node_hook_list *) xmalloc (sizeof (*entry));
307 entry->hook = hook;
308 entry->data = data;
309 entry->next = NULL;
310 while (*ptr)
311 ptr = &(*ptr)->next;
312 *ptr = entry;
313 return entry;
314}
315
316/* Remove ENTRY from the list of hooks called on duplicating nodes. */
317void
318cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *entry)
319{
320 struct cgraph_2node_hook_list **ptr = &first_cgraph_node_duplicated_hook;
321
322 while (*ptr != entry)
323 ptr = &(*ptr)->next;
324 *ptr = entry->next;
325}
326
327/* Call all node duplication hooks. */
328static void
329cgraph_call_node_duplication_hooks (struct cgraph_node *node1,
330 struct cgraph_node *node2)
331{
332 struct cgraph_2node_hook_list *entry = first_cgraph_node_duplicated_hook;
333 while (entry)
334 {
335 entry->hook (node1, node2, entry->data);
336 entry = entry->next;
337 }
338}
339
e72fcfe8
JH
340/* Returns a hash code for P. */
341
342static hashval_t
439f7bc3 343hash_node (const void *p)
e72fcfe8 344{
cceb1885 345 const struct cgraph_node *n = (const struct cgraph_node *) p;
6f312d18 346 return (hashval_t) DECL_UID (n->decl);
e72fcfe8
JH
347}
348
6356f892 349/* Returns nonzero if P1 and P2 are equal. */
e72fcfe8
JH
350
351static int
439f7bc3 352eq_node (const void *p1, const void *p2)
e72fcfe8 353{
cceb1885
GDR
354 const struct cgraph_node *n1 = (const struct cgraph_node *) p1;
355 const struct cgraph_node *n2 = (const struct cgraph_node *) p2;
6f312d18 356 return DECL_UID (n1->decl) == DECL_UID (n2->decl);
e72fcfe8
JH
357}
358
1ae58c30 359/* Allocate new callgraph node and insert it into basic data structures. */
0550e7b7 360
18c6ada9
JH
361static struct cgraph_node *
362cgraph_create_node (void)
363{
364 struct cgraph_node *node;
365
cceb1885 366 node = GGC_CNEW (struct cgraph_node);
18c6ada9
JH
367 node->next = cgraph_nodes;
368 node->uid = cgraph_max_uid++;
6bad2617 369 node->pid = -1;
474eccc6 370 node->order = cgraph_order++;
18c6ada9
JH
371 if (cgraph_nodes)
372 cgraph_nodes->previous = node;
373 node->previous = NULL;
670cd5c5 374 node->global.estimated_growth = INT_MIN;
18c6ada9
JH
375 cgraph_nodes = node;
376 cgraph_n_nodes++;
377 return node;
378}
379
e72fcfe8 380/* Return cgraph node assigned to DECL. Create new one when needed. */
0550e7b7 381
1c4a429a 382struct cgraph_node *
439f7bc3 383cgraph_node (tree decl)
e72fcfe8 384{
6f312d18 385 struct cgraph_node key, *node, **slot;
e72fcfe8 386
341c100f 387 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
988d1653 388
e72fcfe8 389 if (!cgraph_hash)
ed2df68b 390 cgraph_hash = htab_create_ggc (10, hash_node, eq_node, NULL);
e72fcfe8 391
6f312d18
ZW
392 key.decl = decl;
393
394 slot = (struct cgraph_node **) htab_find_slot (cgraph_hash, &key, INSERT);
395
e72fcfe8 396 if (*slot)
6b02a499
JH
397 {
398 node = *slot;
399 if (!node->master_clone)
400 node->master_clone = node;
401 return node;
402 }
18c6ada9
JH
403
404 node = cgraph_create_node ();
e72fcfe8 405 node->decl = decl;
e72fcfe8 406 *slot = node;
5c2e00ee 407 if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
e72fcfe8
JH
408 {
409 node->origin = cgraph_node (DECL_CONTEXT (decl));
410 node->next_nested = node->origin->nested;
411 node->origin->nested = node;
6b02a499 412 node->master_clone = node;
e72fcfe8 413 }
266ad5c8 414
e72fcfe8
JH
415 return node;
416}
417
ea99e0be
JH
418/* Insert already constructed node into hashtable. */
419
420void
421cgraph_insert_node_to_hashtable (struct cgraph_node *node)
422{
423 struct cgraph_node **slot;
424
425 slot = (struct cgraph_node **) htab_find_slot (cgraph_hash, node, INSERT);
426
427 gcc_assert (!*slot);
428 *slot = node;
429}
430
266ad5c8
JH
431/* Returns a hash code for P. */
432
433static hashval_t
434hash_node_by_assembler_name (const void *p)
435{
436 const struct cgraph_node *n = (const struct cgraph_node *) p;
437 return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->decl));
438}
439
440/* Returns nonzero if P1 and P2 are equal. */
441
442static int
443eq_assembler_name (const void *p1, const void *p2)
444{
445 const struct cgraph_node *n1 = (const struct cgraph_node *) p1;
446 const_tree name = (const_tree)p2;
447 return (decl_assembler_name_equal (n1->decl, name));
448}
bedb9fc0
RH
449
450/* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
451 Return NULL if there's no such node. */
452
453struct cgraph_node *
454cgraph_node_for_asm (tree asmname)
455{
456 struct cgraph_node *node;
266ad5c8 457 void **slot;
bedb9fc0 458
266ad5c8
JH
459 if (!assembler_name_hash)
460 {
461 assembler_name_hash =
462 htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name,
463 NULL);
464 for (node = cgraph_nodes; node; node = node->next)
465 if (!node->global.inlined_to)
466 {
467 tree name = DECL_ASSEMBLER_NAME (node->decl);
468 slot = htab_find_slot_with_hash (assembler_name_hash, name,
469 decl_assembler_name_hash (name),
470 INSERT);
471 /* We can have multiple declarations with same assembler name. For C++
472 it is __builtin_strlen and strlen, for instance. Do we need to
473 record them all? Original implementation marked just first one
474 so lets hope for the best. */
475 if (*slot)
476 continue;
477 *slot = node;
478 }
479 }
480
481 slot = htab_find_slot_with_hash (assembler_name_hash, asmname,
482 decl_assembler_name_hash (asmname),
483 NO_INSERT);
bedb9fc0 484
266ad5c8
JH
485 if (slot)
486 return (struct cgraph_node *) *slot;
bedb9fc0
RH
487 return NULL;
488}
489
70d539ce
JH
490/* Returns a hash value for X (which really is a die_struct). */
491
492static hashval_t
493edge_hash (const void *x)
494{
741ac903 495 return htab_hash_pointer (((const struct cgraph_edge *) x)->call_stmt);
70d539ce
JH
496}
497
498/* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y. */
499
500static int
501edge_eq (const void *x, const void *y)
502{
741ac903 503 return ((const struct cgraph_edge *) x)->call_stmt == y;
70d539ce
JH
504}
505
e0704a46 506/* Return callgraph edge representing CALL_EXPR statement. */
18c6ada9 507struct cgraph_edge *
e0704a46 508cgraph_edge (struct cgraph_node *node, tree call_stmt)
18c6ada9 509{
70d539ce
JH
510 struct cgraph_edge *e, *e2;
511 int n = 0;
512
513 if (node->call_site_hash)
f883e0a7
KG
514 return (struct cgraph_edge *)
515 htab_find_with_hash (node->call_site_hash, call_stmt,
516 htab_hash_pointer (call_stmt));
18c6ada9
JH
517
518 /* This loop may turn out to be performance problem. In such case adding
519 hashtables into call nodes with very many edges is probably best
2b8a92de 520 solution. It is not good idea to add pointer into CALL_EXPR itself
18c6ada9
JH
521 because we want to make possible having multiple cgraph nodes representing
522 different clones of the same body before the body is actually cloned. */
523 for (e = node->callees; e; e= e->next_callee)
70d539ce
JH
524 {
525 if (e->call_stmt == call_stmt)
526 break;
527 n++;
528 }
529 if (n > 100)
530 {
531 node->call_site_hash = htab_create_ggc (120, edge_hash, edge_eq, NULL);
532 for (e2 = node->callees; e2; e2 = e2->next_callee)
533 {
534 void **slot;
535 slot = htab_find_slot_with_hash (node->call_site_hash,
536 e2->call_stmt,
537 htab_hash_pointer (e2->call_stmt),
538 INSERT);
539 gcc_assert (!*slot);
540 *slot = e2;
541 }
542 }
18c6ada9
JH
543 return e;
544}
545
fa10beec 546/* Change call_stmt of edge E to NEW_STMT. */
0550e7b7 547
70d539ce
JH
548void
549cgraph_set_call_stmt (struct cgraph_edge *e, tree new_stmt)
550{
551 if (e->caller->call_site_hash)
552 {
553 htab_remove_elt_with_hash (e->caller->call_site_hash,
554 e->call_stmt,
555 htab_hash_pointer (e->call_stmt));
556 }
557 e->call_stmt = new_stmt;
558 if (e->caller->call_site_hash)
559 {
560 void **slot;
561 slot = htab_find_slot_with_hash (e->caller->call_site_hash,
562 e->call_stmt,
563 htab_hash_pointer
564 (e->call_stmt), INSERT);
565 gcc_assert (!*slot);
566 *slot = e;
567 }
568}
569
e72fcfe8
JH
570/* Create edge from CALLER to CALLEE in the cgraph. */
571
18c6ada9
JH
572struct cgraph_edge *
573cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
45a80bb9 574 tree call_stmt, gcov_type count, int freq, int nest)
e72fcfe8 575{
cceb1885 576 struct cgraph_edge *edge = GGC_NEW (struct cgraph_edge);
18c6ada9
JH
577#ifdef ENABLE_CHECKING
578 struct cgraph_edge *e;
579
580 for (e = caller->callees; e; e = e->next_callee)
e0704a46 581 gcc_assert (e->call_stmt != call_stmt);
18c6ada9
JH
582#endif
583
e0704a46 584 gcc_assert (get_call_expr_in (call_stmt));
b58b1157 585
dc0bfe6a
JH
586 if (!DECL_SAVED_TREE (callee->decl))
587 edge->inline_failed = N_("function body not available");
95c755e9
JH
588 else if (callee->local.redefined_extern_inline)
589 edge->inline_failed = N_("redefined extern inline functions are not "
590 "considered for inlining");
dc0bfe6a
JH
591 else if (callee->local.inlinable)
592 edge->inline_failed = N_("function not considered for inlining");
593 else
594 edge->inline_failed = N_("function not inlinable");
595
18c6ada9 596 edge->aux = NULL;
e72fcfe8
JH
597
598 edge->caller = caller;
599 edge->callee = callee;
e0704a46 600 edge->call_stmt = call_stmt;
2563c224 601 edge->prev_caller = NULL;
e72fcfe8 602 edge->next_caller = callee->callers;
2563c224
RG
603 if (callee->callers)
604 callee->callers->prev_caller = edge;
605 edge->prev_callee = NULL;
e72fcfe8 606 edge->next_callee = caller->callees;
2563c224
RG
607 if (caller->callees)
608 caller->callees->prev_callee = edge;
e72fcfe8
JH
609 caller->callees = edge;
610 callee->callers = edge;
e42922b1 611 edge->count = count;
45a80bb9
JH
612 gcc_assert (count >= 0);
613 edge->frequency = freq;
614 gcc_assert (freq >= 0);
615 gcc_assert (freq <= CGRAPH_FREQ_MAX);
e42922b1 616 edge->loop_nest = nest;
3e293154 617 edge->indirect_call = 0;
9088c1cc 618 edge->uid = cgraph_edge_max_uid++;
70d539ce
JH
619 if (caller->call_site_hash)
620 {
621 void **slot;
622 slot = htab_find_slot_with_hash (caller->call_site_hash,
623 edge->call_stmt,
624 htab_hash_pointer
625 (edge->call_stmt),
626 INSERT);
627 gcc_assert (!*slot);
628 *slot = edge;
629 }
e72fcfe8
JH
630 return edge;
631}
632
2563c224
RG
633/* Remove the edge E from the list of the callers of the callee. */
634
635static inline void
636cgraph_edge_remove_callee (struct cgraph_edge *e)
637{
638 if (e->prev_caller)
639 e->prev_caller->next_caller = e->next_caller;
640 if (e->next_caller)
641 e->next_caller->prev_caller = e->prev_caller;
642 if (!e->prev_caller)
643 e->callee->callers = e->next_caller;
644}
645
646/* Remove the edge E from the list of the callees of the caller. */
647
648static inline void
649cgraph_edge_remove_caller (struct cgraph_edge *e)
650{
651 if (e->prev_callee)
652 e->prev_callee->next_callee = e->next_callee;
653 if (e->next_callee)
654 e->next_callee->prev_callee = e->prev_callee;
655 if (!e->prev_callee)
656 e->caller->callees = e->next_callee;
70d539ce
JH
657 if (e->caller->call_site_hash)
658 htab_remove_elt_with_hash (e->caller->call_site_hash,
659 e->call_stmt,
660 htab_hash_pointer (e->call_stmt));
2563c224
RG
661}
662
663/* Remove the edge E in the cgraph. */
e72fcfe8 664
cb967da5 665void
18c6ada9 666cgraph_remove_edge (struct cgraph_edge *e)
e72fcfe8 667{
9088c1cc 668 cgraph_call_edge_removal_hooks (e);
2563c224
RG
669 /* Remove from callers list of the callee. */
670 cgraph_edge_remove_callee (e);
671
672 /* Remove from callees list of the callers. */
673 cgraph_edge_remove_caller (e);
e72fcfe8
JH
674}
675
18c6ada9
JH
676/* Redirect callee of E to N. The function does not update underlying
677 call expression. */
678
679void
680cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
681{
2563c224
RG
682 /* Remove from callers list of the current callee. */
683 cgraph_edge_remove_callee (e);
18c6ada9 684
2563c224
RG
685 /* Insert to callers list of the new callee. */
686 e->prev_caller = NULL;
687 if (n->callers)
688 n->callers->prev_caller = e;
18c6ada9
JH
689 e->next_caller = n->callers;
690 n->callers = e;
2563c224
RG
691 e->callee = n;
692}
693
2bafad93
JJ
694/* Update or remove corresponding cgraph edge if a call OLD_CALL
695 in OLD_STMT changed into NEW_STMT. */
696
697void
698cgraph_update_edges_for_call_stmt (tree old_stmt, tree old_call,
699 tree new_stmt)
700{
701 tree new_call = get_call_expr_in (new_stmt);
702 struct cgraph_node *node = cgraph_node (cfun->decl);
703
704 if (old_call != new_call)
705 {
706 struct cgraph_edge *e = cgraph_edge (node, old_stmt);
707 struct cgraph_edge *ne = NULL;
708 tree new_decl;
709
710 if (e)
711 {
712 gcov_type count = e->count;
713 int frequency = e->frequency;
714 int loop_nest = e->loop_nest;
715
716 cgraph_remove_edge (e);
717 if (new_call)
718 {
719 new_decl = get_callee_fndecl (new_call);
720 if (new_decl)
721 {
722 ne = cgraph_create_edge (node, cgraph_node (new_decl),
723 new_stmt, count, frequency,
724 loop_nest);
725 gcc_assert (ne->inline_failed);
726 }
727 }
728 }
729 }
730 else if (old_stmt != new_stmt)
731 {
732 struct cgraph_edge *e = cgraph_edge (node, old_stmt);
733
734 if (e)
735 cgraph_set_call_stmt (e, new_stmt);
736 }
737}
738
2563c224
RG
739/* Remove all callees from the node. */
740
741void
742cgraph_node_remove_callees (struct cgraph_node *node)
743{
744 struct cgraph_edge *e;
745
746 /* It is sufficient to remove the edges from the lists of callers of
747 the callees. The callee list of the node can be zapped with one
748 assignment. */
749 for (e = node->callees; e; e = e->next_callee)
9088c1cc
MJ
750 {
751 cgraph_call_edge_removal_hooks (e);
752 cgraph_edge_remove_callee (e);
753 }
2563c224 754 node->callees = NULL;
70d539ce
JH
755 if (node->call_site_hash)
756 {
757 htab_delete (node->call_site_hash);
758 node->call_site_hash = NULL;
759 }
2563c224
RG
760}
761
762/* Remove all callers from the node. */
763
764static void
765cgraph_node_remove_callers (struct cgraph_node *node)
766{
767 struct cgraph_edge *e;
768
769 /* It is sufficient to remove the edges from the lists of callees of
770 the callers. The caller list of the node can be zapped with one
771 assignment. */
772 for (e = node->callers; e; e = e->next_caller)
9088c1cc
MJ
773 {
774 cgraph_call_edge_removal_hooks (e);
775 cgraph_edge_remove_caller (e);
776 }
2563c224 777 node->callers = NULL;
18c6ada9
JH
778}
779
3a40c18a
JH
780/* Release memory used to represent body of function NODE. */
781
782void
783cgraph_release_function_body (struct cgraph_node *node)
784{
785 if (DECL_STRUCT_FUNCTION (node->decl)
786 && DECL_STRUCT_FUNCTION (node->decl)->gimple_df)
787 {
788 tree old_decl = current_function_decl;
789 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
790 current_function_decl = node->decl;
791 delete_tree_ssa ();
792 delete_tree_cfg_annotations ();
4437b50d 793 cfun->eh = NULL;
3a40c18a
JH
794 current_function_decl = old_decl;
795 pop_cfun();
796 }
797 DECL_SAVED_TREE (node->decl) = NULL;
798 DECL_STRUCT_FUNCTION (node->decl) = NULL;
799 DECL_INITIAL (node->decl) = error_mark_node;
800}
801
18d13f34
JH
802/* Remove the node from cgraph. */
803
804void
439f7bc3 805cgraph_remove_node (struct cgraph_node *node)
18d13f34 806{
2ee1067b 807 void **slot;
4a76d91a 808 bool kill_body = false;
18c6ada9 809
9088c1cc 810 cgraph_call_node_removal_hooks (node);
2563c224
RG
811 cgraph_node_remove_callers (node);
812 cgraph_node_remove_callees (node);
266ad5c8 813
96fc428c
JH
814 /* Incremental inlining access removed nodes stored in the postorder list.
815 */
816 node->needed = node->reachable = false;
18d13f34
JH
817 while (node->nested)
818 cgraph_remove_node (node->nested);
819 if (node->origin)
820 {
821 struct cgraph_node **node2 = &node->origin->nested;
822
823 while (*node2 != node)
824 node2 = &(*node2)->next_nested;
825 *node2 = node->next_nested;
826 }
827 if (node->previous)
828 node->previous->next = node->next;
829 else
9b0436b7 830 cgraph_nodes = node->next;
18d13f34
JH
831 if (node->next)
832 node->next->previous = node->previous;
96fc428c
JH
833 node->next = NULL;
834 node->previous = NULL;
6f312d18 835 slot = htab_find_slot (cgraph_hash, node, NO_INSERT);
18c6ada9
JH
836 if (*slot == node)
837 {
838 if (node->next_clone)
1655dc9d 839 {
6b02a499
JH
840 struct cgraph_node *new_node = node->next_clone;
841 struct cgraph_node *n;
842
843 /* Make the next clone be the master clone */
c22cacf3 844 for (n = new_node; n; n = n->next_clone)
6b02a499 845 n->master_clone = new_node;
c22cacf3 846
6b02a499 847 *slot = new_node;
1655dc9d
JH
848 node->next_clone->prev_clone = NULL;
849 }
18c6ada9
JH
850 else
851 {
c22cacf3 852 htab_clear_slot (cgraph_hash, slot);
4a76d91a 853 kill_body = true;
18c6ada9
JH
854 }
855 }
856 else
857 {
1655dc9d
JH
858 node->prev_clone->next_clone = node->next_clone;
859 if (node->next_clone)
c22cacf3 860 node->next_clone->prev_clone = node->prev_clone;
18c6ada9
JH
861 }
862
c22cacf3 863 /* While all the clones are removed after being proceeded, the function
4a76d91a
JH
864 itself is kept in the cgraph even after it is compiled. Check whether
865 we are done with this body and reclaim it proactively if this is the case.
866 */
867 if (!kill_body && *slot)
18c6ada9 868 {
cceb1885 869 struct cgraph_node *n = (struct cgraph_node *) *slot;
4a76d91a 870 if (!n->next_clone && !n->global.inlined_to
d63db217
JH
871 && (cgraph_global_info_ready
872 && (TREE_ASM_WRITTEN (n->decl) || DECL_EXTERNAL (n->decl))))
4a76d91a
JH
873 kill_body = true;
874 }
266ad5c8
JH
875 if (assembler_name_hash)
876 {
877 tree name = DECL_ASSEMBLER_NAME (node->decl);
878 slot = htab_find_slot_with_hash (assembler_name_hash, name,
879 decl_assembler_name_hash (name),
880 NO_INSERT);
881 /* Inline clones are not hashed. */
882 if (slot && *slot == node)
883 htab_clear_slot (assembler_name_hash, slot);
884 }
18c6ada9 885
7e8b322a 886 if (kill_body)
3a40c18a 887 cgraph_release_function_body (node);
96fc428c 888 node->decl = NULL;
70d539ce
JH
889 if (node->call_site_hash)
890 {
891 htab_delete (node->call_site_hash);
892 node->call_site_hash = NULL;
893 }
18c6ada9 894 cgraph_n_nodes--;
18d13f34
JH
895 /* Do not free the structure itself so the walk over chain can continue. */
896}
897
8dafba3c
RH
898/* Notify finalize_compilation_unit that given node is reachable. */
899
1668aabc 900void
8dafba3c 901cgraph_mark_reachable_node (struct cgraph_node *node)
1668aabc 902{
ba245151 903 if (!node->reachable && node->local.finalized)
1668aabc 904 {
ba245151 905 notice_global_symbol (node->decl);
1668aabc 906 node->reachable = 1;
45676d2b 907 gcc_assert (!cgraph_global_info_ready);
e767b5be
JH
908
909 node->next_needed = cgraph_nodes_queue;
910 cgraph_nodes_queue = node;
1668aabc
JH
911 }
912}
913
8dafba3c
RH
914/* Likewise indicate that a node is needed, i.e. reachable via some
915 external means. */
916
917void
918cgraph_mark_needed_node (struct cgraph_node *node)
919{
920 node->needed = 1;
921 cgraph_mark_reachable_node (node);
922}
18d13f34 923
dafc5b82
JH
924/* Return local info for the compiled function. */
925
926struct cgraph_local_info *
439f7bc3 927cgraph_local_info (tree decl)
dafc5b82
JH
928{
929 struct cgraph_node *node;
c22cacf3 930
341c100f 931 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
dafc5b82
JH
932 node = cgraph_node (decl);
933 return &node->local;
934}
935
936/* Return local info for the compiled function. */
937
938struct cgraph_global_info *
439f7bc3 939cgraph_global_info (tree decl)
dafc5b82
JH
940{
941 struct cgraph_node *node;
c22cacf3 942
341c100f 943 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL && cgraph_global_info_ready);
dafc5b82
JH
944 node = cgraph_node (decl);
945 return &node->global;
946}
947
b255a036
JH
948/* Return local info for the compiled function. */
949
950struct cgraph_rtl_info *
439f7bc3 951cgraph_rtl_info (tree decl)
b255a036
JH
952{
953 struct cgraph_node *node;
c22cacf3 954
341c100f 955 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
b255a036
JH
956 node = cgraph_node (decl);
957 if (decl != current_function_decl
958 && !TREE_ASM_WRITTEN (node->decl))
959 return NULL;
960 return &node->rtl;
961}
962
a194aa56
JH
963/* Return name of the node used in debug output. */
964const char *
439f7bc3 965cgraph_node_name (struct cgraph_node *node)
a194aa56 966{
ae2bcd98 967 return lang_hooks.decl_printable_name (node->decl, 2);
a194aa56 968}
dafc5b82 969
6b02a499 970/* Names used to print out the availability enum. */
8a4a83ed 971const char * const cgraph_availability_names[] =
fa10beec 972 {"unset", "not_available", "overwritable", "available", "local"};
6b02a499 973
c4e622b6
DN
974
975/* Dump call graph node NODE to file F. */
976
18c6ada9
JH
977void
978dump_cgraph_node (FILE *f, struct cgraph_node *node)
979{
980 struct cgraph_edge *edge;
6bad2617 981 fprintf (f, "%s/%i(%i):", cgraph_node_name (node), node->uid, node->pid);
18c6ada9
JH
982 if (node->global.inlined_to)
983 fprintf (f, " (inline copy in %s/%i)",
984 cgraph_node_name (node->global.inlined_to),
985 node->global.inlined_to->uid);
6b02a499 986 if (cgraph_function_flags_ready)
c22cacf3 987 fprintf (f, " availability:%s",
8a4a83ed 988 cgraph_availability_names [cgraph_function_body_availability (node)]);
6b02a499
JH
989 if (node->master_clone && node->master_clone->uid != node->uid)
990 fprintf (f, "(%i)", node->master_clone->uid);
e42922b1
JH
991 if (node->count)
992 fprintf (f, " executed "HOST_WIDEST_INT_PRINT_DEC"x",
993 (HOST_WIDEST_INT)node->count);
95622280
JH
994 if (node->local.inline_summary.self_insns)
995 fprintf (f, " %i insns", node->local.inline_summary.self_insns);
996 if (node->global.insns && node->global.insns
997 != node->local.inline_summary.self_insns)
18c6ada9 998 fprintf (f, " (%i after inlining)", node->global.insns);
95622280
JH
999 if (node->local.inline_summary.estimated_self_stack_size)
1000 fprintf (f, " %i bytes stack usage", (int)node->local.inline_summary.estimated_self_stack_size);
1001 if (node->global.estimated_stack_size != node->local.inline_summary.estimated_self_stack_size)
ff28a94d 1002 fprintf (f, " %i bytes after inlining", (int)node->global.estimated_stack_size);
18c6ada9
JH
1003 if (node->origin)
1004 fprintf (f, " nested in: %s", cgraph_node_name (node->origin));
1005 if (node->needed)
1006 fprintf (f, " needed");
1007 else if (node->reachable)
1008 fprintf (f, " reachable");
1009 if (DECL_SAVED_TREE (node->decl))
1010 fprintf (f, " tree");
1011 if (node->output)
1012 fprintf (f, " output");
18c6ada9
JH
1013 if (node->local.local)
1014 fprintf (f, " local");
e7d6beb0
JH
1015 if (node->local.externally_visible)
1016 fprintf (f, " externally_visible");
1017 if (node->local.finalized)
1018 fprintf (f, " finalized");
18c6ada9
JH
1019 if (node->local.disregard_inline_limits)
1020 fprintf (f, " always_inline");
1021 else if (node->local.inlinable)
1022 fprintf (f, " inlinable");
e7d6beb0
JH
1023 if (node->local.redefined_extern_inline)
1024 fprintf (f, " redefined_extern_inline");
18c6ada9
JH
1025 if (TREE_ASM_WRITTEN (node->decl))
1026 fprintf (f, " asm_written");
1027
1028 fprintf (f, "\n called by: ");
1029 for (edge = node->callers; edge; edge = edge->next_caller)
1030 {
1031 fprintf (f, "%s/%i ", cgraph_node_name (edge->caller),
1032 edge->caller->uid);
e42922b1
JH
1033 if (edge->count)
1034 fprintf (f, "("HOST_WIDEST_INT_PRINT_DEC"x) ",
1035 (HOST_WIDEST_INT)edge->count);
45a80bb9
JH
1036 if (edge->frequency)
1037 fprintf (f, "(%.2f per call) ",
1038 edge->frequency / (double)CGRAPH_FREQ_BASE);
18c6ada9
JH
1039 if (!edge->inline_failed)
1040 fprintf(f, "(inlined) ");
3e293154
MJ
1041 if (edge->indirect_call)
1042 fprintf(f, "(indirect) ");
18c6ada9
JH
1043 }
1044
1045 fprintf (f, "\n calls: ");
1046 for (edge = node->callees; edge; edge = edge->next_callee)
1047 {
1048 fprintf (f, "%s/%i ", cgraph_node_name (edge->callee),
1049 edge->callee->uid);
1050 if (!edge->inline_failed)
1051 fprintf(f, "(inlined) ");
3e293154
MJ
1052 if (edge->indirect_call)
1053 fprintf(f, "(indirect) ");
6b02a499
JH
1054 if (edge->count)
1055 fprintf (f, "("HOST_WIDEST_INT_PRINT_DEC"x) ",
1056 (HOST_WIDEST_INT)edge->count);
45a80bb9
JH
1057 if (edge->frequency)
1058 fprintf (f, "(%.2f per call) ",
1059 edge->frequency / (double)CGRAPH_FREQ_BASE);
6b02a499
JH
1060 if (edge->loop_nest)
1061 fprintf (f, "(nested in %i loops) ", edge->loop_nest);
18c6ada9
JH
1062 }
1063 fprintf (f, "\n");
1064}
1065
c4e622b6
DN
1066
1067/* Dump call graph node NODE to stderr. */
1068
1069void
1070debug_cgraph_node (struct cgraph_node *node)
1071{
1072 dump_cgraph_node (stderr, node);
1073}
1074
1075
1076/* Dump the callgraph to file F. */
e72fcfe8
JH
1077
1078void
439f7bc3 1079dump_cgraph (FILE *f)
e72fcfe8
JH
1080{
1081 struct cgraph_node *node;
1082
7d82fe7c 1083 fprintf (f, "callgraph:\n\n");
e72fcfe8 1084 for (node = cgraph_nodes; node; node = node->next)
18c6ada9 1085 dump_cgraph_node (f, node);
e72fcfe8 1086}
988d1653 1087
c4e622b6
DN
1088
1089/* Dump the call graph to stderr. */
1090
1091void
1092debug_cgraph (void)
1093{
1094 dump_cgraph (stderr);
1095}
1096
1097
fccc4eb2 1098/* Set the DECL_ASSEMBLER_NAME and update cgraph hashtables. */
c4e622b6 1099
fccc4eb2
JH
1100void
1101change_decl_assembler_name (tree decl, tree name)
1102{
266ad5c8 1103 gcc_assert (!assembler_name_hash);
fccc4eb2
JH
1104 if (!DECL_ASSEMBLER_NAME_SET_P (decl))
1105 {
1106 SET_DECL_ASSEMBLER_NAME (decl, name);
1107 return;
1108 }
1109 if (name == DECL_ASSEMBLER_NAME (decl))
1110 return;
1111
df964a18
JH
1112 if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
1113 && DECL_RTL_SET_P (decl))
d4ee4d25 1114 warning (0, "%D renamed after being referenced in assembly", decl);
fccc4eb2 1115
fccc4eb2 1116 SET_DECL_ASSEMBLER_NAME (decl, name);
e69529cd
JH
1117}
1118
474eccc6
ILT
1119/* Add a top-level asm statement to the list. */
1120
1121struct cgraph_asm_node *
1122cgraph_add_asm_node (tree asm_str)
1123{
1124 struct cgraph_asm_node *node;
1125
1126 node = GGC_CNEW (struct cgraph_asm_node);
1127 node->asm_str = asm_str;
1128 node->order = cgraph_order++;
1129 node->next = NULL;
1130 if (cgraph_asm_nodes == NULL)
1131 cgraph_asm_nodes = node;
1132 else
1133 cgraph_asm_last_node->next = node;
1134 cgraph_asm_last_node = node;
1135 return node;
1136}
1137
1bb17c21
JH
1138/* Return true when the DECL can possibly be inlined. */
1139bool
1140cgraph_function_possibly_inlined_p (tree decl)
1141{
1bb17c21 1142 if (!cgraph_global_info_ready)
c37f4ba4 1143 return !DECL_UNINLINABLE (decl) && !flag_really_no_inline;
6f312d18 1144 return DECL_POSSIBLY_INLINED (decl);
18c6ada9
JH
1145}
1146
1147/* Create clone of E in the node N represented by CALL_EXPR the callgraph. */
1148struct cgraph_edge *
e42922b1 1149cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
45a80bb9
JH
1150 tree call_stmt, gcov_type count_scale, int freq_scale,
1151 int loop_nest, bool update_original)
18c6ada9 1152{
e42922b1 1153 struct cgraph_edge *new;
45a80bb9
JH
1154 gcov_type count = e->count * count_scale / REG_BR_PROB_BASE;
1155 gcov_type freq = e->frequency * (gcov_type) freq_scale / CGRAPH_FREQ_BASE;
e42922b1 1156
45a80bb9
JH
1157 if (freq > CGRAPH_FREQ_MAX)
1158 freq = CGRAPH_FREQ_MAX;
1159 new = cgraph_create_edge (n, e->callee, call_stmt, count, freq,
c22cacf3 1160 e->loop_nest + loop_nest);
18c6ada9
JH
1161
1162 new->inline_failed = e->inline_failed;
3e293154 1163 new->indirect_call = e->indirect_call;
c5a4444c 1164 if (update_original)
d63f0fe5
JH
1165 {
1166 e->count -= new->count;
1167 if (e->count < 0)
1168 e->count = 0;
1169 }
9088c1cc 1170 cgraph_call_edge_duplication_hooks (e, new);
18c6ada9 1171 return new;
1bb17c21 1172}
e69529cd 1173
e42922b1 1174/* Create node representing clone of N executed COUNT times. Decrease
c22cacf3 1175 the execution counts from original node too.
c5a4444c
JH
1176
1177 When UPDATE_ORIGINAL is true, the counts are subtracted from the original
1178 function's profile to reflect the fact that part of execution is handled
1179 by node. */
18c6ada9 1180struct cgraph_node *
45a80bb9 1181cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq, int loop_nest,
c5a4444c 1182 bool update_original)
18c6ada9
JH
1183{
1184 struct cgraph_node *new = cgraph_create_node ();
1185 struct cgraph_edge *e;
06191a23 1186 gcov_type count_scale;
18c6ada9
JH
1187
1188 new->decl = n->decl;
1189 new->origin = n->origin;
1190 if (new->origin)
1191 {
1192 new->next_nested = new->origin->nested;
1193 new->origin->nested = new;
1194 }
1195 new->analyzed = n->analyzed;
1196 new->local = n->local;
1197 new->global = n->global;
1198 new->rtl = n->rtl;
6b02a499 1199 new->master_clone = n->master_clone;
e42922b1
JH
1200 new->count = count;
1201 if (n->count)
1202 count_scale = new->count * REG_BR_PROB_BASE / n->count;
1203 else
1204 count_scale = 0;
c5a4444c 1205 if (update_original)
d63f0fe5
JH
1206 {
1207 n->count -= count;
1208 if (n->count < 0)
1209 n->count = 0;
1210 }
18c6ada9
JH
1211
1212 for (e = n->callees;e; e=e->next_callee)
45a80bb9 1213 cgraph_clone_edge (e, new, e->call_stmt, count_scale, freq, loop_nest,
c5a4444c 1214 update_original);
18c6ada9
JH
1215
1216 new->next_clone = n->next_clone;
1655dc9d 1217 new->prev_clone = n;
18c6ada9 1218 n->next_clone = new;
1655dc9d
JH
1219 if (new->next_clone)
1220 new->next_clone->prev_clone = new;
18c6ada9 1221
9088c1cc 1222 cgraph_call_node_duplication_hooks (n, new);
18c6ada9
JH
1223 return new;
1224}
8f235343 1225
6b02a499
JH
1226/* Return true if N is an master_clone, (see cgraph_master_clone). */
1227
1228bool
1229cgraph_is_master_clone (struct cgraph_node *n)
1230{
1231 return (n == cgraph_master_clone (n));
1232}
1233
1234struct cgraph_node *
1235cgraph_master_clone (struct cgraph_node *n)
1236{
1237 enum availability avail = cgraph_function_body_availability (n);
c22cacf3 1238
6b02a499
JH
1239 if (avail == AVAIL_NOT_AVAILABLE || avail == AVAIL_OVERWRITABLE)
1240 return NULL;
1241
c22cacf3 1242 if (!n->master_clone)
6b02a499 1243 n->master_clone = cgraph_node (n->decl);
c22cacf3 1244
6b02a499
JH
1245 return n->master_clone;
1246}
1247
8f235343
JH
1248/* NODE is no longer nested function; update cgraph accordingly. */
1249void
1250cgraph_unnest_node (struct cgraph_node *node)
1251{
1252 struct cgraph_node **node2 = &node->origin->nested;
1253 gcc_assert (node->origin);
1254
1255 while (*node2 != node)
1256 node2 = &(*node2)->next_nested;
1257 *node2 = node->next_nested;
1258 node->origin = NULL;
1259}
6b02a499
JH
1260
1261/* Return function availability. See cgraph.h for description of individual
1262 return values. */
1263enum availability
1264cgraph_function_body_availability (struct cgraph_node *node)
1265{
1266 enum availability avail;
1267 gcc_assert (cgraph_function_flags_ready);
093c2329 1268 if (!node->analyzed)
6b02a499
JH
1269 avail = AVAIL_NOT_AVAILABLE;
1270 else if (node->local.local)
1271 avail = AVAIL_LOCAL;
1272 else if (node->local.externally_visible)
1273 avail = AVAIL_AVAILABLE;
1274
1275 /* If the function can be overwritten, return OVERWRITABLE. Take
1276 care at least of two notable extensions - the COMDAT functions
1277 used to share template instantiations in C++ (this is symmetric
1278 to code cp_cannot_inline_tree_fn and probably shall be shared and
ff5c4582 1279 the inlinability hooks completely eliminated).
6b02a499
JH
1280
1281 ??? Does the C++ one definition rule allow us to always return
1282 AVAIL_AVAILABLE here? That would be good reason to preserve this
1283 hook Similarly deal with extern inline functions - this is again
ff5c4582 1284 necessary to get C++ shared functions having keyed templates
6b02a499
JH
1285 right and in the C extension documentation we probably should
1286 document the requirement of both versions of function (extern
1287 inline and offline) having same side effect characteristics as
1288 good optimization is what this optimization is about. */
c22cacf3 1289
6b02a499
JH
1290 else if (!(*targetm.binds_local_p) (node->decl)
1291 && !DECL_COMDAT (node->decl) && !DECL_EXTERNAL (node->decl))
1292 avail = AVAIL_OVERWRITABLE;
1293 else avail = AVAIL_AVAILABLE;
1294
1295 return avail;
1296}
1297
f45e0ad1
JH
1298/* Add the function FNDECL to the call graph.
1299 Unlike cgraph_finalize_function, this function is intended to be used
1300 by middle end and allows insertion of new function at arbitrary point
1301 of compilation. The function can be either in high, low or SSA form
1302 GIMPLE.
50674e96 1303
f45e0ad1
JH
1304 The function is assumed to be reachable and have address taken (so no
1305 API breaking optimizations are performed on it).
50674e96 1306
f45e0ad1
JH
1307 Main work done by this function is to enqueue the function for later
1308 processing to avoid need the passes to be re-entrant. */
953ff289
DN
1309
1310void
f45e0ad1 1311cgraph_add_new_function (tree fndecl, bool lowered)
953ff289 1312{
f45e0ad1
JH
1313 struct cgraph_node *node;
1314 switch (cgraph_state)
1315 {
1316 case CGRAPH_STATE_CONSTRUCTION:
fa10beec 1317 /* Just enqueue function to be processed at nearest occurrence. */
f45e0ad1
JH
1318 node = cgraph_node (fndecl);
1319 node->next_needed = cgraph_new_nodes;
1320 if (lowered)
1321 node->lowered = true;
1322 cgraph_new_nodes = node;
1323 break;
1324
1325 case CGRAPH_STATE_IPA:
7a388ee4 1326 case CGRAPH_STATE_IPA_SSA:
f45e0ad1
JH
1327 case CGRAPH_STATE_EXPANSION:
1328 /* Bring the function into finalized state and enqueue for later
1329 analyzing and compilation. */
1330 node = cgraph_node (fndecl);
1331 node->local.local = false;
1332 node->local.finalized = true;
1333 node->reachable = node->needed = true;
ff2c88a5
JH
1334 if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
1335 {
1336 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
1337 current_function_decl = fndecl;
1338 tree_register_cfg_hooks ();
1339 tree_lowering_passes (fndecl);
1340 bitmap_obstack_initialize (NULL);
1341 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
1342 execute_pass_list (pass_early_local_passes.pass.sub);
1343 bitmap_obstack_release (NULL);
1344 pop_cfun ();
1345 current_function_decl = NULL;
1346
1347 lowered = true;
1348 }
f45e0ad1
JH
1349 if (lowered)
1350 node->lowered = true;
1351 node->next_needed = cgraph_new_nodes;
1352 cgraph_new_nodes = node;
1353 break;
1354
1355 case CGRAPH_STATE_FINISHED:
1356 /* At the very end of compilation we have to do all the work up
1357 to expansion. */
1358 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
1359 current_function_decl = fndecl;
1360 tree_register_cfg_hooks ();
1361 if (!lowered)
1362 tree_lowering_passes (fndecl);
7a388ee4 1363 bitmap_obstack_initialize (NULL);
c72321c9 1364 if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
8ddbbcae 1365 execute_pass_list (pass_early_local_passes.pass.sub);
7a388ee4 1366 bitmap_obstack_release (NULL);
f45e0ad1
JH
1367 tree_rest_of_compilation (fndecl);
1368 pop_cfun ();
1369 current_function_decl = NULL;
1370 break;
1371 }
953ff289
DN
1372}
1373
988d1653 1374#include "gt-cgraph.h"