OSDN Git Service

* gcc/doc/extended.texi: Replace the dash character with
[pf3gnuchains/gcc-fork.git] / gcc / cgraphbuild.c
1 /* Callgraph construction.
2    Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
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
35 /* Walk tree and record all calls and references to functions/variables.
36    Called via walk_tree: TP is pointer to tree to be examined.  
37    When DATA is non-null, record references to callgraph.
38    */
39
40 static tree
41 record_reference (tree *tp, int *walk_subtrees, void *data)
42 {
43   tree t = *tp;
44   tree decl;
45   bool do_callgraph = data != NULL;
46
47   switch (TREE_CODE (t))
48     {
49     case VAR_DECL:
50       if (TREE_STATIC (t) || DECL_EXTERNAL (t))
51         {
52           varpool_mark_needed_node (varpool_node (t));
53           if (lang_hooks.callgraph.analyze_expr)
54             return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees);
55         }
56       break;
57
58     case FDESC_EXPR:
59     case ADDR_EXPR:
60       /* Record dereferences to the functions.  This makes the
61          functions reachable unconditionally.  */
62       decl = TREE_OPERAND (*tp, 0);
63       if (TREE_CODE (decl) == FUNCTION_DECL && do_callgraph)
64         cgraph_mark_address_taken_node (cgraph_node (decl));
65       break;
66
67     default:
68       /* Save some cycles by not walking types and declaration as we
69          won't find anything useful there anyway.  */
70       if (IS_TYPE_OR_DECL_P (*tp))
71         {
72           *walk_subtrees = 0;
73           break;
74         }
75
76       if ((unsigned int) TREE_CODE (t) >= LAST_AND_UNUSED_TREE_CODE)
77         return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees);
78       break;
79     }
80
81   return NULL_TREE;
82 }
83
84 /* Reset inlining information of all incoming call edges of NODE.  */
85
86 void
87 reset_inline_failed (struct cgraph_node *node)
88 {
89   struct cgraph_edge *e;
90
91   for (e = node->callers; e; e = e->next_caller)
92     {
93       e->callee->global.inlined_to = NULL;
94       if (!node->analyzed)
95         e->inline_failed = CIF_BODY_NOT_AVAILABLE;
96       else if (node->local.redefined_extern_inline)
97         e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
98       else if (!node->local.inlinable)
99         e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
100       else if (e->call_stmt_cannot_inline_p)
101         e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
102       else
103         e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
104     }
105 }
106
107 /* Computes the frequency of the call statement so that it can be stored in
108    cgraph_edge.  BB is the basic block of the call statement.  */
109 int
110 compute_call_stmt_bb_frequency (tree decl, basic_block bb)
111 {
112   int entry_freq = ENTRY_BLOCK_PTR->frequency;
113   int freq = bb->frequency;
114
115   if (profile_status_for_function (DECL_STRUCT_FUNCTION (decl)) == PROFILE_ABSENT)
116     return CGRAPH_FREQ_BASE;
117
118   if (!entry_freq)
119     entry_freq = 1, freq++;
120
121   freq = freq * CGRAPH_FREQ_BASE / entry_freq;
122   if (freq > CGRAPH_FREQ_MAX)
123     freq = CGRAPH_FREQ_MAX;
124
125   return freq;
126 }
127
128 /* Create cgraph edges for function calls.
129    Also look for functions and variables having addresses taken.  */
130
131 static unsigned int
132 build_cgraph_edges (void)
133 {
134   basic_block bb;
135   struct cgraph_node *node = cgraph_node (current_function_decl);
136   struct pointer_set_t *visited_nodes = pointer_set_create ();
137   gimple_stmt_iterator gsi;
138   tree step;
139
140   /* Create the callgraph edges and record the nodes referenced by the function.
141      body.  */
142   FOR_EACH_BB (bb)
143     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
144       {
145         gimple stmt = gsi_stmt (gsi);
146         tree decl;
147
148         if (is_gimple_call (stmt) && (decl = gimple_call_fndecl (stmt)))
149           {
150             size_t i;
151             size_t n = gimple_call_num_args (stmt);
152             cgraph_create_edge (node, cgraph_node (decl), stmt,
153                                 bb->count, compute_call_stmt_bb_frequency (current_function_decl, bb),
154                                 bb->loop_depth);
155             for (i = 0; i < n; i++)
156               walk_tree (gimple_call_arg_ptr (stmt, i), record_reference,
157                          node, visited_nodes);
158             if (gimple_call_lhs (stmt))
159               walk_tree (gimple_call_lhs_ptr (stmt), record_reference, node,
160                          visited_nodes);
161           }
162         else
163           {
164             struct walk_stmt_info wi;
165             memset (&wi, 0, sizeof (wi));
166             wi.info = node;
167             wi.pset = visited_nodes;
168             walk_gimple_op (stmt, record_reference, &wi);
169             if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
170                 && gimple_omp_parallel_child_fn (stmt))
171               {
172                 tree fn = gimple_omp_parallel_child_fn (stmt);
173                 cgraph_mark_needed_node (cgraph_node (fn));
174               }
175             if (gimple_code (stmt) == GIMPLE_OMP_TASK)
176               {
177                 tree fn = gimple_omp_task_child_fn (stmt);
178                 if (fn)
179                   cgraph_mark_needed_node (cgraph_node (fn));
180                 fn = gimple_omp_task_copy_fn (stmt);
181                 if (fn)
182                   cgraph_mark_needed_node (cgraph_node (fn));
183               }
184           }
185       }
186
187   /* Look for initializers of constant variables and private statics.  */
188   for (step = cfun->local_decls;
189        step;
190        step = TREE_CHAIN (step))
191     {
192       tree decl = TREE_VALUE (step);
193       if (TREE_CODE (decl) == VAR_DECL
194           && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl)))
195         varpool_finalize_decl (decl);
196       else if (TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
197         walk_tree (&DECL_INITIAL (decl), record_reference, node, visited_nodes);
198     }
199
200   pointer_set_destroy (visited_nodes);
201   return 0;
202 }
203
204 struct gimple_opt_pass pass_build_cgraph_edges =
205 {
206  {
207   GIMPLE_PASS,
208   NULL,                                 /* name */
209   NULL,                                 /* gate */
210   build_cgraph_edges,                   /* execute */
211   NULL,                                 /* sub */
212   NULL,                                 /* next */
213   0,                                    /* static_pass_number */
214   TV_NONE,                              /* tv_id */
215   PROP_cfg,                             /* properties_required */
216   0,                                    /* properties_provided */
217   0,                                    /* properties_destroyed */
218   0,                                    /* todo_flags_start */
219   0                                     /* todo_flags_finish */
220  }
221 };
222
223 /* Record references to functions and other variables present in the
224    initial value of DECL, a variable.  
225    When ONLY_VARS is true, we mark needed only variables, not functions.  */
226
227 void
228 record_references_in_initializer (tree decl, bool only_vars)
229 {
230   struct pointer_set_t *visited_nodes = pointer_set_create ();
231   walk_tree (&DECL_INITIAL (decl), record_reference, 
232             only_vars ? NULL : decl, visited_nodes);
233   pointer_set_destroy (visited_nodes);
234 }
235
236 /* Rebuild cgraph edges for current function node.  This needs to be run after
237    passes that don't update the cgraph.  */
238
239 unsigned int
240 rebuild_cgraph_edges (void)
241 {
242   basic_block bb;
243   struct cgraph_node *node = cgraph_node (current_function_decl);
244   gimple_stmt_iterator gsi;
245
246   cgraph_node_remove_callees (node);
247
248   node->count = ENTRY_BLOCK_PTR->count;
249
250   FOR_EACH_BB (bb)
251     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
252       {
253         gimple stmt = gsi_stmt (gsi);
254         tree decl;
255
256         if (is_gimple_call (stmt) && (decl = gimple_call_fndecl (stmt)))
257           cgraph_create_edge (node, cgraph_node (decl), stmt,
258                               bb->count,
259                               compute_call_stmt_bb_frequency
260                                 (current_function_decl, bb),
261                               bb->loop_depth);
262
263       }
264   gcc_assert (!node->global.inlined_to);
265
266   return 0;
267 }
268
269 struct gimple_opt_pass pass_rebuild_cgraph_edges =
270 {
271  {
272   GIMPLE_PASS,
273   NULL,                                 /* name */
274   NULL,                                 /* gate */
275   rebuild_cgraph_edges,                 /* execute */
276   NULL,                                 /* sub */
277   NULL,                                 /* next */
278   0,                                    /* static_pass_number */
279   TV_NONE,                              /* tv_id */
280   PROP_cfg,                             /* properties_required */
281   0,                                    /* properties_provided */
282   0,                                    /* properties_destroyed */
283   0,                                    /* todo_flags_start */
284   0,                                    /* todo_flags_finish */
285  }
286 };
287
288
289 static unsigned int
290 remove_cgraph_callee_edges (void)
291 {
292   cgraph_node_remove_callees (cgraph_node (current_function_decl));
293   return 0;
294 }
295
296 struct gimple_opt_pass pass_remove_cgraph_callee_edges =
297 {
298  {
299   GIMPLE_PASS,
300   NULL,                                 /* name */
301   NULL,                                 /* gate */
302   remove_cgraph_callee_edges,           /* execute */
303   NULL,                                 /* sub */
304   NULL,                                 /* next */
305   0,                                    /* static_pass_number */
306   TV_NONE,                              /* tv_id */
307   0,                                    /* properties_required */
308   0,                                    /* properties_provided */
309   0,                                    /* properties_destroyed */
310   0,                                    /* todo_flags_start */
311   0,                                    /* todo_flags_finish */
312  }
313 };