]> gcc.gnu.org Git - gcc.git/blame - gcc/ipa-prop.c
t-softfp-compat: Update comments.
[gcc.git] / gcc / ipa-prop.c
CommitLineData
518dc859 1/* Interprocedural analyses.
9dcd6f09 2 Copyright (C) 2005, 2007 Free Software Foundation, Inc.
518dc859
RL
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
518dc859
RL
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
518dc859
RL
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
dcd416e3
MJ
34/* Initialize worklist to contain all functions. */
35struct ipa_func_list *
36ipa_init_func_list (void)
518dc859
RL
37{
38 struct cgraph_node *node;
dcd416e3 39 struct ipa_func_list * wl;
518dc859
RL
40
41 wl = NULL;
42 for (node = cgraph_nodes; node; node = node->next)
dcd416e3 43 ipa_push_func_to_list (&wl, node);
518dc859
RL
44
45 return wl;
46}
47
dcd416e3 48/* Add cgraph node MT to the worklist. Set worklist element WL
518dc859
RL
49 to point to MT. */
50void
dcd416e3 51ipa_push_func_to_list (struct ipa_func_list **wl, struct cgraph_node *mt)
518dc859 52{
dcd416e3 53 struct ipa_func_list *temp;
518dc859 54
d3bfe4de 55 temp = XCNEW (struct ipa_func_list);
dcd416e3
MJ
56 temp->node = mt;
57 temp->next = *wl;
518dc859
RL
58 *wl = temp;
59}
60
dcd416e3 61/* Remove a function from the worklist. WL points to the first
518dc859
RL
62 element in the list, which is removed. */
63struct cgraph_node *
dcd416e3 64ipa_pop_func_from_list (struct ipa_func_list ** wl)
518dc859 65{
dcd416e3
MJ
66 struct ipa_func_list *first;
67 struct cgraph_node *return_func;
518dc859
RL
68
69 first = *wl;
dcd416e3
MJ
70 *wl = (*wl)->next;
71 return_func = first->node;
518dc859 72 free (first);
dcd416e3 73 return return_func;
518dc859
RL
74}
75
dcd416e3
MJ
76/* Return index of the formal whose tree is ptree in function which corresponds
77 to info. */
518dc859 78static int
dcd416e3 79ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
518dc859
RL
80{
81 int i, count;
82
dcd416e3 83 count = ipa_get_param_count (info);
518dc859 84 for (i = 0; i < count; i++)
dcd416e3 85 if (ipa_get_ith_param(info, i) == ptree)
518dc859
RL
86 return i;
87
88 return -1;
89}
90
dcd416e3 91/* Insert the formal trees to the param_decls array in function MT. */
518dc859 92void
dcd416e3 93ipa_create_param_decls_array (struct cgraph_node *mt)
518dc859
RL
94{
95 tree fndecl;
96 tree fnargs;
97 tree parm;
98 int param_num;
dcd416e3 99 struct ipa_node_params *info = IPA_NODE_REF (mt);
518dc859 100
dcd416e3 101 info->param_decls = XCNEWVEC (tree, ipa_get_param_count (info));
518dc859
RL
102 fndecl = mt->decl;
103 fnargs = DECL_ARGUMENTS (fndecl);
104 param_num = 0;
105 for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
106 {
dcd416e3 107 info->param_decls[param_num] = parm;
518dc859
RL
108 param_num++;
109 }
110}
111
112/* Count number of formals in MT. Insert the result to the
dcd416e3 113 ipa_node_params. */
518dc859 114void
dcd416e3 115ipa_count_formal_params (struct cgraph_node *mt)
518dc859
RL
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++;
dcd416e3 127 ipa_set_param_count (IPA_NODE_REF (mt), param_num);
518dc859
RL
128}
129
dcd416e3
MJ
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). */
518dc859 133static void
dcd416e3 134ipa_check_stmt_modifications (struct cgraph_node *mt, tree stmt)
518dc859 135{
dcd416e3 136 int index, j;
3cc1cccc 137 tree parm_decl;
dcd416e3 138 struct ipa_node_params *info;
518dc859
RL
139
140 switch (TREE_CODE (stmt))
141 {
07beea0d 142 case GIMPLE_MODIFY_STMT:
3cc1cccc 143 if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == PARM_DECL)
518dc859 144 {
dcd416e3 145 info = IPA_NODE_REF (mt);
3cc1cccc 146 parm_decl = GIMPLE_STMT_OPERAND (stmt, 0);
dcd416e3
MJ
147 index = ipa_get_param_decl_index (info, parm_decl);
148 if (index >= 0)
149 info->modified_flags[index] = true;
518dc859
RL
150 }
151 break;
152 case ASM_EXPR:
153 /* Asm code could modify any of the parameters. */
dcd416e3
MJ
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;
518dc859
RL
157 break;
158 default:
159 break;
160 }
161}
162
518dc859 163/* The modify computation driver for MT. Compute which formal arguments
dcd416e3 164 of function MT are locally modified. Formals may be modified in MT
518dc859
RL
165 if their address is taken, or if
166 they appear on the left hand side of an assignment. */
167void
dcd416e3 168ipa_detect_param_modifications (struct cgraph_node *mt)
518dc859
RL
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;
dcd416e3 177 struct ipa_node_params *info = IPA_NODE_REF (mt);
518dc859 178
dcd416e3 179 if (ipa_get_param_count (info) == 0)
3cc1cccc
RL
180 return;
181
dcd416e3
MJ
182 count = ipa_get_param_count (info);
183 info->modified_flags = XCNEWVEC (bool, count);
518dc859 184 decl = mt->decl;
518dc859 185 /* ??? Handle pending sizes case. Set all parameters
dcd416e3 186 of the function to be modified. */
3cc1cccc 187
518dc859
RL
188 if (DECL_UNINLINABLE (decl))
189 {
190 for (j = 0; j < count; j++)
dcd416e3
MJ
191 info->modified_flags[j] = true;
192
518dc859
RL
193 return;
194 }
195 /* Formals whose address is taken are considered modified. */
196 for (j = 0; j < count; j++)
197 {
dcd416e3 198 parm_tree = ipa_get_ith_param (info, j);
3cc1cccc
RL
199 if (!is_gimple_reg (parm_tree)
200 && TREE_ADDRESSABLE (parm_tree))
dcd416e3 201 info->modified_flags[j] = true;
518dc859
RL
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);
dcd416e3 212 ipa_check_stmt_modifications (mt, stmt);
518dc859
RL
213 }
214 }
215 }
216}
217
518dc859 218/* Count number of arguments callsite CS has and store it in
dcd416e3 219 ipa_edge_args structure corresponding to this callsite. */
518dc859 220void
dcd416e3 221ipa_count_arguments (struct cgraph_edge *cs)
518dc859
RL
222{
223 tree call_tree;
518dc859
RL
224 int arg_num;
225
dcd416e3 226 call_tree = get_call_expr_in (cs->call_stmt);
518dc859 227 gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
5039610b 228 arg_num = call_expr_nargs (call_tree);
dcd416e3 229 ipa_set_cs_argument_count (IPA_EDGE_REF (cs), arg_num);
518dc859
RL
230}
231
232/* Compute jump function for all arguments of callsite CS
dcd416e3
MJ
233 and insert the information in the jump_functions array
234 in the ipa_edge_args corresponding to this callsite. */
518dc859 235void
dcd416e3 236ipa_compute_jump_functions (struct cgraph_edge *cs)
518dc859
RL
237{
238 tree call_tree;
a8bd670c 239 tree arg, cst_decl;
518dc859 240 int arg_num;
518dc859 241 struct cgraph_node *mt;
3cc1cccc
RL
242 tree parm_decl;
243 struct function *curr_cfun;
5039610b 244 call_expr_arg_iterator iter;
dcd416e3 245 struct ipa_edge_args *args = IPA_EDGE_REF (cs);
518dc859 246
dcd416e3 247 if (ipa_get_cs_argument_count (args) == 0)
518dc859 248 return;
dcd416e3
MJ
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);
518dc859 252 gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
518dc859
RL
253 arg_num = 0;
254
5039610b 255 FOR_EACH_CALL_EXPR_ARG (arg, iter, call_tree)
518dc859
RL
256 {
257 /* If the formal parameter was passed as argument, we store
dcd416e3 258 IPA_PASS_THROUGH and its index in the caller as the jump function
518dc859 259 of this argument. */
5039610b
SL
260 if ((TREE_CODE (arg) == SSA_NAME
261 && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
262 || TREE_CODE (arg) == PARM_DECL)
518dc859 263 {
dcd416e3
MJ
264 struct ipa_node_params *info;
265 int index;
266
267 mt = cs->caller;
268 info = IPA_NODE_REF (mt);
5039610b 269 parm_decl = TREE_CODE (arg) == PARM_DECL ? arg : SSA_NAME_VAR (arg);
3cc1cccc 270
dcd416e3
MJ
271 index = ipa_get_param_decl_index (info, parm_decl);
272 if (TREE_CODE (arg) == SSA_NAME && IS_VALID_JUMP_FUNC_INDEX (index))
3cc1cccc 273 {
5039610b 274 curr_cfun = DECL_STRUCT_FUNCTION (mt->decl);
3cc1cccc 275 if (!gimple_default_def (curr_cfun, parm_decl)
5039610b 276 || gimple_default_def (curr_cfun, parm_decl) != arg)
dcd416e3 277 info->modified_flags[index] = true;
5039610b 278 }
dcd416e3
MJ
279 if (!IS_VALID_JUMP_FUNC_INDEX (index) || info->modified_flags[index])
280 args->jump_functions[arg_num].type = IPA_UNKNOWN;
518dc859
RL
281 else
282 {
dcd416e3
MJ
283 args->jump_functions[arg_num].type = IPA_PASS_THROUGH;
284 args->jump_functions[arg_num].value.formal_id = index;
518dc859
RL
285 }
286 }
287 /* If a constant value was passed as argument,
dcd416e3 288 we store IPA_CONST and its value as the jump function
518dc859 289 of this argument. */
5039610b 290 else if (TREE_CODE (arg) == INTEGER_CST
325217ed
CF
291 || TREE_CODE (arg) == REAL_CST
292 || TREE_CODE (arg) == FIXED_CST)
518dc859 293 {
dcd416e3
MJ
294 args->jump_functions[arg_num].type = IPA_CONST;
295 args->jump_functions[arg_num].value.constant = arg;
518dc859
RL
296 }
297 /* This is for the case of Fortran. If the address of a const_decl
dcd416e3
MJ
298 was passed as argument then we store
299 IPA_CONST_REF/IPA_CONST_REF and the constant
518dc859 300 value as the jump function corresponding to this argument. */
5039610b
SL
301 else if (TREE_CODE (arg) == ADDR_EXPR
302 && TREE_CODE (TREE_OPERAND (arg, 0)) == CONST_DECL)
518dc859 303 {
5039610b 304 cst_decl = TREE_OPERAND (arg, 0);
518dc859 305 if (TREE_CODE (DECL_INITIAL (cst_decl)) == INTEGER_CST
325217ed
CF
306 || TREE_CODE (DECL_INITIAL (cst_decl)) == REAL_CST
307 || TREE_CODE (DECL_INITIAL (cst_decl)) == FIXED_CST)
518dc859 308 {
dcd416e3
MJ
309 args->jump_functions[arg_num].type = IPA_CONST_REF;
310 args->jump_functions[arg_num].value.constant = cst_decl;
518dc859
RL
311 }
312 }
313 else
dcd416e3 314 args->jump_functions[arg_num].type = IPA_UNKNOWN;
518dc859
RL
315 arg_num++;
316 }
317}
318
dcd416e3
MJ
319/* Allocate and initialize ipa_node_params structure for the given cgraph
320 node. */
518dc859 321void
dcd416e3 322ipa_create_node_params (struct cgraph_node *node)
518dc859 323{
dcd416e3 324 node->aux = xcalloc (1, sizeof (struct ipa_node_params));
518dc859
RL
325}
326
dcd416e3 327/* Allocate and initialize ipa_node_params structure for all
518dc859
RL
328 nodes in callgraph. */
329void
dcd416e3 330ipa_create_all_node_params (void)
518dc859
RL
331{
332 struct cgraph_node *node;
333
334 for (node = cgraph_nodes; node; node = node->next)
dcd416e3 335 ipa_create_node_params (node);
518dc859
RL
336}
337
338/* Allocate and initialize ipa_edge structure. */
339void
dcd416e3 340ipa_create_all_edge_args (void)
518dc859
RL
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)
dcd416e3 347 cs->aux = xcalloc (1, sizeof (struct ipa_edge_args));
518dc859
RL
348}
349
350/* Free ipa_edge structure. */
351void
dcd416e3 352ipa_free_all_edge_args (void)
518dc859
RL
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)
dcd416e3
MJ
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 }
518dc859
RL
366}
367
dcd416e3 368/* Free ipa data structures of ipa_node_params and ipa_edge_args. */
518dc859 369void
dcd416e3 370ipa_free_all_node_params (void)
518dc859
RL
371{
372 struct cgraph_node *node;
518dc859
RL
373
374 for (node = cgraph_nodes; node; node = node->next)
375 {
376 if (node->aux == NULL)
377 continue;
dcd416e3
MJ
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;
518dc859
RL
386 }
387}
388
dcd416e3 389/* Print ipa_tree_map data structures of all functions in the
518dc859
RL
390 callgraph to F. */
391void
dcd416e3 392ipa_print_all_tree_maps (FILE * f)
518dc859
RL
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 {
dcd416e3
MJ
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);
518dc859
RL
404 for (i = 0; i < count; i++)
405 {
dcd416e3 406 temp = ipa_get_ith_param (info, i);
518dc859
RL
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
dcd416e3 415/* Print modified_flags data structures of all functions in the
518dc859
RL
416 callgraph to F. */
417void
dcd416e3 418ipa_print_all_params_modified (FILE * f)
518dc859
RL
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 {
dcd416e3
MJ
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);
518dc859
RL
430 for (i = 0; i < count; i++)
431 {
dcd416e3 432 temp = info->modified_flags[i];
518dc859
RL
433 if (temp)
434 fprintf (f, " param [%d] true \n", i);
435 else
436 fprintf (f, " param [%d] false \n", i);
437 }
438 }
439}
dcd416e3 440
This page took 1.241898 seconds and 5 git commands to generate.