OSDN Git Service

* cgraph.c (cgraph_node): Do not confuse nested functions and methods.
[pf3gnuchains/gcc-fork.git] / gcc / cgraph.c
1 /* Callgraph handling code.
2    Copyright (C) 2003 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 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "tree-inline.h"
28 #include "langhooks.h"
29 #include "hashtab.h"
30 #include "toplev.h"
31 #include "flags.h"
32 #include "ggc.h"
33 #include "debug.h"
34 #include "target.h"
35 #include "cgraph.h"
36
37 /* Hash table used to convert declarations into nodes.  */
38 static htab_t cgraph_hash = 0;
39
40 /* The linked list of cgraph nodes.  */
41 struct cgraph_node *cgraph_nodes;
42
43 /* Number of nodes in existence.  */
44 int cgraph_n_nodes;
45
46 /* Set when whole unit has been analyzed so we can access global info.  */
47 bool cgraph_global_info_ready = false;
48
49 static struct cgraph_edge *create_edge PARAMS ((struct cgraph_node *,
50                                                 struct cgraph_node *));
51 static void remove_edge PARAMS ((struct cgraph_node *, struct cgraph_node *));
52 static hashval_t hash_node PARAMS ((const PTR));
53 static int eq_node PARAMS ((const PTR, const PTR));
54
55 /* Returns a hash code for P.  */
56
57 static hashval_t
58 hash_node (p)
59      const PTR p;
60 {
61   return (hashval_t)
62     htab_hash_pointer (DECL_ASSEMBLER_NAME
63                        (((struct cgraph_node *) p)->decl));
64 }
65
66 /* Returns non-zero if P1 and P2 are equal.  */
67
68 static int
69 eq_node (p1, p2)
70      const PTR p1;
71      const PTR p2;
72 {
73   return ((DECL_ASSEMBLER_NAME (((struct cgraph_node *) p1)->decl)) ==
74           DECL_ASSEMBLER_NAME ((tree) p2));
75 }
76
77 /* Return cgraph node assigned to DECL.  Create new one when needed.  */
78 struct cgraph_node *
79 cgraph_node (decl)
80      tree decl;
81 {
82   struct cgraph_node *node;
83   struct cgraph_node **slot;
84
85   if (!cgraph_hash)
86     cgraph_hash = htab_create (10, hash_node, eq_node, NULL);
87
88   slot =
89     (struct cgraph_node **) htab_find_slot_with_hash (cgraph_hash, decl,
90                                                       htab_hash_pointer
91                                                       (DECL_ASSEMBLER_NAME
92                                                        (decl)), 1);
93   if (*slot)
94     return *slot;
95   node = xcalloc (sizeof (*node), 1);
96   node->decl = decl;
97   node->next = cgraph_nodes;
98   cgraph_nodes = node;
99   cgraph_n_nodes++;
100   *slot = node;
101   if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
102     {
103       node->origin = cgraph_node (DECL_CONTEXT (decl));
104       node->next_nested = node->origin->nested;
105       node->origin->nested = node;
106     }
107   return node;
108 }
109
110 /* Create edge from CALLER to CALLEE in the cgraph.  */
111
112 static struct cgraph_edge *
113 create_edge (caller, callee)
114      struct cgraph_node *caller, *callee;
115 {
116   struct cgraph_edge *edge = xmalloc (sizeof (struct cgraph_edge));
117
118   edge->caller = caller;
119   edge->callee = callee;
120   edge->next_caller = callee->callers;
121   edge->next_callee = caller->callees;
122   caller->callees = edge;
123   callee->callers = edge;
124   return edge;
125 }
126
127 /* Remove the edge from CALLER to CALLEE in the cgraph.  */
128
129 static void
130 remove_edge (caller, callee)
131      struct cgraph_node *caller, *callee;
132 {
133   struct cgraph_edge **edge, **edge2;
134
135   for (edge = &callee->callers; *edge && (*edge)->caller != caller;
136        edge = &((*edge)->next_caller))
137     continue;
138   if (!*edge)
139     abort ();
140   *edge = (*edge)->next_caller;
141   for (edge2 = &caller->callees; *edge2 && (*edge2)->callee != callee;
142        edge2 = &(*edge2)->next_callee)
143     continue;
144   if (!*edge2)
145     abort ();
146   *edge2 = (*edge2)->next_callee;
147 }
148
149 /* Record call from CALLER to CALLEE  */
150
151 struct cgraph_edge *
152 cgraph_record_call (caller, callee)
153      tree caller, callee;
154 {
155   return create_edge (cgraph_node (caller), cgraph_node (callee));
156 }
157
158 void
159 cgraph_remove_call (caller, callee)
160      tree caller, callee;
161 {
162   remove_edge (cgraph_node (caller), cgraph_node (callee));
163 }
164
165 /* Return true when CALLER_DECL calls CALLEE_DECL.  */
166
167 bool
168 cgraph_calls_p (caller_decl, callee_decl)
169      tree caller_decl, callee_decl;
170 {
171   struct cgraph_node *caller = cgraph_node (caller_decl);
172   struct cgraph_node *callee = cgraph_node (callee_decl);
173   struct cgraph_edge *edge;
174
175   for (edge = callee->callers; edge && (edge)->caller != caller;
176        edge = (edge->next_caller))
177     continue;
178   return edge != NULL;
179 }
180
181 /* Return local info for the compiled function.  */
182
183 struct cgraph_local_info *
184 cgraph_local_info (decl)
185      tree decl;
186 {
187   struct cgraph_node *node;
188   if (TREE_CODE (decl) != FUNCTION_DECL)
189     abort ();
190   node = cgraph_node (decl);
191   return &node->local;
192 }
193
194 /* Return local info for the compiled function.  */
195
196 struct cgraph_global_info *
197 cgraph_global_info (decl)
198      tree decl;
199 {
200   struct cgraph_node *node;
201   if (TREE_CODE (decl) != FUNCTION_DECL || !cgraph_global_info_ready)
202     abort ();
203   node = cgraph_node (decl);
204   return &node->global;
205 }
206
207 /* Return local info for the compiled function.  */
208
209 struct cgraph_rtl_info *
210 cgraph_rtl_info (decl)
211      tree decl;
212 {
213   struct cgraph_node *node;
214   if (TREE_CODE (decl) != FUNCTION_DECL)
215     abort ();
216   node = cgraph_node (decl);
217   if (decl != current_function_decl
218       && !TREE_ASM_WRITTEN (node->decl))
219     return NULL;
220   return &node->rtl;
221 }
222
223
224 /* Dump the callgraph.  */
225
226 void
227 dump_cgraph (f)
228      FILE *f;
229 {
230   struct cgraph_node *node;
231
232   fprintf (f, "\nCallgraph:\n\n");
233   for (node = cgraph_nodes; node; node = node->next)
234     {
235       struct cgraph_edge *edge;
236       fprintf (f, "%s", IDENTIFIER_POINTER (DECL_NAME (node->decl)));
237       if (node->origin)
238         fprintf (f, " nested in: %s",
239                  IDENTIFIER_POINTER (DECL_NAME (node->origin->decl)));
240       if (node->needed)
241         fprintf (f, " needed");
242       else if (node->reachable)
243         fprintf (f, " reachable");
244       if (DECL_SAVED_TREE (node->decl))
245         fprintf (f, " tree");
246
247       fprintf (f, "\n  called by :");
248       for (edge = node->callers; edge; edge = edge->next_caller)
249         fprintf (f, "%s ",
250                  IDENTIFIER_POINTER (DECL_NAME (edge->caller->decl)));
251
252       fprintf (f, "\n  calls: ");
253       for (edge = node->callees; edge; edge = edge->next_callee)
254         fprintf (f, "%s ",
255                  IDENTIFIER_POINTER (DECL_NAME (edge->callee->decl)));
256       fprintf (f, "\n");
257     }
258 }