1 /* Callgraph handling code.
2 Copyright (C) 2003 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
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
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
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
24 #include "coretypes.h"
27 #include "tree-inline.h"
28 #include "langhooks.h"
38 /* The known declarations must not get garbage collected. Callgraph
39 datastructures should not get saved via PCH code since this would
40 make it difficult to extend into intra-module optimizer later. So
41 we store only the references into the array to prevent gabrage
42 collector from deleting live data. */
43 static GTY(()) varray_type known_fns
;
45 /* Hash table used to convert declarations into nodes. */
46 static htab_t cgraph_hash
= 0;
48 /* The linked list of cgraph nodes. */
49 struct cgraph_node
*cgraph_nodes
;
51 /* Number of nodes in existence. */
54 /* Set when whole unit has been analyzed so we can access global info. */
55 bool cgraph_global_info_ready
= false;
57 static struct cgraph_edge
*create_edge
PARAMS ((struct cgraph_node
*,
58 struct cgraph_node
*));
59 static void cgraph_remove_edge
PARAMS ((struct cgraph_node
*, struct cgraph_node
*));
60 static hashval_t hash_node
PARAMS ((const PTR
));
61 static int eq_node
PARAMS ((const PTR
, const PTR
));
63 /* Returns a hash code for P. */
70 htab_hash_pointer (DECL_ASSEMBLER_NAME
71 (((struct cgraph_node
*) p
)->decl
));
74 /* Returns non-zero if P1 and P2 are equal. */
81 return ((DECL_ASSEMBLER_NAME (((struct cgraph_node
*) p1
)->decl
)) ==
82 DECL_ASSEMBLER_NAME ((tree
) p2
));
85 /* Return cgraph node assigned to DECL. Create new one when needed. */
90 struct cgraph_node
*node
;
91 struct cgraph_node
**slot
;
93 if (TREE_CODE (decl
) != FUNCTION_DECL
)
98 cgraph_hash
= htab_create (10, hash_node
, eq_node
, NULL
);
99 VARRAY_TREE_INIT (known_fns
, 32, "known_fns");
103 (struct cgraph_node
**) htab_find_slot_with_hash (cgraph_hash
, decl
,
109 node
= xcalloc (sizeof (*node
), 1);
111 node
->next
= cgraph_nodes
;
113 cgraph_nodes
->previous
= node
;
114 node
->previous
= NULL
;
118 if (DECL_CONTEXT (decl
) && TREE_CODE (DECL_CONTEXT (decl
)) == FUNCTION_DECL
)
120 node
->origin
= cgraph_node (DECL_CONTEXT (decl
));
121 node
->next_nested
= node
->origin
->nested
;
122 node
->origin
->nested
= node
;
124 VARRAY_PUSH_TREE (known_fns
, decl
);
128 /* Create edge from CALLER to CALLEE in the cgraph. */
130 static struct cgraph_edge
*
131 create_edge (caller
, callee
)
132 struct cgraph_node
*caller
, *callee
;
134 struct cgraph_edge
*edge
= xmalloc (sizeof (struct cgraph_edge
));
136 edge
->caller
= caller
;
137 edge
->callee
= callee
;
138 edge
->next_caller
= callee
->callers
;
139 edge
->next_callee
= caller
->callees
;
140 caller
->callees
= edge
;
141 callee
->callers
= edge
;
145 /* Remove the edge from CALLER to CALLEE in the cgraph. */
148 cgraph_remove_edge (caller
, callee
)
149 struct cgraph_node
*caller
, *callee
;
151 struct cgraph_edge
**edge
, **edge2
;
153 for (edge
= &callee
->callers
; *edge
&& (*edge
)->caller
!= caller
;
154 edge
= &((*edge
)->next_caller
))
158 *edge
= (*edge
)->next_caller
;
159 for (edge2
= &caller
->callees
; *edge2
&& (*edge2
)->callee
!= callee
;
160 edge2
= &(*edge2
)->next_callee
)
164 *edge2
= (*edge2
)->next_callee
;
167 /* Remove the node from cgraph. */
170 cgraph_remove_node (node
)
171 struct cgraph_node
*node
;
173 while (node
->callers
)
174 cgraph_remove_edge (node
->callers
->caller
, node
);
175 while (node
->callees
)
176 cgraph_remove_edge (node
, node
->callees
->callee
);
178 cgraph_remove_node (node
->nested
);
181 struct cgraph_node
**node2
= &node
->origin
->nested
;
183 while (*node2
!= node
)
184 node2
= &(*node2
)->next_nested
;
185 *node2
= node
->next_nested
;
188 node
->previous
->next
= node
->next
;
192 node
->next
->previous
= node
->previous
;
193 DECL_SAVED_TREE (node
->decl
) = NULL
;
194 /* Do not free the structure itself so the walk over chain can continue. */
198 /* Record call from CALLER to CALLEE */
201 cgraph_record_call (caller
, callee
)
204 return create_edge (cgraph_node (caller
), cgraph_node (callee
));
208 cgraph_remove_call (caller
, callee
)
211 cgraph_remove_edge (cgraph_node (caller
), cgraph_node (callee
));
214 /* Return true when CALLER_DECL calls CALLEE_DECL. */
217 cgraph_calls_p (caller_decl
, callee_decl
)
218 tree caller_decl
, callee_decl
;
220 struct cgraph_node
*caller
= cgraph_node (caller_decl
);
221 struct cgraph_node
*callee
= cgraph_node (callee_decl
);
222 struct cgraph_edge
*edge
;
224 for (edge
= callee
->callers
; edge
&& (edge
)->caller
!= caller
;
225 edge
= (edge
->next_caller
))
230 /* Return local info for the compiled function. */
232 struct cgraph_local_info
*
233 cgraph_local_info (decl
)
236 struct cgraph_node
*node
;
237 if (TREE_CODE (decl
) != FUNCTION_DECL
)
239 node
= cgraph_node (decl
);
243 /* Return local info for the compiled function. */
245 struct cgraph_global_info
*
246 cgraph_global_info (decl
)
249 struct cgraph_node
*node
;
250 if (TREE_CODE (decl
) != FUNCTION_DECL
|| !cgraph_global_info_ready
)
252 node
= cgraph_node (decl
);
253 return &node
->global
;
256 /* Return local info for the compiled function. */
258 struct cgraph_rtl_info
*
259 cgraph_rtl_info (decl
)
262 struct cgraph_node
*node
;
263 if (TREE_CODE (decl
) != FUNCTION_DECL
)
265 node
= cgraph_node (decl
);
266 if (decl
!= current_function_decl
267 && !TREE_ASM_WRITTEN (node
->decl
))
273 /* Dump the callgraph. */
279 struct cgraph_node
*node
;
281 fprintf (f
, "\nCallgraph:\n\n");
282 for (node
= cgraph_nodes
; node
; node
= node
->next
)
284 struct cgraph_edge
*edge
;
285 fprintf (f
, "%s", IDENTIFIER_POINTER (DECL_NAME (node
->decl
)));
287 fprintf (f
, " nested in: %s",
288 IDENTIFIER_POINTER (DECL_NAME (node
->origin
->decl
)));
290 fprintf (f
, " needed");
291 else if (node
->reachable
)
292 fprintf (f
, " reachable");
293 if (DECL_SAVED_TREE (node
->decl
))
294 fprintf (f
, " tree");
296 fprintf (f
, "\n called by :");
297 for (edge
= node
->callers
; edge
; edge
= edge
->next_caller
)
299 IDENTIFIER_POINTER (DECL_NAME (edge
->caller
->decl
)));
301 fprintf (f
, "\n calls: ");
302 for (edge
= node
->callees
; edge
; edge
= edge
->next_callee
)
304 IDENTIFIER_POINTER (DECL_NAME (edge
->callee
->decl
)));
309 #include "gt-cgraph.h"