Add files that I missed when importing NaCl changes earlier
[gcc/nacl-gcc.git] / gcc / ipa-prop.c
blobcff8c7530e8600c563da9181071ce01aee276d80
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 /* This file contains interfaces that can be used for various IPA
35 optimizations:
37 - ipa_methodlist interface - It is used to create and handle a temporary
38 worklist used in the propagation stage of IPCP. (can be used for more
39 IPA optimizations).
41 - ipa_callsite interface - for each callsite this interface creates and
42 handles ipa_edge structure associated with it.
44 - ipa_method interface - for each method this interface creates and
45 handles ipa_node structure associated with it. */
47 /* ipa_methodlist interface. */
49 /* Create a new worklist node. */
50 static inline ipa_methodlist_p
51 ipa_create_methodlist_node (void)
53 return (ipa_methodlist_p) xcalloc (1, sizeof (struct ipa_methodlist));
56 /* Return true if worklist WL is empty. */
57 bool
58 ipa_methodlist_not_empty (ipa_methodlist_p wl)
60 return (wl != NULL);
63 /* Return the method in worklist element WL. */
64 static inline struct cgraph_node *
65 ipa_methodlist_method (ipa_methodlist_p wl)
67 return wl->method_p;
70 /* Make worklist element WL point to method MT in the callgraph. */
71 static inline void
72 ipa_methodlist_method_set (ipa_methodlist_p wl, struct cgraph_node *mt)
74 wl->method_p = mt;
77 /* Return the next element in the worklist following worklist
78 element WL. */
79 static inline ipa_methodlist_p
80 ipa_methodlist_next_method (ipa_methodlist_p wl)
82 return wl->next_method;
85 /* Set worklist element WL1 to point to worklist element WL2. */
86 static inline void
87 ipa_methodlist_next_method_set (ipa_methodlist_p wl1, ipa_methodlist_p wl2)
89 wl1->next_method = wl2;
92 /* Initialize worklist to contain all methods. */
93 ipa_methodlist_p
94 ipa_methodlist_init (void)
96 struct cgraph_node *node;
97 ipa_methodlist_p wl;
99 wl = NULL;
100 for (node = cgraph_nodes; node; node = node->next)
101 ipa_add_method (&wl, node);
103 return wl;
106 /* Add method MT to the worklist. Set worklist element WL
107 to point to MT. */
108 void
109 ipa_add_method (ipa_methodlist_p * wl, struct cgraph_node *mt)
111 ipa_methodlist_p temp;
113 temp = ipa_create_methodlist_node ();
114 ipa_methodlist_method_set (temp, mt);
115 ipa_methodlist_next_method_set (temp, *wl);
116 *wl = temp;
119 /* Remove a method from the worklist. WL points to the first
120 element in the list, which is removed. */
121 struct cgraph_node *
122 ipa_remove_method (ipa_methodlist_p * wl)
124 ipa_methodlist_p first;
125 struct cgraph_node *return_method;
127 first = *wl;
128 *wl = ipa_methodlist_next_method (*wl);
129 return_method = ipa_methodlist_method (first);
130 free (first);
131 return return_method;
134 /* ipa_method interface. */
136 /* Return number of formals of method MT. */
138 ipa_method_formal_count (struct cgraph_node *mt)
140 return IPA_NODE_REF (mt)->ipa_arg_num;
143 /* Set number of formals of method MT to I. */
144 void
145 ipa_method_formal_count_set (struct cgraph_node *mt, int i)
147 IPA_NODE_REF (mt)->ipa_arg_num = i;
150 /* Return whether I-th formal of MT is modified in MT. */
151 static inline bool
152 ipa_method_is_modified (struct cgraph_node *mt, int i)
154 return IPA_NODE_REF (mt)->ipa_mod[i];
157 /* Return the tree of I-th formal of MT. */
158 tree
159 ipa_method_get_tree (struct cgraph_node *mt, int i)
161 return IPA_NODE_REF (mt)->ipa_param_tree[i];
164 /* Create tree map structure for MT. */
165 static inline void
166 ipa_method_tree_map_create (struct cgraph_node *mt)
168 IPA_NODE_REF (mt)->ipa_param_tree =
169 XCNEWVEC (tree, ipa_method_formal_count (mt));
172 /* Create modify structure for MT. */
173 static inline void
174 ipa_method_modify_create (struct cgraph_node *mt)
176 ((struct ipa_node *) mt->aux)->ipa_mod =
177 XCNEWVEC (bool, ipa_method_formal_count (mt));
180 /* Set modify of I-th formal of MT to VAL. */
181 static inline void
182 ipa_method_modify_set (struct cgraph_node *mt, int i, bool val)
184 IPA_NODE_REF (mt)->ipa_mod[i] = val;
187 /* Return index of the formal whose tree is PTREE in method MT. */
188 static int
189 ipa_method_tree_map (struct cgraph_node *mt, tree ptree)
191 int i, count;
193 count = ipa_method_formal_count (mt);
194 for (i = 0; i < count; i++)
195 if (IPA_NODE_REF (mt)->ipa_param_tree[i] == ptree)
196 return i;
198 return -1;
201 /* Insert the formal trees to the ipa_param_tree array in method MT. */
202 void
203 ipa_method_compute_tree_map (struct cgraph_node *mt)
205 tree fndecl;
206 tree fnargs;
207 tree parm;
208 int param_num;
210 ipa_method_tree_map_create (mt);
211 fndecl = mt->decl;
212 fnargs = DECL_ARGUMENTS (fndecl);
213 param_num = 0;
214 for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
216 IPA_NODE_REF (mt)->ipa_param_tree[param_num] = parm;
217 param_num++;
221 /* Count number of formals in MT. Insert the result to the
222 ipa_node. */
223 void
224 ipa_method_formal_compute_count (struct cgraph_node *mt)
226 tree fndecl;
227 tree fnargs;
228 tree parm;
229 int param_num;
231 fndecl = mt->decl;
232 fnargs = DECL_ARGUMENTS (fndecl);
233 param_num = 0;
234 for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
235 param_num++;
236 ipa_method_formal_count_set (mt, param_num);
239 /* Check STMT to detect whether a formal is modified within MT,
240 the appropriate entry is updated in the ipa_mod array of ipa_node
241 (associated with MT). */
242 static void
243 ipa_method_modify_stmt (struct cgraph_node *mt, tree stmt)
245 int i, j;
247 switch (TREE_CODE (stmt))
249 case MODIFY_EXPR:
250 if (TREE_CODE (TREE_OPERAND (stmt, 0)) == PARM_DECL)
252 i = ipa_method_tree_map (mt, TREE_OPERAND (stmt, 0));
253 if (i >= 0)
254 ipa_method_modify_set (mt, i, true);
256 break;
257 case ASM_EXPR:
258 /* Asm code could modify any of the parameters. */
259 for (j = 0; j < ipa_method_formal_count (mt); j++)
260 ipa_method_modify_set (mt, j, true);
261 break;
262 default:
263 break;
267 /* Initialize ipa_mod array of MT. */
268 static void
269 ipa_method_modify_init (struct cgraph_node *mt)
271 int i, count;
273 ipa_method_modify_create (mt);
274 count = ipa_method_formal_count (mt);
275 for (i = 0; i < count; i++)
276 ipa_method_modify_set (mt, i, false);
279 /* The modify computation driver for MT. Compute which formal arguments
280 of method MT are locally modified. Formals may be modified in MT
281 if their address is taken, or if
282 they appear on the left hand side of an assignment. */
283 void
284 ipa_method_compute_modify (struct cgraph_node *mt)
286 tree decl;
287 tree body;
288 int j, count;
289 basic_block bb;
290 struct function *func;
291 block_stmt_iterator bsi;
292 tree stmt, parm_tree;
294 ipa_method_modify_init (mt);
295 decl = mt->decl;
296 count = ipa_method_formal_count (mt);
297 /* ??? Handle pending sizes case. Set all parameters
298 of the method to be modified. */
299 if (DECL_UNINLINABLE (decl))
301 for (j = 0; j < count; j++)
302 ipa_method_modify_set (mt, j, true);
303 return;
305 /* Formals whose address is taken are considered modified. */
306 for (j = 0; j < count; j++)
308 parm_tree = ipa_method_get_tree (mt, j);
309 if (TREE_ADDRESSABLE (parm_tree))
310 ipa_method_modify_set (mt, j, true);
312 body = DECL_SAVED_TREE (decl);
313 if (body != NULL)
315 func = DECL_STRUCT_FUNCTION (decl);
316 FOR_EACH_BB_FN (bb, func)
318 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
320 stmt = bsi_stmt (bsi);
321 ipa_method_modify_stmt (mt, stmt);
328 /* ipa_callsite interface. */
330 /* Return number of arguments in callsite CS. */
332 ipa_callsite_param_count (struct cgraph_edge *cs)
334 return IPA_EDGE_REF (cs)->ipa_param_num;
337 /* Set number of arguments in callsite CS to I. */
338 void
339 ipa_callsite_param_count_set (struct cgraph_edge *cs, int i)
341 IPA_EDGE_REF (cs)->ipa_param_num = i;
344 /* Return the jump function (ipa_jump_func struct) for argument I of
345 callsite CS. */
346 struct ipa_jump_func *
347 ipa_callsite_param (struct cgraph_edge *cs, int i)
349 return &(IPA_EDGE_REF (cs)->ipa_param_map[i]);
352 /* return the callee (cgraph_node) of callsite CS. */
353 struct cgraph_node *
354 ipa_callsite_callee (struct cgraph_edge *cs)
356 return cs->callee;
359 /* Set field 'type' of jump function (ipa_jump_func struct) of argument I
360 in callsite CS. */
361 static inline void
362 ipa_callsite_param_set_type (struct cgraph_edge *cs, int i,
363 enum jump_func_type type1)
365 IPA_EDGE_REF (cs)->ipa_param_map[i].type = type1;
368 /* Set FORMAL as 'info_type' field of jump function (ipa_jump_func struct)
369 of argument I of callsite CS. */
370 static inline void
371 ipa_callsite_param_set_info_type_formal (struct cgraph_edge *cs, int i,
372 unsigned int formal)
374 ipa_callsite_param (cs, i)->info_type.formal_id = formal;
377 /* Set int-valued INFO_TYPE1 as 'info_type' field of
378 jump function (ipa_jump_func struct) of argument I of callsite CS. */
379 static inline void
380 ipa_callsite_param_set_info_type (struct cgraph_edge *cs, int i, tree info_type1)
382 ipa_callsite_param (cs, i)->info_type.value = info_type1;
385 /* Allocate space for callsite CS. */
386 static inline void
387 ipa_callsite_param_map_create (struct cgraph_edge *cs)
389 IPA_EDGE_REF (cs)->ipa_param_map =
390 XCNEWVEC (struct ipa_jump_func, ipa_callsite_param_count (cs));
393 /* Return the call expr tree related to callsite CS. */
394 static inline tree
395 ipa_callsite_tree (struct cgraph_edge *cs)
397 return cs->call_stmt;
400 /* Return the caller (cgraph_node) of CS. */
401 static inline struct cgraph_node *
402 ipa_callsite_caller (struct cgraph_edge *cs)
404 return cs->caller;
407 /* Count number of arguments callsite CS has and store it in
408 ipa_edge structure corresponding to this callsite. */
409 void
410 ipa_callsite_compute_count (struct cgraph_edge *cs)
412 tree call_tree;
413 tree arg;
414 int arg_num;
416 call_tree = get_call_expr_in (ipa_callsite_tree (cs));
417 gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
418 arg = TREE_OPERAND (call_tree, 1);
419 arg_num = 0;
420 for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
421 arg_num++;
422 ipa_callsite_param_count_set (cs, arg_num);
425 /* Compute jump function for all arguments of callsite CS
426 and insert the information in the ipa_param_map array
427 in the ipa_edge corresponding to this callsite. (Explanation
428 on jump functions is in ipa-prop.h). */
429 void
430 ipa_callsite_compute_param (struct cgraph_edge *cs)
432 tree call_tree;
433 tree arg, cst_decl;
434 int arg_num;
435 int i;
436 struct cgraph_node *mt;
438 if (ipa_callsite_param_count (cs) == 0)
439 return;
440 ipa_callsite_param_map_create (cs);
441 call_tree = get_call_expr_in (ipa_callsite_tree (cs));
442 gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
443 arg = TREE_OPERAND (call_tree, 1);
444 arg_num = 0;
446 for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
448 /* If the formal parameter was passed as argument, we store
449 FORMAL_IPATYPE and its index in the caller as the jump function
450 of this argument. */
451 if (TREE_CODE (TREE_VALUE (arg)) == PARM_DECL)
453 mt = ipa_callsite_caller (cs);
454 i = ipa_method_tree_map (mt, TREE_VALUE (arg));
455 if (i < 0 || ipa_method_is_modified (mt, i))
456 ipa_callsite_param_set_type (cs, arg_num, UNKNOWN_IPATYPE);
457 else
459 ipa_callsite_param_set_type (cs, arg_num, FORMAL_IPATYPE);
460 ipa_callsite_param_set_info_type_formal (cs, arg_num, i);
463 /* If a constant value was passed as argument,
464 we store CONST_IPATYPE and its value as the jump function
465 of this argument. */
466 else if (TREE_CODE (TREE_VALUE (arg)) == INTEGER_CST
467 || TREE_CODE (TREE_VALUE (arg)) == REAL_CST)
469 ipa_callsite_param_set_type (cs, arg_num, CONST_IPATYPE);
470 ipa_callsite_param_set_info_type (cs, arg_num,
471 TREE_VALUE (arg));
473 /* This is for the case of Fortran. If the address of a const_decl
474 was passed as argument then we store
475 CONST_IPATYPE_REF/CONST_IPATYPE_REF and the constant
476 value as the jump function corresponding to this argument. */
477 else if (TREE_CODE (TREE_VALUE (arg)) == ADDR_EXPR
478 && TREE_CODE (TREE_OPERAND (TREE_VALUE (arg), 0)) ==
479 CONST_DECL)
481 cst_decl = TREE_OPERAND (TREE_VALUE (arg), 0);
482 if (TREE_CODE (DECL_INITIAL (cst_decl)) == INTEGER_CST
483 || TREE_CODE (DECL_INITIAL (cst_decl)) == REAL_CST)
485 ipa_callsite_param_set_type (cs, arg_num,
486 CONST_IPATYPE_REF);
487 ipa_callsite_param_set_info_type (cs, arg_num,
488 DECL_INITIAL (cst_decl));
491 else
492 ipa_callsite_param_set_type (cs, arg_num, UNKNOWN_IPATYPE);
493 arg_num++;
497 /* Return type of jump function JF. */
498 enum jump_func_type
499 get_type (struct ipa_jump_func *jf)
501 return jf->type;
504 /* Return info type of jump function JF. */
505 union parameter_info *
506 ipa_jf_get_info_type (struct ipa_jump_func *jf)
508 return &(jf->info_type);
511 /* Allocate and initialize ipa_node structure.
512 cgraph_node NODE points to the new allocated ipa_node. */
513 void
514 ipa_node_create (struct cgraph_node *node)
516 node->aux = xcalloc (1, sizeof (struct ipa_node));
519 /* Allocate and initialize ipa_node structure for all
520 nodes in callgraph. */
521 void
522 ipa_nodes_create (void)
524 struct cgraph_node *node;
526 for (node = cgraph_nodes; node; node = node->next)
527 ipa_node_create (node);
530 /* Allocate and initialize ipa_edge structure. */
531 void
532 ipa_edges_create (void)
534 struct cgraph_node *node;
535 struct cgraph_edge *cs;
537 for (node = cgraph_nodes; node; node = node->next)
538 for (cs = node->callees; cs; cs = cs->next_callee)
539 cs->aux = xcalloc (1, sizeof (struct ipa_edge));
542 /* Free ipa_node structure. */
543 void
544 ipa_nodes_free (void)
546 struct cgraph_node *node;
548 for (node = cgraph_nodes; node; node = node->next)
550 free (node->aux);
551 node->aux = NULL;
555 /* Free ipa_edge structure. */
556 void
557 ipa_edges_free (void)
559 struct cgraph_node *node;
560 struct cgraph_edge *cs;
562 for (node = cgraph_nodes; node; node = node->next)
563 for (cs = node->callees; cs; cs = cs->next_callee)
565 free (cs->aux);
566 cs->aux = NULL;
570 /* Free ipa data structures of ipa_node and ipa_edge. */
571 void
572 ipa_free (void)
574 struct cgraph_node *node;
575 struct cgraph_edge *cs;
577 for (node = cgraph_nodes; node; node = node->next)
579 if (node->aux == NULL)
580 continue;
581 if (IPA_NODE_REF (node)->ipcp_cval)
582 free (IPA_NODE_REF (node)->ipcp_cval);
583 if (IPA_NODE_REF (node)->ipa_param_tree)
584 free (IPA_NODE_REF (node)->ipa_param_tree);
585 if (IPA_NODE_REF (node)->ipa_mod)
586 free (IPA_NODE_REF (node)->ipa_mod);
587 for (cs = node->callees; cs; cs = cs->next_callee)
589 if (cs->aux)
590 if (IPA_EDGE_REF (cs)->ipa_param_map)
591 free (IPA_EDGE_REF (cs)->ipa_param_map);
596 /* Print ipa_tree_map data structures of all methods in the
597 callgraph to F. */
598 void
599 ipa_method_tree_print (FILE * f)
601 int i, count;
602 tree temp;
603 struct cgraph_node *node;
605 fprintf (f, "\nPARAM TREE MAP PRINT\n");
606 for (node = cgraph_nodes; node; node = node->next)
608 fprintf (f, "method %s Trees :: \n", cgraph_node_name (node));
609 count = ipa_method_formal_count (node);
610 for (i = 0; i < count; i++)
612 temp = ipa_method_get_tree (node, i);
613 if (TREE_CODE (temp) == PARM_DECL)
614 fprintf (f, " param [%d] : %s\n", i,
615 (*lang_hooks.decl_printable_name) (temp, 2));
621 /* Print ipa_modify data structures of all methods in the
622 callgraph to F. */
623 void
624 ipa_method_modify_print (FILE * f)
626 int i, count;
627 bool temp;
628 struct cgraph_node *node;
630 fprintf (f, "\nMODIFY PRINT\n");
631 for (node = cgraph_nodes; node; node = node->next)
633 fprintf (f, "method %s :: \n", cgraph_node_name (node));
634 count = ipa_method_formal_count (node);
635 for (i = 0; i < count; i++)
637 temp = ipa_method_is_modified (node, i);
638 if (temp)
639 fprintf (f, " param [%d] true \n", i);
640 else
641 fprintf (f, " param [%d] false \n", i);