]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cgraph.c
* testsuite/26_numerics/cmath/c99_classification_macros_c.cc: Tweak.
[thirdparty/gcc.git] / gcc / cgraph.c
CommitLineData
e72fcfe8 1/* Callgraph handling code.
ad616de1 2 Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
e72fcfe8
JH
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 2, 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 COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
21
18c6ada9
JH
22/* This file contains basic routines manipulating call graph and variable pool
23
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.
31 Each function (external or not) corresponds to the unique node (in
32 contrast to tree DECL nodes where we can have multiple nodes for each
33 function).
34
35 The mapping from declarations to call-graph nodes is done using hash table
36 based on DECL_ASSEMBLER_NAME, so it is essential for assembler name to
37 not change once the declaration is inserted into the call-graph.
38 The call-graph nodes are created lazily using cgraph_node function when
39 called for unknown declaration.
40
41 When built, there is one edge for each direct call. It is possible that
42 the reference will be later optimized out. The call-graph is built
43 conservatively in order to make conservative data flow analysis possible.
44
45 The callgraph at the moment does not represent indirect calls or calls
46 from other compilation unit. Flag NEEDED is set for each node that may
1f838355 47 be accessed in such an invisible way and it shall be considered an
18c6ada9
JH
48 entry point to the callgraph.
49
50 Intraprocedural information:
51
52 Callgraph is place to store data needed for intraprocedural optimization.
1ae58c30 53 All data structures are divided into three components: local_info that
18c6ada9 54 is produced while analyzing the function, global_info that is result
1ae58c30 55 of global walking of the callgraph on the end of compilation and
18c6ada9
JH
56 rtl_info used by RTL backend to propagate data from already compiled
57 functions to their callers.
58
59 Inlining plans:
60
61 The function inlining information is decided in advance and maintained
62 in the callgraph as so called inline plan.
1ae58c30 63 For each inlined call, the callee's node is cloned to represent the
1ea7e6ad 64 new function copy produced by inliner.
1ae58c30
KH
65 Each inlined call gets a unique corresponding clone node of the callee
66 and the data structure is updated while inlining is performed, so
67 the clones are eliminated and their callee edges redirected to the
18c6ada9
JH
68 caller.
69
70 Each edge has "inline_failed" field. When the field is set to NULL,
2b8a92de
KH
71 the call will be inlined. When it is non-NULL it contains a reason
72 why inlining wasn't performed.
18c6ada9
JH
73
74
75The varpool data structure:
76
77 Varpool is used to maintain variables in similar manner as call-graph
78 is used for functions. Most of the API is symmetric replacing cgraph
79 function prefix by cgraph_varpool */
80
81
e72fcfe8
JH
82#include "config.h"
83#include "system.h"
84#include "coretypes.h"
85#include "tm.h"
86#include "tree.h"
e72fcfe8
JH
87#include "langhooks.h"
88#include "hashtab.h"
89#include "toplev.h"
90#include "flags.h"
91#include "ggc.h"
92#include "debug.h"
93#include "target.h"
1c4a429a 94#include "cgraph.h"
988d1653 95#include "varray.h"
e69529cd 96#include "output.h"
dc0bfe6a 97#include "intl.h"
988d1653 98
e72fcfe8 99/* Hash table used to convert declarations into nodes. */
ed2df68b 100static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
e72fcfe8
JH
101
102/* The linked list of cgraph nodes. */
1c4a429a 103struct cgraph_node *cgraph_nodes;
e72fcfe8 104
1668aabc
JH
105/* Queue of cgraph nodes scheduled to be lowered. */
106struct cgraph_node *cgraph_nodes_queue;
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
dafc5b82
JH
114/* Set when whole unit has been analyzed so we can access global info. */
115bool cgraph_global_info_ready = false;
116
e69529cd 117/* Hash table used to convert declarations into nodes. */
ed2df68b 118static GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash;
e69529cd
JH
119
120/* Queue of cgraph nodes scheduled to be lowered and output. */
121struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
122
ed2df68b
JH
123/* The linked list of cgraph varpool nodes. */
124static GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes;
125
439f7bc3
AJ
126static hashval_t hash_node (const void *);
127static int eq_node (const void *, const void *);
e72fcfe8
JH
128
129/* Returns a hash code for P. */
130
131static hashval_t
439f7bc3 132hash_node (const void *p)
e72fcfe8 133{
6f312d18
ZW
134 const struct cgraph_node *n = p;
135 return (hashval_t) DECL_UID (n->decl);
e72fcfe8
JH
136}
137
6356f892 138/* Returns nonzero if P1 and P2 are equal. */
e72fcfe8
JH
139
140static int
439f7bc3 141eq_node (const void *p1, const void *p2)
e72fcfe8 142{
6f312d18
ZW
143 const struct cgraph_node *n1 = p1, *n2 = p2;
144 return DECL_UID (n1->decl) == DECL_UID (n2->decl);
e72fcfe8
JH
145}
146
1ae58c30 147/* Allocate new callgraph node and insert it into basic data structures. */
18c6ada9
JH
148static struct cgraph_node *
149cgraph_create_node (void)
150{
151 struct cgraph_node *node;
152
153 node = ggc_alloc_cleared (sizeof (*node));
154 node->next = cgraph_nodes;
155 node->uid = cgraph_max_uid++;
156 if (cgraph_nodes)
157 cgraph_nodes->previous = node;
158 node->previous = NULL;
159 cgraph_nodes = node;
160 cgraph_n_nodes++;
161 return node;
162}
163
e72fcfe8 164/* Return cgraph node assigned to DECL. Create new one when needed. */
1c4a429a 165struct cgraph_node *
439f7bc3 166cgraph_node (tree decl)
e72fcfe8 167{
6f312d18 168 struct cgraph_node key, *node, **slot;
e72fcfe8 169
341c100f 170 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
988d1653 171
e72fcfe8 172 if (!cgraph_hash)
ed2df68b 173 cgraph_hash = htab_create_ggc (10, hash_node, eq_node, NULL);
e72fcfe8 174
6f312d18
ZW
175 key.decl = decl;
176
177 slot = (struct cgraph_node **) htab_find_slot (cgraph_hash, &key, INSERT);
178
e72fcfe8
JH
179 if (*slot)
180 return *slot;
18c6ada9
JH
181
182 node = cgraph_create_node ();
e72fcfe8 183 node->decl = decl;
e72fcfe8 184 *slot = node;
5c2e00ee 185 if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
e72fcfe8
JH
186 {
187 node->origin = cgraph_node (DECL_CONTEXT (decl));
188 node->next_nested = node->origin->nested;
189 node->origin->nested = node;
190 }
191 return node;
192}
193
bedb9fc0
RH
194/* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */
195
196static bool
197decl_assembler_name_equal (tree decl, tree asmname)
198{
199 tree decl_asmname = DECL_ASSEMBLER_NAME (decl);
200
201 if (decl_asmname == asmname)
202 return true;
203
204 /* If the target assembler name was set by the user, things are trickier.
205 We have a leading '*' to begin with. After that, it's arguable what
206 is the correct thing to do with -fleading-underscore. Arguably, we've
207 historically been doing the wrong thing in assemble_alias by always
208 printing the leading underscore. Since we're not changing that, make
209 sure user_label_prefix follows the '*' before matching. */
210 if (IDENTIFIER_POINTER (decl_asmname)[0] == '*')
211 {
212 const char *decl_str = IDENTIFIER_POINTER (decl_asmname) + 1;
213 size_t ulp_len = strlen (user_label_prefix);
214
215 if (ulp_len == 0)
216 ;
217 else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
218 decl_str += ulp_len;
219 else
220 return false;
221
222 return strcmp (decl_str, IDENTIFIER_POINTER (asmname)) == 0;
223 }
224
225 return false;
226}
227
228
229/* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
230 Return NULL if there's no such node. */
231
232struct cgraph_node *
233cgraph_node_for_asm (tree asmname)
234{
235 struct cgraph_node *node;
236
237 for (node = cgraph_nodes; node ; node = node->next)
238 if (decl_assembler_name_equal (node->decl, asmname))
239 return node;
240
241 return NULL;
242}
243
18c6ada9
JH
244/* Return callgraph edge representing CALL_EXPR. */
245struct cgraph_edge *
246cgraph_edge (struct cgraph_node *node, tree call_expr)
247{
248 struct cgraph_edge *e;
249
250 /* This loop may turn out to be performance problem. In such case adding
251 hashtables into call nodes with very many edges is probably best
2b8a92de 252 solution. It is not good idea to add pointer into CALL_EXPR itself
18c6ada9
JH
253 because we want to make possible having multiple cgraph nodes representing
254 different clones of the same body before the body is actually cloned. */
255 for (e = node->callees; e; e= e->next_callee)
256 if (e->call_expr == call_expr)
257 break;
258 return e;
259}
260
e72fcfe8
JH
261/* Create edge from CALLER to CALLEE in the cgraph. */
262
18c6ada9
JH
263struct cgraph_edge *
264cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
265 tree call_expr)
e72fcfe8 266{
ed2df68b 267 struct cgraph_edge *edge = ggc_alloc (sizeof (struct cgraph_edge));
18c6ada9
JH
268#ifdef ENABLE_CHECKING
269 struct cgraph_edge *e;
270
271 for (e = caller->callees; e; e = e->next_callee)
341c100f 272 gcc_assert (e->call_expr != call_expr);
18c6ada9
JH
273#endif
274
341c100f 275 gcc_assert (TREE_CODE (call_expr) == CALL_EXPR);
b58b1157 276
dc0bfe6a
JH
277 if (!DECL_SAVED_TREE (callee->decl))
278 edge->inline_failed = N_("function body not available");
95c755e9
JH
279 else if (callee->local.redefined_extern_inline)
280 edge->inline_failed = N_("redefined extern inline functions are not "
281 "considered for inlining");
dc0bfe6a
JH
282 else if (callee->local.inlinable)
283 edge->inline_failed = N_("function not considered for inlining");
284 else
285 edge->inline_failed = N_("function not inlinable");
286
18c6ada9 287 edge->aux = NULL;
e72fcfe8
JH
288
289 edge->caller = caller;
290 edge->callee = callee;
18c6ada9 291 edge->call_expr = call_expr;
e72fcfe8
JH
292 edge->next_caller = callee->callers;
293 edge->next_callee = caller->callees;
294 caller->callees = edge;
295 callee->callers = edge;
296 return edge;
297}
298
18c6ada9 299/* Remove the edge E the cgraph. */
e72fcfe8 300
cb967da5 301void
18c6ada9 302cgraph_remove_edge (struct cgraph_edge *e)
e72fcfe8
JH
303{
304 struct cgraph_edge **edge, **edge2;
305
18c6ada9 306 for (edge = &e->callee->callers; *edge && *edge != e;
e72fcfe8
JH
307 edge = &((*edge)->next_caller))
308 continue;
341c100f 309 gcc_assert (*edge);
e72fcfe8 310 *edge = (*edge)->next_caller;
18c6ada9 311 for (edge2 = &e->caller->callees; *edge2 && *edge2 != e;
e72fcfe8
JH
312 edge2 = &(*edge2)->next_callee)
313 continue;
341c100f 314 gcc_assert (*edge2);
e72fcfe8
JH
315 *edge2 = (*edge2)->next_callee;
316}
317
18c6ada9
JH
318/* Redirect callee of E to N. The function does not update underlying
319 call expression. */
320
321void
322cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
323{
324 struct cgraph_edge **edge;
325
326 for (edge = &e->callee->callers; *edge && *edge != e;
327 edge = &((*edge)->next_caller))
328 continue;
341c100f 329 gcc_assert (*edge);
18c6ada9
JH
330 *edge = (*edge)->next_caller;
331 e->callee = n;
332 e->next_caller = n->callers;
333 n->callers = e;
334}
335
18d13f34
JH
336/* Remove the node from cgraph. */
337
338void
439f7bc3 339cgraph_remove_node (struct cgraph_node *node)
18d13f34 340{
2ee1067b 341 void **slot;
18c6ada9
JH
342 bool check_dead = 1;
343
18d13f34 344 while (node->callers)
18c6ada9 345 cgraph_remove_edge (node->callers);
18d13f34 346 while (node->callees)
18c6ada9 347 cgraph_remove_edge (node->callees);
18d13f34
JH
348 while (node->nested)
349 cgraph_remove_node (node->nested);
350 if (node->origin)
351 {
352 struct cgraph_node **node2 = &node->origin->nested;
353
354 while (*node2 != node)
355 node2 = &(*node2)->next_nested;
356 *node2 = node->next_nested;
357 }
358 if (node->previous)
359 node->previous->next = node->next;
360 else
9b0436b7 361 cgraph_nodes = node->next;
18d13f34
JH
362 if (node->next)
363 node->next->previous = node->previous;
6f312d18 364 slot = htab_find_slot (cgraph_hash, node, NO_INSERT);
18c6ada9
JH
365 if (*slot == node)
366 {
367 if (node->next_clone)
368 *slot = node->next_clone;
369 else
370 {
371 htab_clear_slot (cgraph_hash, slot);
9f8628ba 372 if (!dump_enabled_p (TDI_tree_all))
18c6ada9
JH
373 {
374 DECL_SAVED_TREE (node->decl) = NULL;
375 DECL_STRUCT_FUNCTION (node->decl) = NULL;
376 }
377 check_dead = false;
378 }
379 }
380 else
381 {
382 struct cgraph_node *n;
383
384 for (n = *slot; n->next_clone != node; n = n->next_clone)
385 continue;
386 n->next_clone = node->next_clone;
387 }
388
389 /* Work out whether we still need a function body (either there is inline
390 clone or there is out of line function whose body is not written). */
391 if (check_dead && flag_unit_at_a_time)
392 {
393 struct cgraph_node *n;
394
395 for (n = *slot; n; n = n->next_clone)
396 if (n->global.inlined_to
397 || (!n->global.inlined_to
398 && !TREE_ASM_WRITTEN (n->decl) && !DECL_EXTERNAL (n->decl)))
399 break;
9f8628ba 400 if (!n && !dump_enabled_p (TDI_tree_all))
18c6ada9
JH
401 {
402 DECL_SAVED_TREE (node->decl) = NULL;
403 DECL_STRUCT_FUNCTION (node->decl) = NULL;
89480522 404 DECL_INITIAL (node->decl) = error_mark_node;
18c6ada9
JH
405 }
406 }
407 cgraph_n_nodes--;
18d13f34
JH
408 /* Do not free the structure itself so the walk over chain can continue. */
409}
410
8dafba3c
RH
411/* Notify finalize_compilation_unit that given node is reachable. */
412
1668aabc 413void
8dafba3c 414cgraph_mark_reachable_node (struct cgraph_node *node)
1668aabc 415{
ba245151 416 if (!node->reachable && node->local.finalized)
1668aabc 417 {
ba245151 418 notice_global_symbol (node->decl);
1668aabc 419 node->reachable = 1;
e767b5be
JH
420
421 node->next_needed = cgraph_nodes_queue;
422 cgraph_nodes_queue = node;
1668aabc
JH
423 }
424}
425
8dafba3c
RH
426/* Likewise indicate that a node is needed, i.e. reachable via some
427 external means. */
428
429void
430cgraph_mark_needed_node (struct cgraph_node *node)
431{
432 node->needed = 1;
433 cgraph_mark_reachable_node (node);
434}
18d13f34 435
dafc5b82
JH
436/* Return local info for the compiled function. */
437
438struct cgraph_local_info *
439f7bc3 439cgraph_local_info (tree decl)
dafc5b82
JH
440{
441 struct cgraph_node *node;
341c100f
NS
442
443 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
dafc5b82
JH
444 node = cgraph_node (decl);
445 return &node->local;
446}
447
448/* Return local info for the compiled function. */
449
450struct cgraph_global_info *
439f7bc3 451cgraph_global_info (tree decl)
dafc5b82
JH
452{
453 struct cgraph_node *node;
341c100f
NS
454
455 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL && cgraph_global_info_ready);
dafc5b82
JH
456 node = cgraph_node (decl);
457 return &node->global;
458}
459
b255a036
JH
460/* Return local info for the compiled function. */
461
462struct cgraph_rtl_info *
439f7bc3 463cgraph_rtl_info (tree decl)
b255a036
JH
464{
465 struct cgraph_node *node;
341c100f
NS
466
467 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
b255a036
JH
468 node = cgraph_node (decl);
469 if (decl != current_function_decl
470 && !TREE_ASM_WRITTEN (node->decl))
471 return NULL;
472 return &node->rtl;
473}
474
a194aa56
JH
475/* Return name of the node used in debug output. */
476const char *
439f7bc3 477cgraph_node_name (struct cgraph_node *node)
a194aa56 478{
ae2bcd98 479 return lang_hooks.decl_printable_name (node->decl, 2);
a194aa56 480}
dafc5b82 481
18c6ada9
JH
482/* Dump given cgraph node. */
483void
484dump_cgraph_node (FILE *f, struct cgraph_node *node)
485{
486 struct cgraph_edge *edge;
487 fprintf (f, "%s/%i:", cgraph_node_name (node), node->uid);
488 if (node->global.inlined_to)
489 fprintf (f, " (inline copy in %s/%i)",
490 cgraph_node_name (node->global.inlined_to),
491 node->global.inlined_to->uid);
492 if (node->local.self_insns)
493 fprintf (f, " %i insns", node->local.self_insns);
494 if (node->global.insns && node->global.insns != node->local.self_insns)
495 fprintf (f, " (%i after inlining)", node->global.insns);
496 if (node->origin)
497 fprintf (f, " nested in: %s", cgraph_node_name (node->origin));
498 if (node->needed)
499 fprintf (f, " needed");
500 else if (node->reachable)
501 fprintf (f, " reachable");
502 if (DECL_SAVED_TREE (node->decl))
503 fprintf (f, " tree");
504 if (node->output)
505 fprintf (f, " output");
18c6ada9
JH
506 if (node->local.local)
507 fprintf (f, " local");
508 if (node->local.disregard_inline_limits)
509 fprintf (f, " always_inline");
510 else if (node->local.inlinable)
511 fprintf (f, " inlinable");
512 if (TREE_ASM_WRITTEN (node->decl))
513 fprintf (f, " asm_written");
514
515 fprintf (f, "\n called by: ");
516 for (edge = node->callers; edge; edge = edge->next_caller)
517 {
518 fprintf (f, "%s/%i ", cgraph_node_name (edge->caller),
519 edge->caller->uid);
520 if (!edge->inline_failed)
521 fprintf(f, "(inlined) ");
522 }
523
524 fprintf (f, "\n calls: ");
525 for (edge = node->callees; edge; edge = edge->next_callee)
526 {
527 fprintf (f, "%s/%i ", cgraph_node_name (edge->callee),
528 edge->callee->uid);
529 if (!edge->inline_failed)
530 fprintf(f, "(inlined) ");
531 }
532 fprintf (f, "\n");
533}
534
e72fcfe8
JH
535/* Dump the callgraph. */
536
537void
439f7bc3 538dump_cgraph (FILE *f)
e72fcfe8
JH
539{
540 struct cgraph_node *node;
541
7d82fe7c 542 fprintf (f, "callgraph:\n\n");
e72fcfe8 543 for (node = cgraph_nodes; node; node = node->next)
18c6ada9 544 dump_cgraph_node (f, node);
e72fcfe8 545}
988d1653 546
e69529cd
JH
547/* Returns a hash code for P. */
548
549static hashval_t
6f312d18 550hash_varpool_node (const void *p)
e69529cd 551{
6f312d18
ZW
552 const struct cgraph_varpool_node *n = p;
553 return (hashval_t) DECL_UID (n->decl);
e69529cd
JH
554}
555
f1ba665b 556/* Returns nonzero if P1 and P2 are equal. */
e69529cd
JH
557
558static int
6f312d18 559eq_varpool_node (const void *p1, const void *p2)
e69529cd 560{
6f312d18
ZW
561 const struct cgraph_varpool_node *n1 = p1, *n2 = p2;
562 return DECL_UID (n1->decl) == DECL_UID (n2->decl);
e69529cd
JH
563}
564
565/* Return cgraph_varpool node assigned to DECL. Create new one when needed. */
566struct cgraph_varpool_node *
567cgraph_varpool_node (tree decl)
568{
6f312d18 569 struct cgraph_varpool_node key, *node, **slot;
e69529cd 570
341c100f 571 gcc_assert (DECL_P (decl) && TREE_CODE (decl) != FUNCTION_DECL);
e69529cd
JH
572
573 if (!cgraph_varpool_hash)
6f312d18
ZW
574 cgraph_varpool_hash = htab_create_ggc (10, hash_varpool_node,
575 eq_varpool_node, NULL);
576 key.decl = decl;
ed2df68b 577 slot = (struct cgraph_varpool_node **)
6f312d18 578 htab_find_slot (cgraph_varpool_hash, &key, INSERT);
e69529cd
JH
579 if (*slot)
580 return *slot;
ed2df68b 581 node = ggc_alloc_cleared (sizeof (*node));
e69529cd 582 node->decl = decl;
bedb9fc0 583 node->next = cgraph_varpool_nodes;
ed2df68b 584 cgraph_varpool_nodes = node;
e69529cd 585 *slot = node;
e69529cd
JH
586 return node;
587}
588
bedb9fc0
RH
589struct cgraph_varpool_node *
590cgraph_varpool_node_for_asm (tree asmname)
591{
592 struct cgraph_varpool_node *node;
593
594 for (node = cgraph_varpool_nodes; node ; node = node->next)
595 if (decl_assembler_name_equal (node->decl, asmname))
596 return node;
597
598 return NULL;
599}
600
fccc4eb2
JH
601/* Set the DECL_ASSEMBLER_NAME and update cgraph hashtables. */
602void
603change_decl_assembler_name (tree decl, tree name)
604{
fccc4eb2
JH
605 if (!DECL_ASSEMBLER_NAME_SET_P (decl))
606 {
607 SET_DECL_ASSEMBLER_NAME (decl, name);
608 return;
609 }
610 if (name == DECL_ASSEMBLER_NAME (decl))
611 return;
612
df964a18
JH
613 if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
614 && DECL_RTL_SET_P (decl))
fccc4eb2
JH
615 warning ("%D renamed after being referenced in assembly", decl);
616
fccc4eb2 617 SET_DECL_ASSEMBLER_NAME (decl, name);
e69529cd
JH
618}
619
620/* Notify finalize_compilation_unit that given node is reachable
621 or needed. */
622void
623cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node)
624{
625 if (!node->needed && node->finalized)
626 {
8bd87c4e 627 node->next_needed = cgraph_varpool_nodes_queue;
e69529cd 628 cgraph_varpool_nodes_queue = node;
810db579 629 notice_global_symbol (node->decl);
e69529cd
JH
630 }
631 node->needed = 1;
632}
633
634void
635cgraph_varpool_finalize_decl (tree decl)
636{
637 struct cgraph_varpool_node *node = cgraph_varpool_node (decl);
d853a20e
JH
638
639 /* The first declaration of a variable that comes through this function
640 decides whether it is global (in C, has external linkage)
641 or local (in C, has internal linkage). So do nothing more
642 if this function has already run. */
643 if (node->finalized)
644 return;
645 if (node->needed)
e69529cd 646 {
8bd87c4e 647 node->next_needed = cgraph_varpool_nodes_queue;
e69529cd 648 cgraph_varpool_nodes_queue = node;
ba245151 649 notice_global_symbol (decl);
e69529cd
JH
650 }
651 node->finalized = true;
652
653 if (/* Externally visible variables must be output. The exception are
654 COMDAT functions that must be output only when they are needed. */
655 (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
656 /* Function whose name is output to the assembler file must be produced.
657 It is possible to assemble the name later after finalizing the function
658 and the fact is noticed in assemble_name then. */
659 || (DECL_ASSEMBLER_NAME_SET_P (decl)
660 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
661 {
662 cgraph_varpool_mark_needed_node (node);
663 }
664}
665
666bool
439f7bc3 667cgraph_varpool_assemble_pending_decls (void)
e69529cd
JH
668{
669 bool changed = false;
670
671 while (cgraph_varpool_nodes_queue)
672 {
673 tree decl = cgraph_varpool_nodes_queue->decl;
674 struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue;
675
8bd87c4e 676 cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed;
e69529cd
JH
677 if (!TREE_ASM_WRITTEN (decl))
678 {
679 assemble_variable (decl, 0, 1, 0);
680 changed = true;
681 }
8bd87c4e 682 node->next_needed = NULL;
e69529cd
JH
683 }
684 return changed;
685}
686
1bb17c21
JH
687/* Return true when the DECL can possibly be inlined. */
688bool
689cgraph_function_possibly_inlined_p (tree decl)
690{
1bb17c21 691 if (!cgraph_global_info_ready)
18c6ada9 692 return (DECL_INLINE (decl) && !flag_really_no_inline);
6f312d18 693 return DECL_POSSIBLY_INLINED (decl);
18c6ada9
JH
694}
695
696/* Create clone of E in the node N represented by CALL_EXPR the callgraph. */
697struct cgraph_edge *
698cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n, tree call_expr)
699{
700 struct cgraph_edge *new = cgraph_create_edge (n, e->callee, call_expr);
701
702 new->inline_failed = e->inline_failed;
703 return new;
1bb17c21 704}
e69529cd 705
18c6ada9
JH
706/* Create node representing clone of N. */
707struct cgraph_node *
708cgraph_clone_node (struct cgraph_node *n)
709{
710 struct cgraph_node *new = cgraph_create_node ();
711 struct cgraph_edge *e;
712
713 new->decl = n->decl;
714 new->origin = n->origin;
715 if (new->origin)
716 {
717 new->next_nested = new->origin->nested;
718 new->origin->nested = new;
719 }
720 new->analyzed = n->analyzed;
721 new->local = n->local;
722 new->global = n->global;
723 new->rtl = n->rtl;
724
725 for (e = n->callees;e; e=e->next_callee)
726 cgraph_clone_edge (e, new, e->call_expr);
727
728 new->next_clone = n->next_clone;
729 n->next_clone = new;
730
731 return new;
732}
8f235343
JH
733
734/* NODE is no longer nested function; update cgraph accordingly. */
735void
736cgraph_unnest_node (struct cgraph_node *node)
737{
738 struct cgraph_node **node2 = &node->origin->nested;
739 gcc_assert (node->origin);
740
741 while (*node2 != node)
742 node2 = &(*node2)->next_nested;
743 *node2 = node->next_nested;
744 node->origin = NULL;
745}
988d1653 746#include "gt-cgraph.h"