1 /* Interprocedural analyses.
2 Copyright (C) 2005 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 2, or (at your option) any later
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
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
23 #include "coretypes.h"
25 #include "langhooks.h"
30 #include "tree-flow.h"
31 #include "tree-pass.h"
35 /* This file contains interfaces that can be used for various IPA
38 - ipa_methodlist interface - It is used to create and handle a temporary
39 worklist used in the propagation stage of IPCP. (can be used for more
42 - ipa_callsite interface - for each callsite this interface creates and
43 handles ipa_edge structure associated with it.
45 - ipa_method interface - for each method this interface creates and
46 handles ipa_node structure associated with it. */
48 /* ipa_methodlist interface. */
50 /* Create a new worklist node. */
51 static inline ipa_methodlist_p
52 ipa_create_methodlist_node (void)
54 return (ipa_methodlist_p
) xcalloc (1, sizeof (struct ipa_methodlist
));
57 /* Return true if worklist WL is empty. */
59 ipa_methodlist_not_empty (ipa_methodlist_p wl
)
64 /* Return the method in worklist element WL. */
65 static inline struct cgraph_node
*
66 ipa_methodlist_method (ipa_methodlist_p wl
)
71 /* Make worklist element WL point to method MT in the callgraph. */
73 ipa_methodlist_method_set (ipa_methodlist_p wl
, struct cgraph_node
*mt
)
78 /* Return the next element in the worklist following worklist
80 static inline ipa_methodlist_p
81 ipa_methodlist_next_method (ipa_methodlist_p wl
)
83 return wl
->next_method
;
86 /* Set worklist element WL1 to point to worklist element WL2. */
88 ipa_methodlist_next_method_set (ipa_methodlist_p wl1
, ipa_methodlist_p wl2
)
90 wl1
->next_method
= wl2
;
93 /* Initialize worklist to contain all methods. */
95 ipa_methodlist_init (void)
97 struct cgraph_node
*node
;
101 for (node
= cgraph_nodes
; node
; node
= node
->next
)
102 ipa_add_method (&wl
, node
);
107 /* Add method MT to the worklist. Set worklist element WL
110 ipa_add_method (ipa_methodlist_p
* wl
, struct cgraph_node
*mt
)
112 ipa_methodlist_p temp
;
114 temp
= ipa_create_methodlist_node ();
115 ipa_methodlist_method_set (temp
, mt
);
116 ipa_methodlist_next_method_set (temp
, *wl
);
120 /* Remove a method from the worklist. WL points to the first
121 element in the list, which is removed. */
123 ipa_remove_method (ipa_methodlist_p
* wl
)
125 ipa_methodlist_p first
;
126 struct cgraph_node
*return_method
;
129 *wl
= ipa_methodlist_next_method (*wl
);
130 return_method
= ipa_methodlist_method (first
);
132 return return_method
;
135 /* ipa_method interface. */
137 /* Return number of formals of method MT. */
139 ipa_method_formal_count (struct cgraph_node
*mt
)
141 return IPA_NODE_REF (mt
)->ipa_arg_num
;
144 /* Set number of formals of method MT to I. */
146 ipa_method_formal_count_set (struct cgraph_node
*mt
, int i
)
148 IPA_NODE_REF (mt
)->ipa_arg_num
= i
;
151 /* Return whether I-th formal of MT is modified in MT. */
153 ipa_method_is_modified (struct cgraph_node
*mt
, int i
)
155 return IPA_NODE_REF (mt
)->ipa_mod
[i
];
158 /* Return the tree of I-th formal of MT. */
160 ipa_method_get_tree (struct cgraph_node
*mt
, int i
)
162 return IPA_NODE_REF (mt
)->ipa_param_tree
[i
];
165 /* Create tree map structure for MT. */
167 ipa_method_tree_map_create (struct cgraph_node
*mt
)
169 IPA_NODE_REF (mt
)->ipa_param_tree
=
170 XCNEWVEC (tree
, ipa_method_formal_count (mt
));
173 /* Create modify structure for MT. */
175 ipa_method_modify_create (struct cgraph_node
*mt
)
177 ((struct ipa_node
*) mt
->aux
)->ipa_mod
=
178 XCNEWVEC (bool, ipa_method_formal_count (mt
));
181 /* Set modify of I-th formal of MT to VAL. */
183 ipa_method_modify_set (struct cgraph_node
*mt
, int i
, bool val
)
185 IPA_NODE_REF (mt
)->ipa_mod
[i
] = val
;
188 /* Return index of the formal whose tree is PTREE in method MT. */
190 ipa_method_tree_map (struct cgraph_node
*mt
, tree ptree
)
194 count
= ipa_method_formal_count (mt
);
195 for (i
= 0; i
< count
; i
++)
196 if (IPA_NODE_REF (mt
)->ipa_param_tree
[i
] == ptree
)
202 /* Insert the formal trees to the ipa_param_tree array in method MT. */
204 ipa_method_compute_tree_map (struct cgraph_node
*mt
)
211 ipa_method_tree_map_create (mt
);
213 fnargs
= DECL_ARGUMENTS (fndecl
);
215 for (parm
= fnargs
; parm
; parm
= TREE_CHAIN (parm
))
217 IPA_NODE_REF (mt
)->ipa_param_tree
[param_num
] = parm
;
222 /* Count number of formals in MT. Insert the result to the
225 ipa_method_formal_compute_count (struct cgraph_node
*mt
)
233 fnargs
= DECL_ARGUMENTS (fndecl
);
235 for (parm
= fnargs
; parm
; parm
= TREE_CHAIN (parm
))
237 ipa_method_formal_count_set (mt
, param_num
);
240 /* Check STMT to detect whether a formal is modified within MT,
241 the appropriate entry is updated in the ipa_mod array of ipa_node
242 (associated with MT). */
244 ipa_method_modify_stmt (struct cgraph_node
*mt
, tree stmt
)
249 switch (TREE_CODE (stmt
))
251 case GIMPLE_MODIFY_STMT
:
252 if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt
, 0)) == PARM_DECL
)
254 parm_decl
= GIMPLE_STMT_OPERAND (stmt
, 0);
255 i
= ipa_method_tree_map (mt
, parm_decl
);
257 ipa_method_modify_set (mt
, i
, true);
261 /* Asm code could modify any of the parameters. */
262 for (j
= 0; j
< ipa_method_formal_count (mt
); j
++)
263 ipa_method_modify_set (mt
, j
, true);
270 /* Initialize ipa_mod array of MT. */
272 ipa_method_modify_init (struct cgraph_node
*mt
)
276 ipa_method_modify_create (mt
);
277 count
= ipa_method_formal_count (mt
);
278 for (i
= 0; i
< count
; i
++)
279 ipa_method_modify_set (mt
, i
, false);
282 /* The modify computation driver for MT. Compute which formal arguments
283 of method MT are locally modified. Formals may be modified in MT
284 if their address is taken, or if
285 they appear on the left hand side of an assignment. */
287 ipa_method_compute_modify (struct cgraph_node
*mt
)
293 struct function
*func
;
294 block_stmt_iterator bsi
;
295 tree stmt
, parm_tree
;
297 if (ipa_method_formal_count (mt
) == 0)
300 ipa_method_modify_init (mt
);
302 count
= ipa_method_formal_count (mt
);
303 /* ??? Handle pending sizes case. Set all parameters
304 of the method to be modified. */
306 if (DECL_UNINLINABLE (decl
))
308 for (j
= 0; j
< count
; j
++)
309 ipa_method_modify_set (mt
, j
, true);
312 /* Formals whose address is taken are considered modified. */
313 for (j
= 0; j
< count
; j
++)
315 parm_tree
= ipa_method_get_tree (mt
, j
);
316 if (!is_gimple_reg (parm_tree
)
317 && TREE_ADDRESSABLE (parm_tree
))
318 ipa_method_modify_set (mt
, j
, true);
320 body
= DECL_SAVED_TREE (decl
);
323 func
= DECL_STRUCT_FUNCTION (decl
);
324 FOR_EACH_BB_FN (bb
, func
)
326 for (bsi
= bsi_start (bb
); !bsi_end_p (bsi
); bsi_next (&bsi
))
328 stmt
= bsi_stmt (bsi
);
329 ipa_method_modify_stmt (mt
, stmt
);
336 /* ipa_callsite interface. */
338 /* Return number of arguments in callsite CS. */
340 ipa_callsite_param_count (struct cgraph_edge
*cs
)
342 return IPA_EDGE_REF (cs
)->ipa_param_num
;
345 /* Set number of arguments in callsite CS to I. */
347 ipa_callsite_param_count_set (struct cgraph_edge
*cs
, int i
)
349 IPA_EDGE_REF (cs
)->ipa_param_num
= i
;
352 /* Return the jump function (ipa_jump_func struct) for argument I of
354 struct ipa_jump_func
*
355 ipa_callsite_param (struct cgraph_edge
*cs
, int i
)
357 return &(IPA_EDGE_REF (cs
)->ipa_param_map
[i
]);
360 /* return the callee (cgraph_node) of callsite CS. */
362 ipa_callsite_callee (struct cgraph_edge
*cs
)
367 /* Set field 'type' of jump function (ipa_jump_func struct) of argument I
370 ipa_callsite_param_set_type (struct cgraph_edge
*cs
, int i
,
371 enum jump_func_type type1
)
373 IPA_EDGE_REF (cs
)->ipa_param_map
[i
].type
= type1
;
376 /* Set FORMAL as 'info_type' field of jump function (ipa_jump_func struct)
377 of argument I of callsite CS. */
379 ipa_callsite_param_set_info_type_formal (struct cgraph_edge
*cs
, int i
,
382 ipa_callsite_param (cs
, i
)->info_type
.formal_id
= formal
;
385 /* Set int-valued INFO_TYPE1 as 'info_type' field of
386 jump function (ipa_jump_func struct) of argument I of callsite CS. */
388 ipa_callsite_param_set_info_type (struct cgraph_edge
*cs
, int i
,
391 ipa_callsite_param (cs
, i
)->info_type
.value
= info_type1
;
394 /* Allocate space for callsite CS. */
396 ipa_callsite_param_map_create (struct cgraph_edge
*cs
)
398 IPA_EDGE_REF (cs
)->ipa_param_map
=
399 XCNEWVEC (struct ipa_jump_func
, ipa_callsite_param_count (cs
));
402 /* Return the call expr tree related to callsite CS. */
404 ipa_callsite_tree (struct cgraph_edge
*cs
)
406 return cs
->call_stmt
;
409 /* Return the caller (cgraph_node) of CS. */
410 static inline struct cgraph_node
*
411 ipa_callsite_caller (struct cgraph_edge
*cs
)
416 /* Count number of arguments callsite CS has and store it in
417 ipa_edge structure corresponding to this callsite. */
419 ipa_callsite_compute_count (struct cgraph_edge
*cs
)
424 call_tree
= get_call_expr_in (ipa_callsite_tree (cs
));
425 gcc_assert (TREE_CODE (call_tree
) == CALL_EXPR
);
426 arg_num
= call_expr_nargs (call_tree
);
427 ipa_callsite_param_count_set (cs
, arg_num
);
430 /* Compute jump function for all arguments of callsite CS
431 and insert the information in the ipa_param_map array
432 in the ipa_edge corresponding to this callsite. (Explanation
433 on jump functions is in ipa-prop.h). */
435 ipa_callsite_compute_param (struct cgraph_edge
*cs
)
441 struct cgraph_node
*mt
;
443 struct function
*curr_cfun
;
444 call_expr_arg_iterator iter
;
446 if (ipa_callsite_param_count (cs
) == 0)
448 ipa_callsite_param_map_create (cs
);
449 call_tree
= get_call_expr_in (ipa_callsite_tree (cs
));
450 gcc_assert (TREE_CODE (call_tree
) == CALL_EXPR
);
453 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, call_tree
)
455 /* If the formal parameter was passed as argument, we store
456 FORMAL_IPATYPE and its index in the caller as the jump function
458 if ((TREE_CODE (arg
) == SSA_NAME
459 && TREE_CODE (SSA_NAME_VAR (arg
)) == PARM_DECL
)
460 || TREE_CODE (arg
) == PARM_DECL
)
462 mt
= ipa_callsite_caller (cs
);
463 parm_decl
= TREE_CODE (arg
) == PARM_DECL
? arg
: SSA_NAME_VAR (arg
);
465 i
= ipa_method_tree_map (mt
, parm_decl
);
466 if (TREE_CODE (arg
) == SSA_NAME
&& IS_VALID_TREE_MAP_INDEX (i
))
468 curr_cfun
= DECL_STRUCT_FUNCTION (mt
->decl
);
469 if (!gimple_default_def (curr_cfun
, parm_decl
)
470 || gimple_default_def (curr_cfun
, parm_decl
) != arg
)
471 ipa_method_modify_set (mt
, i
, true);
473 if (!IS_VALID_TREE_MAP_INDEX (i
) || ipa_method_is_modified (mt
, i
))
474 ipa_callsite_param_set_type (cs
, arg_num
, UNKNOWN_IPATYPE
);
477 ipa_callsite_param_set_type (cs
, arg_num
, FORMAL_IPATYPE
);
478 ipa_callsite_param_set_info_type_formal (cs
, arg_num
, i
);
481 /* If a constant value was passed as argument,
482 we store CONST_IPATYPE and its value as the jump function
484 else if (TREE_CODE (arg
) == INTEGER_CST
485 || TREE_CODE (arg
) == REAL_CST
)
487 ipa_callsite_param_set_type (cs
, arg_num
, CONST_IPATYPE
);
488 ipa_callsite_param_set_info_type (cs
, arg_num
, arg
);
490 /* This is for the case of Fortran. If the address of a const_decl
491 was passed as argument then we store
492 CONST_IPATYPE_REF/CONST_IPATYPE_REF and the constant
493 value as the jump function corresponding to this argument. */
494 else if (TREE_CODE (arg
) == ADDR_EXPR
495 && TREE_CODE (TREE_OPERAND (arg
, 0)) == CONST_DECL
)
497 cst_decl
= TREE_OPERAND (arg
, 0);
498 if (TREE_CODE (DECL_INITIAL (cst_decl
)) == INTEGER_CST
499 || TREE_CODE (DECL_INITIAL (cst_decl
)) == REAL_CST
)
501 ipa_callsite_param_set_type (cs
, arg_num
,
503 ipa_callsite_param_set_info_type (cs
, arg_num
,
504 DECL_INITIAL (cst_decl
));
508 ipa_callsite_param_set_type (cs
, arg_num
, UNKNOWN_IPATYPE
);
513 /* Return type of jump function JF. */
515 get_type (struct ipa_jump_func
*jf
)
520 /* Return info type of jump function JF. */
521 union parameter_info
*
522 ipa_jf_get_info_type (struct ipa_jump_func
*jf
)
524 return &(jf
->info_type
);
527 /* Allocate and initialize ipa_node structure.
528 cgraph_node NODE points to the new allocated ipa_node. */
530 ipa_node_create (struct cgraph_node
*node
)
532 node
->aux
= xcalloc (1, sizeof (struct ipa_node
));
535 /* Allocate and initialize ipa_node structure for all
536 nodes in callgraph. */
538 ipa_nodes_create (void)
540 struct cgraph_node
*node
;
542 for (node
= cgraph_nodes
; node
; node
= node
->next
)
543 ipa_node_create (node
);
546 /* Allocate and initialize ipa_edge structure. */
548 ipa_edges_create (void)
550 struct cgraph_node
*node
;
551 struct cgraph_edge
*cs
;
553 for (node
= cgraph_nodes
; node
; node
= node
->next
)
554 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
555 cs
->aux
= xcalloc (1, sizeof (struct ipa_edge
));
558 /* Free ipa_node structure. */
560 ipa_nodes_free (void)
562 struct cgraph_node
*node
;
564 for (node
= cgraph_nodes
; node
; node
= node
->next
)
571 /* Free ipa_edge structure. */
573 ipa_edges_free (void)
575 struct cgraph_node
*node
;
576 struct cgraph_edge
*cs
;
578 for (node
= cgraph_nodes
; node
; node
= node
->next
)
579 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
586 /* Free ipa data structures of ipa_node and ipa_edge. */
590 struct cgraph_node
*node
;
591 struct cgraph_edge
*cs
;
593 for (node
= cgraph_nodes
; node
; node
= node
->next
)
595 if (node
->aux
== NULL
)
597 if (IPA_NODE_REF (node
)->ipcp_cval
)
598 free (IPA_NODE_REF (node
)->ipcp_cval
);
599 if (IPA_NODE_REF (node
)->ipa_param_tree
)
600 free (IPA_NODE_REF (node
)->ipa_param_tree
);
601 if (IPA_NODE_REF (node
)->ipa_mod
)
602 free (IPA_NODE_REF (node
)->ipa_mod
);
603 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
606 if (IPA_EDGE_REF (cs
)->ipa_param_map
)
607 free (IPA_EDGE_REF (cs
)->ipa_param_map
);
612 /* Print ipa_tree_map data structures of all methods in the
615 ipa_method_tree_print (FILE * f
)
619 struct cgraph_node
*node
;
621 fprintf (f
, "\nPARAM TREE MAP PRINT\n");
622 for (node
= cgraph_nodes
; node
; node
= node
->next
)
624 fprintf (f
, "method %s Trees :: \n", cgraph_node_name (node
));
625 count
= ipa_method_formal_count (node
);
626 for (i
= 0; i
< count
; i
++)
628 temp
= ipa_method_get_tree (node
, i
);
629 if (TREE_CODE (temp
) == PARM_DECL
)
630 fprintf (f
, " param [%d] : %s\n", i
,
631 (*lang_hooks
.decl_printable_name
) (temp
, 2));
637 /* Print ipa_modify data structures of all methods in the
640 ipa_method_modify_print (FILE * f
)
644 struct cgraph_node
*node
;
646 fprintf (f
, "\nMODIFY PRINT\n");
647 for (node
= cgraph_nodes
; node
; node
= node
->next
)
649 fprintf (f
, "method %s :: \n", cgraph_node_name (node
));
650 count
= ipa_method_formal_count (node
);
651 for (i
= 0; i
< count
; i
++)
653 temp
= ipa_method_is_modified (node
, i
);
655 fprintf (f
, " param [%d] true \n", i
);
657 fprintf (f
, " param [%d] false \n", i
);