OSDN Git Service

* cgraph.c (cgraph_remove_node): Avoid loop in code deciding whether
[pf3gnuchains/gcc-fork.git] / gcc / cgraph.c
1 /* Callgraph handling code.
2    Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3    Contributed by Jan Hubicka
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 /*  This file contains basic routines manipulating call graph and variable pool
23   
24 The 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
47     be accessed in such an invisible way and it shall be considered an
48     entry point to the callgraph.
49
50     Intraprocedural information:
51
52       Callgraph is place to store data needed for intraprocedural optimization.
53       All data structures are divided into three components: local_info that
54       is produced while analyzing the function, global_info that is result
55       of global walking of the callgraph on the end of compilation and
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.
63       For each inlined call, the callee's node is cloned to represent the
64       new function copy produced by inliner.
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
68       caller. 
69
70       Each edge has "inline_failed" field.  When the field is set to NULL,
71       the call will be inlined.  When it is non-NULL it contains a reason
72       why inlining wasn't performed.
73
74
75 The 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
82 #include "config.h"
83 #include "system.h"
84 #include "coretypes.h"
85 #include "tm.h"
86 #include "tree.h"
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"
94 #include "cgraph.h"
95 #include "varray.h"
96 #include "output.h"
97 #include "intl.h"
98
99 static void cgraph_node_remove_callers (struct cgraph_node *node);
100 static inline void cgraph_edge_remove_caller (struct cgraph_edge *e);
101 static inline void cgraph_edge_remove_callee (struct cgraph_edge *e);
102
103 /* Hash table used to convert declarations into nodes.  */
104 static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
105
106 /* The linked list of cgraph nodes.  */
107 struct cgraph_node *cgraph_nodes;
108
109 /* Queue of cgraph nodes scheduled to be lowered.  */
110 struct cgraph_node *cgraph_nodes_queue;
111
112 /* Number of nodes in existence.  */
113 int cgraph_n_nodes;
114
115 /* Maximal uid used in cgraph nodes.  */
116 int cgraph_max_uid;
117
118 /* Set when whole unit has been analyzed so we can access global info.  */
119 bool cgraph_global_info_ready = false;
120
121 /* Hash table used to convert declarations into nodes.  */
122 static GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash;
123
124 /* Queue of cgraph nodes scheduled to be lowered and output.  */
125 struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
126
127 /* The linked list of cgraph varpool nodes.  */
128 static GTY(())  struct cgraph_varpool_node *cgraph_varpool_nodes;
129
130 static hashval_t hash_node (const void *);
131 static int eq_node (const void *, const void *);
132
133 /* Returns a hash code for P.  */
134
135 static hashval_t
136 hash_node (const void *p)
137 {
138   const struct cgraph_node *n = p;
139   return (hashval_t) DECL_UID (n->decl);
140 }
141
142 /* Returns nonzero if P1 and P2 are equal.  */
143
144 static int
145 eq_node (const void *p1, const void *p2)
146 {
147   const struct cgraph_node *n1 = p1, *n2 = p2;
148   return DECL_UID (n1->decl) == DECL_UID (n2->decl);
149 }
150
151 /* Allocate new callgraph node and insert it into basic data structures.  */
152 static struct cgraph_node *
153 cgraph_create_node (void)
154 {
155   struct cgraph_node *node;
156
157   node = ggc_alloc_cleared (sizeof (*node));
158   node->next = cgraph_nodes;
159   node->uid = cgraph_max_uid++;
160   if (cgraph_nodes)
161     cgraph_nodes->previous = node;
162   node->previous = NULL;
163   cgraph_nodes = node;
164   cgraph_n_nodes++;
165   return node;
166 }
167
168 /* Return cgraph node assigned to DECL.  Create new one when needed.  */
169 struct cgraph_node *
170 cgraph_node (tree decl)
171 {
172   struct cgraph_node key, *node, **slot;
173
174   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
175
176   if (!cgraph_hash)
177     cgraph_hash = htab_create_ggc (10, hash_node, eq_node, NULL);
178
179   key.decl = decl;
180
181   slot = (struct cgraph_node **) htab_find_slot (cgraph_hash, &key, INSERT);
182
183   if (*slot)
184     return *slot;
185
186   node = cgraph_create_node ();
187   node->decl = decl;
188   *slot = node;
189   if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
190     {
191       node->origin = cgraph_node (DECL_CONTEXT (decl));
192       node->next_nested = node->origin->nested;
193       node->origin->nested = node;
194     }
195   return node;
196 }
197
198 /* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL.  */
199
200 static bool
201 decl_assembler_name_equal (tree decl, tree asmname)
202 {
203   tree decl_asmname = DECL_ASSEMBLER_NAME (decl);
204
205   if (decl_asmname == asmname)
206     return true;
207
208   /* If the target assembler name was set by the user, things are trickier.
209      We have a leading '*' to begin with.  After that, it's arguable what
210      is the correct thing to do with -fleading-underscore.  Arguably, we've
211      historically been doing the wrong thing in assemble_alias by always
212      printing the leading underscore.  Since we're not changing that, make
213      sure user_label_prefix follows the '*' before matching.  */
214   if (IDENTIFIER_POINTER (decl_asmname)[0] == '*')
215     {
216       const char *decl_str = IDENTIFIER_POINTER (decl_asmname) + 1;
217       size_t ulp_len = strlen (user_label_prefix);
218
219       if (ulp_len == 0)
220         ;
221       else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
222         decl_str += ulp_len;
223       else
224         return false;
225
226       return strcmp (decl_str, IDENTIFIER_POINTER (asmname)) == 0;
227     }
228
229   return false;
230 }
231
232
233 /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
234    Return NULL if there's no such node.  */
235
236 struct cgraph_node *
237 cgraph_node_for_asm (tree asmname)
238 {
239   struct cgraph_node *node;
240
241   for (node = cgraph_nodes; node ; node = node->next)
242     if (decl_assembler_name_equal (node->decl, asmname))
243       return node;
244
245   return NULL;
246 }
247
248 /* Return callgraph edge representing CALL_EXPR.  */
249 struct cgraph_edge *
250 cgraph_edge (struct cgraph_node *node, tree call_expr)
251 {
252   struct cgraph_edge *e;
253
254   /* This loop may turn out to be performance problem.  In such case adding
255      hashtables into call nodes with very many edges is probably best
256      solution.  It is not good idea to add pointer into CALL_EXPR itself
257      because we want to make possible having multiple cgraph nodes representing
258      different clones of the same body before the body is actually cloned.  */
259   for (e = node->callees; e; e= e->next_callee)
260     if (e->call_expr == call_expr)
261       break;
262   return e;
263 }
264
265 /* Create edge from CALLER to CALLEE in the cgraph.  */
266
267 struct cgraph_edge *
268 cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
269                     tree call_expr)
270 {
271   struct cgraph_edge *edge = ggc_alloc (sizeof (struct cgraph_edge));
272 #ifdef ENABLE_CHECKING
273   struct cgraph_edge *e;
274
275   for (e = caller->callees; e; e = e->next_callee)
276     gcc_assert (e->call_expr != call_expr);
277 #endif
278
279   gcc_assert (TREE_CODE (call_expr) == CALL_EXPR);
280
281   if (!DECL_SAVED_TREE (callee->decl))
282     edge->inline_failed = N_("function body not available");
283   else if (callee->local.redefined_extern_inline)
284     edge->inline_failed = N_("redefined extern inline functions are not "
285                              "considered for inlining");
286   else if (callee->local.inlinable)
287     edge->inline_failed = N_("function not considered for inlining");
288   else
289     edge->inline_failed = N_("function not inlinable");
290
291   edge->aux = NULL;
292
293   edge->caller = caller;
294   edge->callee = callee;
295   edge->call_expr = call_expr;
296   edge->prev_caller = NULL;
297   edge->next_caller = callee->callers;
298   if (callee->callers)
299     callee->callers->prev_caller = edge;
300   edge->prev_callee = NULL;
301   edge->next_callee = caller->callees;
302   if (caller->callees)
303     caller->callees->prev_callee = edge;
304   caller->callees = edge;
305   callee->callers = edge;
306   return edge;
307 }
308
309 /* Remove the edge E from the list of the callers of the callee.  */
310
311 static inline void
312 cgraph_edge_remove_callee (struct cgraph_edge *e)
313 {
314   if (e->prev_caller)
315     e->prev_caller->next_caller = e->next_caller;
316   if (e->next_caller)
317     e->next_caller->prev_caller = e->prev_caller;
318   if (!e->prev_caller)
319     e->callee->callers = e->next_caller;
320 }
321
322 /* Remove the edge E from the list of the callees of the caller.  */
323
324 static inline void
325 cgraph_edge_remove_caller (struct cgraph_edge *e)
326 {
327   if (e->prev_callee)
328     e->prev_callee->next_callee = e->next_callee;
329   if (e->next_callee)
330     e->next_callee->prev_callee = e->prev_callee;
331   if (!e->prev_callee)
332     e->caller->callees = e->next_callee;
333 }
334
335 /* Remove the edge E in the cgraph.  */
336
337 void
338 cgraph_remove_edge (struct cgraph_edge *e)
339 {
340   /* Remove from callers list of the callee.  */
341   cgraph_edge_remove_callee (e);
342
343   /* Remove from callees list of the callers.  */
344   cgraph_edge_remove_caller (e);
345 }
346
347 /* Redirect callee of E to N.  The function does not update underlying
348    call expression.  */
349
350 void
351 cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
352 {
353   /* Remove from callers list of the current callee.  */
354   cgraph_edge_remove_callee (e);
355
356   /* Insert to callers list of the new callee.  */
357   e->prev_caller = NULL;
358   if (n->callers)
359     n->callers->prev_caller = e;
360   e->next_caller = n->callers;
361   n->callers = e;
362   e->callee = n;
363 }
364
365 /* Remove all callees from the node.  */
366
367 void
368 cgraph_node_remove_callees (struct cgraph_node *node)
369 {
370   struct cgraph_edge *e;
371
372   /* It is sufficient to remove the edges from the lists of callers of
373      the callees.  The callee list of the node can be zapped with one
374      assignment.  */
375   for (e = node->callees; e; e = e->next_callee)
376     cgraph_edge_remove_callee (e);
377   node->callees = NULL;
378 }
379
380 /* Remove all callers from the node.  */
381
382 static void
383 cgraph_node_remove_callers (struct cgraph_node *node)
384 {
385   struct cgraph_edge *e;
386
387   /* It is sufficient to remove the edges from the lists of callees of
388      the callers.  The caller list of the node can be zapped with one
389      assignment.  */
390   for (e = node->callers; e; e = e->next_caller)
391     cgraph_edge_remove_caller (e);
392   node->callers = NULL;
393 }
394
395 /* Remove the node from cgraph.  */
396
397 void
398 cgraph_remove_node (struct cgraph_node *node)
399 {
400   void **slot;
401   bool kill_body = false;
402
403   cgraph_node_remove_callers (node);
404   cgraph_node_remove_callees (node);
405   while (node->nested)
406     cgraph_remove_node (node->nested);
407   if (node->origin)
408     {
409       struct cgraph_node **node2 = &node->origin->nested;
410
411       while (*node2 != node)
412         node2 = &(*node2)->next_nested;
413       *node2 = node->next_nested;
414     }
415   if (node->previous)
416     node->previous->next = node->next;
417   else
418     cgraph_nodes = node->next;
419   if (node->next)
420     node->next->previous = node->previous;
421   slot = htab_find_slot (cgraph_hash, node, NO_INSERT);
422   if (*slot == node)
423     {
424       if (node->next_clone)
425         *slot = node->next_clone;
426       else
427         {
428           htab_clear_slot (cgraph_hash, slot);
429           kill_body = true;
430         }
431     }
432   else
433     {
434       struct cgraph_node *n;
435
436       for (n = *slot; n->next_clone != node; n = n->next_clone)
437         continue;
438       n->next_clone = node->next_clone;
439     }
440
441   /* While all the clones are removed after being proceeded, the function 
442      itself is kept in the cgraph even after it is compiled.  Check whether
443      we are done with this body and reclaim it proactively if this is the case.
444      */
445   if (!kill_body && *slot)
446     {
447       struct cgraph_node *n = *slot;
448       if (!n->next_clone && !n->global.inlined_to
449           && (TREE_ASM_WRITTEN (n->decl) || DECL_EXTERNAL (n->decl)))
450         kill_body = true;
451     }
452
453   if (kill_body && !dump_enabled_p (TDI_tree_all) && flag_unit_at_a_time)
454     {
455       DECL_SAVED_TREE (node->decl) = NULL;
456       DECL_STRUCT_FUNCTION (node->decl) = NULL;
457       DECL_INITIAL (node->decl) = error_mark_node;
458     }
459   cgraph_n_nodes--;
460   /* Do not free the structure itself so the walk over chain can continue.  */
461 }
462
463 /* Notify finalize_compilation_unit that given node is reachable.  */
464
465 void
466 cgraph_mark_reachable_node (struct cgraph_node *node)
467 {
468   if (!node->reachable && node->local.finalized)
469     {
470       notice_global_symbol (node->decl);
471       node->reachable = 1;
472
473       node->next_needed = cgraph_nodes_queue;
474       cgraph_nodes_queue = node;
475     }
476 }
477
478 /* Likewise indicate that a node is needed, i.e. reachable via some
479    external means.  */
480
481 void
482 cgraph_mark_needed_node (struct cgraph_node *node)
483 {
484   node->needed = 1;
485   cgraph_mark_reachable_node (node);
486 }
487
488 /* Return local info for the compiled function.  */
489
490 struct cgraph_local_info *
491 cgraph_local_info (tree decl)
492 {
493   struct cgraph_node *node;
494   
495   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
496   node = cgraph_node (decl);
497   return &node->local;
498 }
499
500 /* Return local info for the compiled function.  */
501
502 struct cgraph_global_info *
503 cgraph_global_info (tree decl)
504 {
505   struct cgraph_node *node;
506   
507   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL && cgraph_global_info_ready);
508   node = cgraph_node (decl);
509   return &node->global;
510 }
511
512 /* Return local info for the compiled function.  */
513
514 struct cgraph_rtl_info *
515 cgraph_rtl_info (tree decl)
516 {
517   struct cgraph_node *node;
518   
519   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
520   node = cgraph_node (decl);
521   if (decl != current_function_decl
522       && !TREE_ASM_WRITTEN (node->decl))
523     return NULL;
524   return &node->rtl;
525 }
526
527 /* Return name of the node used in debug output.  */
528 const char *
529 cgraph_node_name (struct cgraph_node *node)
530 {
531   return lang_hooks.decl_printable_name (node->decl, 2);
532 }
533
534 /* Dump given cgraph node.  */
535 void
536 dump_cgraph_node (FILE *f, struct cgraph_node *node)
537 {
538   struct cgraph_edge *edge;
539   fprintf (f, "%s/%i:", cgraph_node_name (node), node->uid);
540   if (node->global.inlined_to)
541     fprintf (f, " (inline copy in %s/%i)",
542              cgraph_node_name (node->global.inlined_to),
543              node->global.inlined_to->uid);
544   if (node->local.self_insns)
545     fprintf (f, " %i insns", node->local.self_insns);
546   if (node->global.insns && node->global.insns != node->local.self_insns)
547     fprintf (f, " (%i after inlining)", node->global.insns);
548   if (node->origin)
549     fprintf (f, " nested in: %s", cgraph_node_name (node->origin));
550   if (node->needed)
551     fprintf (f, " needed");
552   else if (node->reachable)
553     fprintf (f, " reachable");
554   if (DECL_SAVED_TREE (node->decl))
555     fprintf (f, " tree");
556   if (node->output)
557     fprintf (f, " output");
558   if (node->local.local)
559     fprintf (f, " local");
560   if (node->local.disregard_inline_limits)
561     fprintf (f, " always_inline");
562   else if (node->local.inlinable)
563     fprintf (f, " inlinable");
564   if (TREE_ASM_WRITTEN (node->decl))
565     fprintf (f, " asm_written");
566
567   fprintf (f, "\n  called by: ");
568   for (edge = node->callers; edge; edge = edge->next_caller)
569     {
570       fprintf (f, "%s/%i ", cgraph_node_name (edge->caller),
571                edge->caller->uid);
572       if (!edge->inline_failed)
573         fprintf(f, "(inlined) ");
574     }
575
576   fprintf (f, "\n  calls: ");
577   for (edge = node->callees; edge; edge = edge->next_callee)
578     {
579       fprintf (f, "%s/%i ", cgraph_node_name (edge->callee),
580                edge->callee->uid);
581       if (!edge->inline_failed)
582         fprintf(f, "(inlined) ");
583     }
584   fprintf (f, "\n");
585 }
586
587 /* Dump the callgraph.  */
588
589 void
590 dump_cgraph (FILE *f)
591 {
592   struct cgraph_node *node;
593
594   fprintf (f, "callgraph:\n\n");
595   for (node = cgraph_nodes; node; node = node->next)
596     dump_cgraph_node (f, node);
597 }
598
599 /* Returns a hash code for P.  */
600
601 static hashval_t
602 hash_varpool_node (const void *p)
603 {
604   const struct cgraph_varpool_node *n = p;
605   return (hashval_t) DECL_UID (n->decl);
606 }
607
608 /* Returns nonzero if P1 and P2 are equal.  */
609
610 static int
611 eq_varpool_node (const void *p1, const void *p2)
612 {
613   const struct cgraph_varpool_node *n1 = p1, *n2 = p2;
614   return DECL_UID (n1->decl) == DECL_UID (n2->decl);
615 }
616
617 /* Return cgraph_varpool node assigned to DECL.  Create new one when needed.  */
618 struct cgraph_varpool_node *
619 cgraph_varpool_node (tree decl)
620 {
621   struct cgraph_varpool_node key, *node, **slot;
622
623   gcc_assert (DECL_P (decl) && TREE_CODE (decl) != FUNCTION_DECL);
624
625   if (!cgraph_varpool_hash)
626     cgraph_varpool_hash = htab_create_ggc (10, hash_varpool_node,
627                                            eq_varpool_node, NULL);
628   key.decl = decl;
629   slot = (struct cgraph_varpool_node **)
630     htab_find_slot (cgraph_varpool_hash, &key, INSERT);
631   if (*slot)
632     return *slot;
633   node = ggc_alloc_cleared (sizeof (*node));
634   node->decl = decl;
635   node->next = cgraph_varpool_nodes;
636   cgraph_varpool_nodes = node;
637   *slot = node;
638   return node;
639 }
640
641 struct cgraph_varpool_node *
642 cgraph_varpool_node_for_asm (tree asmname)
643 {
644   struct cgraph_varpool_node *node;
645
646   for (node = cgraph_varpool_nodes; node ; node = node->next)
647     if (decl_assembler_name_equal (node->decl, asmname))
648       return node;
649
650   return NULL;
651 }
652
653 /* Set the DECL_ASSEMBLER_NAME and update cgraph hashtables.  */
654 void
655 change_decl_assembler_name (tree decl, tree name)
656 {
657   if (!DECL_ASSEMBLER_NAME_SET_P (decl))
658     {
659       SET_DECL_ASSEMBLER_NAME (decl, name);
660       return;
661     }
662   if (name == DECL_ASSEMBLER_NAME (decl))
663     return;
664
665   if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
666       && DECL_RTL_SET_P (decl))
667     warning ("%D renamed after being referenced in assembly", decl);
668
669   SET_DECL_ASSEMBLER_NAME (decl, name);
670 }
671
672 /* Notify finalize_compilation_unit that given node is reachable
673    or needed.  */
674 void
675 cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node)
676 {
677   if (!node->needed && node->finalized)
678     {
679       node->next_needed = cgraph_varpool_nodes_queue;
680       cgraph_varpool_nodes_queue = node;
681       notice_global_symbol (node->decl);
682     }
683   node->needed = 1;
684 }
685
686 void
687 cgraph_varpool_finalize_decl (tree decl)
688 {
689   struct cgraph_varpool_node *node = cgraph_varpool_node (decl);
690  
691   /* The first declaration of a variable that comes through this function
692      decides whether it is global (in C, has external linkage)
693      or local (in C, has internal linkage).  So do nothing more
694      if this function has already run.  */
695   if (node->finalized)
696     return;
697   if (node->needed)
698     {
699       node->next_needed = cgraph_varpool_nodes_queue;
700       cgraph_varpool_nodes_queue = node;
701       notice_global_symbol (decl);
702     }
703   node->finalized = true;
704
705   if (/* Externally visible variables must be output.  The exception are
706          COMDAT functions that must be output only when they are needed.  */
707       (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
708       /* Function whose name is output to the assembler file must be produced.
709          It is possible to assemble the name later after finalizing the function
710          and the fact is noticed in assemble_name then.  */
711       || (DECL_ASSEMBLER_NAME_SET_P (decl)
712           && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
713     {
714       cgraph_varpool_mark_needed_node (node);
715     }
716 }
717
718 bool
719 cgraph_varpool_assemble_pending_decls (void)
720 {
721   bool changed = false;
722
723   while (cgraph_varpool_nodes_queue)
724     {
725       tree decl = cgraph_varpool_nodes_queue->decl;
726       struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue;
727
728       cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed;
729       if (!TREE_ASM_WRITTEN (decl))
730         {
731           assemble_variable (decl, 0, 1, 0);
732           changed = true;
733         }
734       node->next_needed = NULL;
735     }
736   return changed;
737 }
738
739 /* Return true when the DECL can possibly be inlined.  */
740 bool
741 cgraph_function_possibly_inlined_p (tree decl)
742 {
743   if (!cgraph_global_info_ready)
744     return (DECL_INLINE (decl) && !flag_really_no_inline);
745   return DECL_POSSIBLY_INLINED (decl);
746 }
747
748 /* Create clone of E in the node N represented by CALL_EXPR the callgraph.  */
749 struct cgraph_edge *
750 cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n, tree call_expr)
751 {
752   struct cgraph_edge *new = cgraph_create_edge (n, e->callee, call_expr);
753
754   new->inline_failed = e->inline_failed;
755   return new;
756 }
757
758 /* Create node representing clone of N.  */
759 struct cgraph_node *
760 cgraph_clone_node (struct cgraph_node *n)
761 {
762   struct cgraph_node *new = cgraph_create_node ();
763   struct cgraph_edge *e;
764
765   new->decl = n->decl;
766   new->origin = n->origin;
767   if (new->origin)
768     {
769       new->next_nested = new->origin->nested;
770       new->origin->nested = new;
771     }
772   new->analyzed = n->analyzed;
773   new->local = n->local;
774   new->global = n->global;
775   new->rtl = n->rtl;
776
777   for (e = n->callees;e; e=e->next_callee)
778     cgraph_clone_edge (e, new, e->call_expr);
779
780   new->next_clone = n->next_clone;
781   n->next_clone = new;
782
783   return new;
784 }
785
786 /* NODE is no longer nested function; update cgraph accordingly.  */
787 void
788 cgraph_unnest_node (struct cgraph_node *node)
789 {
790   struct cgraph_node **node2 = &node->origin->nested;
791   gcc_assert (node->origin);
792
793   while (*node2 != node)
794     node2 = &(*node2)->next_nested;
795   *node2 = node->next_nested;
796   node->origin = NULL;
797 }
798 #include "gt-cgraph.h"