OSDN Git Service

libcpp
[pf3gnuchains/gcc-fork.git] / gcc / ipa-prop.c
1 /* Interprocedural analyses.
2    Copyright (C) 2005, 2007 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tree.h"
24 #include "langhooks.h"
25 #include "ggc.h"
26 #include "target.h"
27 #include "cgraph.h"
28 #include "ipa-prop.h"
29 #include "tree-flow.h"
30 #include "tree-pass.h"
31 #include "flags.h"
32 #include "timevar.h"
33
34 /* Initialize worklist to contain all functions.  */
35 struct ipa_func_list *
36 ipa_init_func_list (void)
37 {
38   struct cgraph_node *node;
39   struct ipa_func_list * wl;
40
41   wl = NULL;
42   for (node = cgraph_nodes; node; node = node->next)
43     ipa_push_func_to_list (&wl, node);
44
45   return wl;
46 }
47
48 /* Add cgraph node MT to the worklist. Set worklist element WL
49    to point to MT.  */
50 void
51 ipa_push_func_to_list (struct ipa_func_list **wl, struct cgraph_node *mt)
52 {
53   struct ipa_func_list *temp;
54
55   temp = xcalloc (1, sizeof (struct ipa_func_list));
56   temp->node = mt;
57   temp->next = *wl;
58   *wl = temp;
59 }
60
61 /* Remove a function from the worklist. WL points to the first
62    element in the list, which is removed.  */
63 struct cgraph_node *
64 ipa_pop_func_from_list (struct ipa_func_list ** wl)
65 {
66   struct ipa_func_list *first;
67   struct cgraph_node *return_func;
68
69   first = *wl;
70   *wl = (*wl)->next;
71   return_func = first->node;
72   free (first);
73   return return_func;
74 }
75
76 /* Return index of the formal whose tree is ptree in function which corresponds
77    to info.  */
78 static int
79 ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
80 {
81   int i, count;
82
83   count = ipa_get_param_count (info);
84   for (i = 0; i < count; i++)
85     if (ipa_get_ith_param(info, i) == ptree)
86       return i;
87
88   return -1;
89 }
90
91 /* Insert the formal trees to the param_decls array in function MT.  */
92 void
93 ipa_create_param_decls_array (struct cgraph_node *mt)
94 {
95   tree fndecl;
96   tree fnargs;
97   tree parm;
98   int param_num;
99   struct ipa_node_params *info = IPA_NODE_REF (mt);
100
101   info->param_decls = XCNEWVEC (tree, ipa_get_param_count (info));
102   fndecl = mt->decl;
103   fnargs = DECL_ARGUMENTS (fndecl);
104   param_num = 0;
105   for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
106     {
107       info->param_decls[param_num] = parm;
108       param_num++;
109     }
110 }
111
112 /* Count number of formals in MT. Insert the result to the 
113    ipa_node_params.  */
114 void
115 ipa_count_formal_params (struct cgraph_node *mt)
116 {
117   tree fndecl;
118   tree fnargs;
119   tree parm;
120   int param_num;
121
122   fndecl = mt->decl;
123   fnargs = DECL_ARGUMENTS (fndecl);
124   param_num = 0;
125   for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
126     param_num++;
127   ipa_set_param_count (IPA_NODE_REF (mt), param_num);
128 }
129
130 /* Check STMT to detect whether a formal is modified within MT, the appropriate
131    entry is updated in the modified_flags array of ipa_node_params (associated
132    with MT).  */
133 static void
134 ipa_check_stmt_modifications (struct cgraph_node *mt, tree stmt)
135 {
136   int index, j;
137   tree parm_decl;
138   struct ipa_node_params *info;
139
140   switch (TREE_CODE (stmt))
141     {
142     case GIMPLE_MODIFY_STMT:
143           if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == PARM_DECL)
144         {
145           info = IPA_NODE_REF (mt);
146           parm_decl = GIMPLE_STMT_OPERAND (stmt, 0);
147           index = ipa_get_param_decl_index (info, parm_decl);
148           if (index >= 0)
149             info->modified_flags[index] = true;
150         }
151       break;
152     case ASM_EXPR:
153       /* Asm code could modify any of the parameters.  */
154       info = IPA_NODE_REF (mt);
155       for (j = 0; j < ipa_get_param_count (IPA_NODE_REF (mt)); j++)
156         info->modified_flags[j] = true;
157       break;
158     default:
159       break;
160     }
161 }
162
163 /* The modify computation driver for MT. Compute which formal arguments 
164    of function MT are locally modified.  Formals may be modified in MT
165    if their address is taken, or if
166    they appear on the left hand side of an assignment.  */
167 void
168 ipa_detect_param_modifications (struct cgraph_node *mt)
169 {
170   tree decl;
171   tree body;
172   int j, count;
173   basic_block bb;
174   struct function *func;
175   block_stmt_iterator bsi;
176   tree stmt, parm_tree;
177   struct ipa_node_params *info = IPA_NODE_REF (mt);
178
179   if (ipa_get_param_count (info) == 0)
180     return;
181
182   count = ipa_get_param_count (info);
183   info->modified_flags = XCNEWVEC (bool, count);
184   decl = mt->decl;
185   /* ??? Handle pending sizes case. Set all parameters 
186      of the function to be modified.  */
187
188   if (DECL_UNINLINABLE (decl))
189     {
190       for (j = 0; j < count; j++)
191         info->modified_flags[j] = true;
192
193       return;
194     }
195   /* Formals whose address is taken are considered modified.  */
196   for (j = 0; j < count; j++)
197     {
198       parm_tree = ipa_get_ith_param (info, j);
199       if (!is_gimple_reg (parm_tree) 
200           && TREE_ADDRESSABLE (parm_tree))
201         info->modified_flags[j] = true;
202     }
203   body = DECL_SAVED_TREE (decl);
204   if (body != NULL)
205     {
206       func = DECL_STRUCT_FUNCTION (decl);
207       FOR_EACH_BB_FN (bb, func)
208       {
209         for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
210           {
211             stmt = bsi_stmt (bsi);
212             ipa_check_stmt_modifications (mt, stmt);
213           }
214       }
215     }
216 }
217
218 /* Count number of arguments callsite CS has and store it in 
219    ipa_edge_args structure corresponding to this callsite.  */
220 void
221 ipa_count_arguments (struct cgraph_edge *cs)
222 {
223   tree call_tree;
224   int arg_num;
225
226   call_tree = get_call_expr_in (cs->call_stmt);
227   gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
228   arg_num = call_expr_nargs (call_tree);
229   ipa_set_cs_argument_count (IPA_EDGE_REF (cs), arg_num);
230 }
231
232 /* Compute jump function for all arguments of callsite CS 
233    and insert the information in the jump_functions array
234    in the ipa_edge_args corresponding to this callsite.  */
235 void
236 ipa_compute_jump_functions (struct cgraph_edge *cs)
237 {
238   tree call_tree;
239   tree arg, cst_decl;
240   int arg_num;
241   struct cgraph_node *mt;
242   tree parm_decl;
243   struct function *curr_cfun;
244   call_expr_arg_iterator iter;
245   struct ipa_edge_args *args = IPA_EDGE_REF (cs);
246
247   if (ipa_get_cs_argument_count (args) == 0)
248     return;
249   args->jump_functions = XCNEWVEC (struct ipa_jump_func,
250                                    ipa_get_cs_argument_count (args));
251   call_tree = get_call_expr_in (cs->call_stmt);
252   gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
253   arg_num = 0;
254
255   FOR_EACH_CALL_EXPR_ARG (arg, iter, call_tree)
256     {
257       /* If the formal parameter was passed as argument, we store 
258          IPA_PASS_THROUGH and its index in the caller as the jump function
259          of this argument.  */
260       if ((TREE_CODE (arg) == SSA_NAME
261            && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
262           || TREE_CODE (arg) == PARM_DECL)
263         {
264           struct ipa_node_params *info;
265           int index;
266
267           mt = cs->caller;
268           info = IPA_NODE_REF (mt);
269           parm_decl = TREE_CODE (arg) == PARM_DECL ? arg : SSA_NAME_VAR (arg);
270           
271           index = ipa_get_param_decl_index (info, parm_decl);
272           if (TREE_CODE (arg) == SSA_NAME && IS_VALID_JUMP_FUNC_INDEX (index))
273             {
274               curr_cfun = DECL_STRUCT_FUNCTION (mt->decl);
275               if (!gimple_default_def (curr_cfun, parm_decl) 
276                   || gimple_default_def (curr_cfun, parm_decl) != arg)
277                 info->modified_flags[index] = true;
278             }
279           if (!IS_VALID_JUMP_FUNC_INDEX (index) || info->modified_flags[index])
280             args->jump_functions[arg_num].type = IPA_UNKNOWN;
281           else
282             {
283               args->jump_functions[arg_num].type = IPA_PASS_THROUGH;
284               args->jump_functions[arg_num].value.formal_id = index;
285             }
286         }
287       /* If a constant value was passed as argument, 
288          we store IPA_CONST and its value as the jump function
289          of this argument.  */
290       else if (TREE_CODE (arg) == INTEGER_CST
291                || TREE_CODE (arg) == REAL_CST
292                || TREE_CODE (arg) == FIXED_CST)
293         {
294           args->jump_functions[arg_num].type = IPA_CONST;
295           args->jump_functions[arg_num].value.constant = arg;
296         }
297       /* This is for the case of Fortran. If the address of a const_decl 
298          was passed as argument then we store
299          IPA_CONST_REF/IPA_CONST_REF and the constant
300          value as the jump function corresponding to this argument.  */
301       else if (TREE_CODE (arg) == ADDR_EXPR
302                && TREE_CODE (TREE_OPERAND (arg, 0)) == CONST_DECL)
303         {
304           cst_decl = TREE_OPERAND (arg, 0);
305           if (TREE_CODE (DECL_INITIAL (cst_decl)) == INTEGER_CST
306               || TREE_CODE (DECL_INITIAL (cst_decl)) == REAL_CST
307               || TREE_CODE (DECL_INITIAL (cst_decl)) == FIXED_CST)
308             {
309               args->jump_functions[arg_num].type = IPA_CONST_REF;
310               args->jump_functions[arg_num].value.constant = cst_decl;
311             }
312         }
313       else
314         args->jump_functions[arg_num].type = IPA_UNKNOWN;
315       arg_num++;
316     }
317 }
318
319 /* Allocate and initialize ipa_node_params structure for the given cgraph
320    node.  */
321 void
322 ipa_create_node_params (struct cgraph_node *node)
323 {
324   node->aux = xcalloc (1, sizeof (struct ipa_node_params));
325 }
326
327 /* Allocate and initialize ipa_node_params structure for all
328    nodes in callgraph.  */
329 void
330 ipa_create_all_node_params (void)
331 {
332   struct cgraph_node *node;
333
334   for (node = cgraph_nodes; node; node = node->next)
335     ipa_create_node_params (node);
336 }
337
338 /* Allocate and initialize ipa_edge structure.  */
339 void
340 ipa_create_all_edge_args (void)
341 {
342   struct cgraph_node *node;
343   struct cgraph_edge *cs;
344
345   for (node = cgraph_nodes; node; node = node->next)
346     for (cs = node->callees; cs; cs = cs->next_callee)
347       cs->aux = xcalloc (1, sizeof (struct ipa_edge_args));
348 }
349
350 /* Free ipa_edge structure.  */
351 void
352 ipa_free_all_edge_args (void)
353 {
354   struct cgraph_node *node;
355   struct cgraph_edge *cs;
356
357   for (node = cgraph_nodes; node; node = node->next)
358     for (cs = node->callees; cs; cs = cs->next_callee)
359       if (cs->aux)
360         {
361           if (IPA_EDGE_REF (cs)->jump_functions)
362             free (IPA_EDGE_REF (cs)->jump_functions);
363           free (cs->aux);
364           cs->aux = NULL;
365         }
366 }
367
368 /* Free ipa data structures of ipa_node_params and ipa_edge_args.  */
369 void
370 ipa_free_all_node_params (void)
371 {
372   struct cgraph_node *node;
373
374   for (node = cgraph_nodes; node; node = node->next)
375     {
376       if (node->aux == NULL)
377         continue;
378       if (IPA_NODE_REF (node)->ipcp_lattices)
379         free (IPA_NODE_REF (node)->ipcp_lattices);
380       if (IPA_NODE_REF (node)->param_decls)
381         free (IPA_NODE_REF (node)->param_decls);
382       if (IPA_NODE_REF (node)->modified_flags)
383         free (IPA_NODE_REF (node)->modified_flags);
384       free (node->aux);
385       node->aux = NULL;
386     }
387 }
388
389 /* Print ipa_tree_map data structures of all functions in the
390    callgraph to F.  */
391 void
392 ipa_print_all_tree_maps (FILE * f)
393 {
394   int i, count;
395   tree temp;
396   struct cgraph_node *node;
397
398   fprintf (f, "\nPARAM TREE MAP PRINT\n");
399   for (node = cgraph_nodes; node; node = node->next)
400     {
401       struct ipa_node_params *info = IPA_NODE_REF (node);
402       fprintf (f, "function  %s Trees :: \n", cgraph_node_name (node));
403       count = ipa_get_param_count (info);
404       for (i = 0; i < count; i++)
405         {
406           temp = ipa_get_ith_param (info, i);
407           if (TREE_CODE (temp) == PARM_DECL)
408             fprintf (f, "  param [%d] : %s\n", i,
409                      (*lang_hooks.decl_printable_name) (temp, 2));
410         }
411
412     }
413 }
414
415 /* Print modified_flags data structures of all functions in the
416    callgraph to F.  */
417 void
418 ipa_print_all_params_modified (FILE * f)
419 {
420   int i, count;
421   bool temp;
422   struct cgraph_node *node;
423
424   fprintf (f, "\nMODIFY PRINT\n");
425   for (node = cgraph_nodes; node; node = node->next)
426     {
427       struct ipa_node_params *info = IPA_NODE_REF (node);
428       fprintf (f, "function  %s :: \n", cgraph_node_name (node));
429       count = ipa_get_param_count (info);
430       for (i = 0; i < count; i++)
431         {
432           temp = info->modified_flags[i];
433           if (temp)
434             fprintf (f, " param [%d] true \n", i);
435           else
436             fprintf (f, " param [%d] false \n", i);
437         }
438     }
439 }
440