Check in tree-dce enh to trunk
[official-gcc.git] / gcc / ipa-prop.c
blobf0403634c10001b892ac9d0ad7182f2d53b233fb
1 /* Interprocedural analyses.
2 Copyright (C) 2005, 2007 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
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"
34 /* Initialize worklist to contain all functions. */
35 struct ipa_func_list *
36 ipa_init_func_list (void)
38 struct cgraph_node *node;
39 struct ipa_func_list * wl;
41 wl = NULL;
42 for (node = cgraph_nodes; node; node = node->next)
43 ipa_push_func_to_list (&wl, node);
45 return wl;
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)
53 struct ipa_func_list *temp;
55 temp = xcalloc (1, sizeof (struct ipa_func_list));
56 temp->node = mt;
57 temp->next = *wl;
58 *wl = temp;
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)
66 struct ipa_func_list *first;
67 struct cgraph_node *return_func;
69 first = *wl;
70 *wl = (*wl)->next;
71 return_func = first->node;
72 free (first);
73 return return_func;
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)
81 int i, count;
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;
88 return -1;
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)
95 tree fndecl;
96 tree fnargs;
97 tree parm;
98 int param_num;
99 struct ipa_node_params *info = IPA_NODE_REF (mt);
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))
107 info->param_decls[param_num] = parm;
108 param_num++;
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)
117 tree fndecl;
118 tree fnargs;
119 tree parm;
120 int param_num;
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);
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)
136 int index, j;
137 tree parm_decl;
138 struct ipa_node_params *info;
140 switch (TREE_CODE (stmt))
142 case GIMPLE_MODIFY_STMT:
143 if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == PARM_DECL)
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;
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;
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)
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);
179 if (ipa_get_param_count (info) == 0)
180 return;
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. */
188 if (DECL_UNINLINABLE (decl))
190 for (j = 0; j < count; j++)
191 info->modified_flags[j] = true;
193 return;
195 /* Formals whose address is taken are considered modified. */
196 for (j = 0; j < count; j++)
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;
203 body = DECL_SAVED_TREE (decl);
204 if (body != NULL)
206 func = DECL_STRUCT_FUNCTION (decl);
207 FOR_EACH_BB_FN (bb, func)
209 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
211 stmt = bsi_stmt (bsi);
212 ipa_check_stmt_modifications (mt, stmt);
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)
223 tree call_tree;
224 int arg_num;
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);
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)
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);
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;
255 FOR_EACH_CALL_EXPR_ARG (arg, iter, call_tree)
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)
264 struct ipa_node_params *info;
265 int index;
267 mt = cs->caller;
268 info = IPA_NODE_REF (mt);
269 parm_decl = TREE_CODE (arg) == PARM_DECL ? arg : SSA_NAME_VAR (arg);
271 index = ipa_get_param_decl_index (info, parm_decl);
272 if (TREE_CODE (arg) == SSA_NAME && IS_VALID_JUMP_FUNC_INDEX (index))
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;
279 if (!IS_VALID_JUMP_FUNC_INDEX (index) || info->modified_flags[index])
280 args->jump_functions[arg_num].type = IPA_UNKNOWN;
281 else
283 args->jump_functions[arg_num].type = IPA_PASS_THROUGH;
284 args->jump_functions[arg_num].value.formal_id = index;
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)
294 args->jump_functions[arg_num].type = IPA_CONST;
295 args->jump_functions[arg_num].value.constant = arg;
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)
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)
309 args->jump_functions[arg_num].type = IPA_CONST_REF;
310 args->jump_functions[arg_num].value.constant = cst_decl;
313 else
314 args->jump_functions[arg_num].type = IPA_UNKNOWN;
315 arg_num++;
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)
324 node->aux = xcalloc (1, sizeof (struct ipa_node_params));
327 /* Allocate and initialize ipa_node_params structure for all
328 nodes in callgraph. */
329 void
330 ipa_create_all_node_params (void)
332 struct cgraph_node *node;
334 for (node = cgraph_nodes; node; node = node->next)
335 ipa_create_node_params (node);
338 /* Allocate and initialize ipa_edge structure. */
339 void
340 ipa_create_all_edge_args (void)
342 struct cgraph_node *node;
343 struct cgraph_edge *cs;
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));
350 /* Free ipa_edge structure. */
351 void
352 ipa_free_all_edge_args (void)
354 struct cgraph_node *node;
355 struct cgraph_edge *cs;
357 for (node = cgraph_nodes; node; node = node->next)
358 for (cs = node->callees; cs; cs = cs->next_callee)
359 if (cs->aux)
361 if (IPA_EDGE_REF (cs)->jump_functions)
362 free (IPA_EDGE_REF (cs)->jump_functions);
363 free (cs->aux);
364 cs->aux = NULL;
368 /* Free ipa data structures of ipa_node_params and ipa_edge_args. */
369 void
370 ipa_free_all_node_params (void)
372 struct cgraph_node *node;
374 for (node = cgraph_nodes; node; node = node->next)
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;
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)
394 int i, count;
395 tree temp;
396 struct cgraph_node *node;
398 fprintf (f, "\nPARAM TREE MAP PRINT\n");
399 for (node = cgraph_nodes; node; node = node->next)
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++)
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));
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)
420 int i, count;
421 bool temp;
422 struct cgraph_node *node;
424 fprintf (f, "\nMODIFY PRINT\n");
425 for (node = cgraph_nodes; node; node = node->next)
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++)
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);