OSDN Git Service

* cgraphbuild.c (record_eh_tables): Mark personality function as having
[pf3gnuchains/gcc-fork.git] / gcc / cgraphbuild.c
1 /* Callgraph construction.
2    Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3    Free Software Foundation, Inc.
4    Contributed by Jan Hubicka
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "tree-flow.h"
28 #include "langhooks.h"
29 #include "pointer-set.h"
30 #include "cgraph.h"
31 #include "intl.h"
32 #include "gimple.h"
33 #include "tree-pass.h"
34 #include "ipa-utils.h"
35 #include "except.h"
36 #include "ipa-inline.h"
37
38 /* Context of record_reference.  */
39 struct record_reference_ctx
40 {
41   bool only_vars;
42   struct varpool_node *varpool_node;
43 };
44
45 /* Walk tree and record all calls and references to functions/variables.
46    Called via walk_tree: TP is pointer to tree to be examined.
47    When DATA is non-null, record references to callgraph.
48    */
49
50 static tree
51 record_reference (tree *tp, int *walk_subtrees, void *data)
52 {
53   tree t = *tp;
54   tree decl;
55   struct record_reference_ctx *ctx = (struct record_reference_ctx *)data;
56
57   t = canonicalize_constructor_val (t);
58   if (!t)
59     t = *tp;
60   else if (t != *tp)
61     *tp = t;
62
63   switch (TREE_CODE (t))
64     {
65     case VAR_DECL:
66     case FUNCTION_DECL:
67       gcc_unreachable ();
68       break;
69
70     case FDESC_EXPR:
71     case ADDR_EXPR:
72       /* Record dereferences to the functions.  This makes the
73          functions reachable unconditionally.  */
74       decl = get_base_var (*tp);
75       if (TREE_CODE (decl) == FUNCTION_DECL)
76         {
77           struct cgraph_node *node = cgraph_get_create_node (decl);
78           if (!ctx->only_vars)
79             cgraph_mark_address_taken_node (node);
80           ipa_record_reference (NULL, ctx->varpool_node, node, NULL,
81                                 IPA_REF_ADDR, NULL);
82         }
83
84       if (TREE_CODE (decl) == VAR_DECL)
85         {
86           struct varpool_node *vnode = varpool_node (decl);
87           if (lang_hooks.callgraph.analyze_expr)
88             lang_hooks.callgraph.analyze_expr (&decl, walk_subtrees);
89           varpool_mark_needed_node (vnode);
90           if (vnode->alias && vnode->extra_name)
91             vnode = vnode->extra_name;
92           ipa_record_reference (NULL, ctx->varpool_node,
93                                 NULL, vnode,
94                                 IPA_REF_ADDR, NULL);
95         }
96       *walk_subtrees = 0;
97       break;
98
99     default:
100       /* Save some cycles by not walking types and declaration as we
101          won't find anything useful there anyway.  */
102       if (IS_TYPE_OR_DECL_P (*tp))
103         {
104           *walk_subtrees = 0;
105           break;
106         }
107
108       if ((unsigned int) TREE_CODE (t) >= LAST_AND_UNUSED_TREE_CODE)
109         return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees);
110       break;
111     }
112
113   return NULL_TREE;
114 }
115
116 /* Record references to typeinfos in the type list LIST.  */
117
118 static void
119 record_type_list (struct cgraph_node *node, tree list)
120 {
121   for (; list; list = TREE_CHAIN (list))
122     {
123       tree type = TREE_VALUE (list);
124       
125       if (TYPE_P (type))
126         type = lookup_type_for_runtime (type);
127       STRIP_NOPS (type);
128       if (TREE_CODE (type) == ADDR_EXPR)
129         {
130           type = TREE_OPERAND (type, 0);
131           if (TREE_CODE (type) == VAR_DECL)
132             {
133               struct varpool_node *vnode = varpool_node (type);
134               varpool_mark_needed_node (vnode);
135               ipa_record_reference (node, NULL,
136                                     NULL, vnode,
137                                     IPA_REF_ADDR, NULL);
138             }
139         }
140     }
141 }
142
143 /* Record all references we will introduce by producing EH tables
144    for NODE.  */
145
146 static void
147 record_eh_tables (struct cgraph_node *node, struct function *fun)
148 {
149   eh_region i;
150
151   if (DECL_FUNCTION_PERSONALITY (node->decl))
152     {
153       struct cgraph_node *per_node;
154
155       per_node = cgraph_get_create_node (DECL_FUNCTION_PERSONALITY (node->decl));
156       ipa_record_reference (node, NULL, per_node, NULL, IPA_REF_ADDR, NULL);
157       cgraph_mark_address_taken_node (per_node);
158     }
159
160   i = fun->eh->region_tree;
161   if (!i)
162     return;
163
164   while (1)
165     {
166       switch (i->type)
167         {
168         case ERT_CLEANUP:
169         case ERT_MUST_NOT_THROW:
170           break;
171
172         case ERT_TRY:
173           {
174             eh_catch c;
175             for (c = i->u.eh_try.first_catch; c; c = c->next_catch)
176               record_type_list (node, c->type_list);
177           }
178           break;
179
180         case ERT_ALLOWED_EXCEPTIONS:
181           record_type_list (node, i->u.allowed.type_list);
182           break;
183         }
184       /* If there are sub-regions, process them.  */
185       if (i->inner)
186         i = i->inner;
187       /* If there are peers, process them.  */
188       else if (i->next_peer)
189         i = i->next_peer;
190       /* Otherwise, step back up the tree to the next peer.  */
191       else
192         {
193           do
194             {
195               i = i->outer;
196               if (i == NULL)
197                 return;
198             }
199           while (i->next_peer == NULL);
200           i = i->next_peer;
201         }
202     }
203 }
204
205 /* Reset inlining information of all incoming call edges of NODE.  */
206
207 void
208 reset_inline_failed (struct cgraph_node *node)
209 {
210   struct cgraph_edge *e;
211
212   for (e = node->callers; e; e = e->next_caller)
213     {
214       e->callee->global.inlined_to = NULL;
215       initialize_inline_failed (e);
216     }
217 }
218
219 /* Computes the frequency of the call statement so that it can be stored in
220    cgraph_edge.  BB is the basic block of the call statement.  */
221 int
222 compute_call_stmt_bb_frequency (tree decl, basic_block bb)
223 {
224   int entry_freq = ENTRY_BLOCK_PTR_FOR_FUNCTION
225                      (DECL_STRUCT_FUNCTION (decl))->frequency;
226   int freq = bb->frequency;
227
228   if (profile_status_for_function (DECL_STRUCT_FUNCTION (decl)) == PROFILE_ABSENT)
229     return CGRAPH_FREQ_BASE;
230
231   if (!entry_freq)
232     entry_freq = 1, freq++;
233
234   freq = freq * CGRAPH_FREQ_BASE / entry_freq;
235   if (freq > CGRAPH_FREQ_MAX)
236     freq = CGRAPH_FREQ_MAX;
237
238   return freq;
239 }
240
241 /* Mark address taken in STMT.  */
242
243 static bool
244 mark_address (gimple stmt, tree addr, void *data)
245 {
246   addr = get_base_address (addr);
247   if (TREE_CODE (addr) == FUNCTION_DECL)
248     {
249       struct cgraph_node *node = cgraph_get_create_node (addr);
250       cgraph_mark_address_taken_node (node);
251       ipa_record_reference ((struct cgraph_node *)data, NULL,
252                             node, NULL,
253                             IPA_REF_ADDR, stmt);
254     }
255   else if (addr && TREE_CODE (addr) == VAR_DECL
256            && (TREE_STATIC (addr) || DECL_EXTERNAL (addr)))
257     {
258       struct varpool_node *vnode = varpool_node (addr);
259       int walk_subtrees;
260
261       if (lang_hooks.callgraph.analyze_expr)
262         lang_hooks.callgraph.analyze_expr (&addr, &walk_subtrees);
263       varpool_mark_needed_node (vnode);
264       if (vnode->alias && vnode->extra_name)
265         vnode = vnode->extra_name;
266       ipa_record_reference ((struct cgraph_node *)data, NULL,
267                             NULL, vnode,
268                             IPA_REF_ADDR, stmt);
269     }
270
271   return false;
272 }
273
274 /* Mark load of T.  */
275
276 static bool
277 mark_load (gimple stmt, tree t, void *data)
278 {
279   t = get_base_address (t);
280   if (t && TREE_CODE (t) == FUNCTION_DECL)
281     {
282       /* ??? This can happen on platforms with descriptors when these are
283          directly manipulated in the code.  Pretend that it's an address.  */
284       struct cgraph_node *node = cgraph_get_create_node (t);
285       cgraph_mark_address_taken_node (node);
286       ipa_record_reference ((struct cgraph_node *)data, NULL,
287                             node, NULL,
288                             IPA_REF_ADDR, stmt);
289     }
290   else if (t && TREE_CODE (t) == VAR_DECL
291            && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
292     {
293       struct varpool_node *vnode = varpool_node (t);
294       int walk_subtrees;
295
296       if (lang_hooks.callgraph.analyze_expr)
297         lang_hooks.callgraph.analyze_expr (&t, &walk_subtrees);
298       varpool_mark_needed_node (vnode);
299       if (vnode->alias && vnode->extra_name)
300         vnode = vnode->extra_name;
301       ipa_record_reference ((struct cgraph_node *)data, NULL,
302                             NULL, vnode,
303                             IPA_REF_LOAD, stmt);
304     }
305   return false;
306 }
307
308 /* Mark store of T.  */
309
310 static bool
311 mark_store (gimple stmt, tree t, void *data)
312 {
313   t = get_base_address (t);
314   if (t && TREE_CODE (t) == VAR_DECL
315       && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
316     {
317       struct varpool_node *vnode = varpool_node (t);
318       int walk_subtrees;
319
320       if (lang_hooks.callgraph.analyze_expr)
321         lang_hooks.callgraph.analyze_expr (&t, &walk_subtrees);
322       varpool_mark_needed_node (vnode);
323       if (vnode->alias && vnode->extra_name)
324         vnode = vnode->extra_name;
325       ipa_record_reference ((struct cgraph_node *)data, NULL,
326                             NULL, vnode,
327                             IPA_REF_STORE, stmt);
328      }
329   return false;
330 }
331
332 /* Create cgraph edges for function calls.
333    Also look for functions and variables having addresses taken.  */
334
335 static unsigned int
336 build_cgraph_edges (void)
337 {
338   basic_block bb;
339   struct cgraph_node *node = cgraph_get_node (current_function_decl);
340   struct pointer_set_t *visited_nodes = pointer_set_create ();
341   gimple_stmt_iterator gsi;
342   tree decl;
343   unsigned ix;
344
345   /* Create the callgraph edges and record the nodes referenced by the function.
346      body.  */
347   FOR_EACH_BB (bb)
348     {
349       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
350         {
351           gimple stmt = gsi_stmt (gsi);
352           tree decl;
353
354           if (is_gimple_call (stmt))
355             {
356               int freq = compute_call_stmt_bb_frequency (current_function_decl,
357                                                          bb);
358               decl = gimple_call_fndecl (stmt);
359               if (decl)
360                 cgraph_create_edge (node, cgraph_get_create_node (decl),
361                                     stmt, bb->count, freq);
362               else
363                 cgraph_create_indirect_edge (node, stmt,
364                                              gimple_call_flags (stmt),
365                                              bb->count, freq);
366             }
367           walk_stmt_load_store_addr_ops (stmt, node, mark_load,
368                                          mark_store, mark_address);
369           if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
370               && gimple_omp_parallel_child_fn (stmt))
371             {
372               tree fn = gimple_omp_parallel_child_fn (stmt);
373               ipa_record_reference (node, NULL, cgraph_get_create_node (fn),
374                                     NULL, IPA_REF_ADDR, stmt);
375             }
376           if (gimple_code (stmt) == GIMPLE_OMP_TASK)
377             {
378               tree fn = gimple_omp_task_child_fn (stmt);
379               if (fn)
380                 ipa_record_reference (node, NULL, cgraph_get_create_node (fn),
381                                       NULL, IPA_REF_ADDR, stmt);
382               fn = gimple_omp_task_copy_fn (stmt);
383               if (fn)
384                 ipa_record_reference (node, NULL, cgraph_get_create_node (fn),
385                                       NULL, IPA_REF_ADDR, stmt);
386             }
387         }
388       for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi))
389         walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node,
390                                        mark_load, mark_store, mark_address);
391    }
392
393   /* Look for initializers of constant variables and private statics.  */
394   FOR_EACH_LOCAL_DECL (cfun, ix, decl)
395     if (TREE_CODE (decl) == VAR_DECL
396         && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl)))
397       varpool_finalize_decl (decl);
398   record_eh_tables (node, cfun);
399
400   pointer_set_destroy (visited_nodes);
401   return 0;
402 }
403
404 struct gimple_opt_pass pass_build_cgraph_edges =
405 {
406  {
407   GIMPLE_PASS,
408   "*build_cgraph_edges",                        /* name */
409   NULL,                                 /* gate */
410   build_cgraph_edges,                   /* execute */
411   NULL,                                 /* sub */
412   NULL,                                 /* next */
413   0,                                    /* static_pass_number */
414   TV_NONE,                              /* tv_id */
415   PROP_cfg,                             /* properties_required */
416   0,                                    /* properties_provided */
417   0,                                    /* properties_destroyed */
418   0,                                    /* todo_flags_start */
419   0                                     /* todo_flags_finish */
420  }
421 };
422
423 /* Record references to functions and other variables present in the
424    initial value of DECL, a variable.
425    When ONLY_VARS is true, we mark needed only variables, not functions.  */
426
427 void
428 record_references_in_initializer (tree decl, bool only_vars)
429 {
430   struct pointer_set_t *visited_nodes = pointer_set_create ();
431   struct varpool_node *node = varpool_node (decl);
432   struct record_reference_ctx ctx = {false, NULL};
433
434   ctx.varpool_node = node;
435   ctx.only_vars = only_vars;
436   walk_tree (&DECL_INITIAL (decl), record_reference,
437              &ctx, visited_nodes);
438   pointer_set_destroy (visited_nodes);
439 }
440
441 /* Rebuild cgraph edges for current function node.  This needs to be run after
442    passes that don't update the cgraph.  */
443
444 unsigned int
445 rebuild_cgraph_edges (void)
446 {
447   basic_block bb;
448   struct cgraph_node *node = cgraph_get_node (current_function_decl);
449   gimple_stmt_iterator gsi;
450
451   cgraph_node_remove_callees (node);
452   ipa_remove_all_references (&node->ref_list);
453
454   node->count = ENTRY_BLOCK_PTR->count;
455
456   FOR_EACH_BB (bb)
457     {
458       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
459         {
460           gimple stmt = gsi_stmt (gsi);
461           tree decl;
462
463           if (is_gimple_call (stmt))
464             {
465               int freq = compute_call_stmt_bb_frequency (current_function_decl,
466                                                          bb);
467               decl = gimple_call_fndecl (stmt);
468               if (decl)
469                 cgraph_create_edge (node, cgraph_get_create_node (decl), stmt,
470                                     bb->count, freq);
471               else
472                 cgraph_create_indirect_edge (node, stmt,
473                                              gimple_call_flags (stmt),
474                                              bb->count, freq);
475             }
476           walk_stmt_load_store_addr_ops (stmt, node, mark_load,
477                                          mark_store, mark_address);
478
479         }
480       for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi))
481         walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node,
482                                        mark_load, mark_store, mark_address);
483     }
484   record_eh_tables (node, cfun);
485   gcc_assert (!node->global.inlined_to);
486
487   return 0;
488 }
489
490 /* Rebuild cgraph edges for current function node.  This needs to be run after
491    passes that don't update the cgraph.  */
492
493 void
494 cgraph_rebuild_references (void)
495 {
496   basic_block bb;
497   struct cgraph_node *node = cgraph_get_node (current_function_decl);
498   gimple_stmt_iterator gsi;
499
500   ipa_remove_all_references (&node->ref_list);
501
502   node->count = ENTRY_BLOCK_PTR->count;
503
504   FOR_EACH_BB (bb)
505     {
506       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
507         {
508           gimple stmt = gsi_stmt (gsi);
509
510           walk_stmt_load_store_addr_ops (stmt, node, mark_load,
511                                          mark_store, mark_address);
512
513         }
514       for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi))
515         walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node,
516                                        mark_load, mark_store, mark_address);
517     }
518   record_eh_tables (node, cfun);
519 }
520
521 struct gimple_opt_pass pass_rebuild_cgraph_edges =
522 {
523  {
524   GIMPLE_PASS,
525   "*rebuild_cgraph_edges",              /* name */
526   NULL,                                 /* gate */
527   rebuild_cgraph_edges,                 /* execute */
528   NULL,                                 /* sub */
529   NULL,                                 /* next */
530   0,                                    /* static_pass_number */
531   TV_CGRAPH,                            /* tv_id */
532   PROP_cfg,                             /* properties_required */
533   0,                                    /* properties_provided */
534   0,                                    /* properties_destroyed */
535   0,                                    /* todo_flags_start */
536   0,                                    /* todo_flags_finish */
537  }
538 };
539
540
541 static unsigned int
542 remove_cgraph_callee_edges (void)
543 {
544   cgraph_node_remove_callees (cgraph_get_node (current_function_decl));
545   return 0;
546 }
547
548 struct gimple_opt_pass pass_remove_cgraph_callee_edges =
549 {
550  {
551   GIMPLE_PASS,
552   "*remove_cgraph_callee_edges",                /* name */
553   NULL,                                 /* gate */
554   remove_cgraph_callee_edges,           /* execute */
555   NULL,                                 /* sub */
556   NULL,                                 /* next */
557   0,                                    /* static_pass_number */
558   TV_NONE,                              /* tv_id */
559   0,                                    /* properties_required */
560   0,                                    /* properties_provided */
561   0,                                    /* properties_destroyed */
562   0,                                    /* todo_flags_start */
563   0,                                    /* todo_flags_finish */
564  }
565 };