re PR driver/31353 (gcc --help=target gives a linker error.)
[official-gcc.git] / gcc / ipa-cp.c
blob32f8b6d6dcd4d34064993366cbbabbc30c41a6b2
1 /* Interprocedural constant propagation
2 Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
3 Contributed by Razya Ladelsky <RAZYA@il.ibm.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 /* Interprocedural constant propagation.
23 The aim of interprocedural constant propagation (IPCP) is to find which
24 function's argument has the same constant value in each invocation throughout
25 the whole program. For example, for an application consisting of two files,
26 foo1.c, foo2.c:
28 foo1.c contains :
30 int f (int x)
32 g (x);
34 void main (void)
36 f (3);
37 h (3);
40 foo2.c contains :
42 int h (int y)
44 g (y);
46 int g (int y)
48 printf ("value is %d",y);
51 The IPCP algorithm will find that g's formal argument y
52 is always called with the value 3.
54 The algorithm used is based on "Interprocedural Constant Propagation",
55 by Challahan David, Keith D Cooper, Ken Kennedy, Linda Torczon, Comp86,
56 pg 152-161
58 The optimization is divided into three stages:
60 First stage - intraprocedural analysis
61 =======================================
62 This phase computes jump_function and modify information.
64 A jump function for a callsite represents the values passed as actual
65 arguments
66 of the callsite. There are three types of values :
67 Formal - the caller's formal parameter is passed as an actual argument.
68 Constant - a constant is passed as an actual argument.
69 Unknown - neither of the above.
71 In order to compute the jump functions, we need the modify information for
72 the formal parameters of methods.
74 The jump function info, ipa_jump_func, is defined in ipa_edge
75 structure (defined in ipa_prop.h and pointed to by cgraph_node->aux)
76 The modify info, ipa_modify, is defined in ipa_node structure
77 (defined in ipa_prop.h and pointed to by cgraph_edge->aux).
79 -ipcp_init_stage() is the first stage driver.
81 Second stage - interprocedural analysis
82 ========================================
83 This phase does the interprocedural constant propagation.
84 It computes for all formal parameters in the program
85 their cval value that may be:
86 TOP - unknown.
87 BOTTOM - non constant.
88 CONSTANT_TYPE - constant value.
90 Cval of formal f will have a constant value if all callsites to this
91 function have the same constant value passed to f.
93 The cval info, ipcp_formal, is defined in ipa_node structure
94 (defined in ipa_prop.h and pointed to by cgraph_edge->aux).
96 -ipcp_iterate_stage() is the second stage driver.
98 Third phase - transformation of methods code
99 ============================================
100 Propagates the constant-valued formals into the function.
101 For each method mt, whose parameters are consts, we create a clone/version.
103 We use two ways to annotate the versioned function with the constant
104 formal information:
105 1. We insert an assignment statement 'parameter = const' at the beginning
106 of the cloned method.
107 2. For read-only formals whose address is not taken, we replace all uses
108 of the formal with the constant (we provide versioning with an
109 ipa_replace_map struct representing the trees we want to replace).
111 We also need to modify some callsites to call to the cloned methods instead
112 of the original ones. For a callsite passing an argument found to be a
113 constant by IPCP, there are two different cases to handle:
114 1. A constant is passed as an argument.
115 2. A parameter (of the caller) passed as an argument (pass through argument).
117 In the first case, the callsite in the original caller should be redirected
118 to call the cloned callee.
119 In the second case, both the caller and the callee have clones
120 and the callsite of the cloned caller would be redirected to call to
121 the cloned callee.
123 The callgraph is updated accordingly.
125 This update is done in two stages:
126 First all cloned methods are created during a traversal of the callgraph,
127 during which all callsites are redirected to call the cloned method.
128 Then the callsites are traversed and updated as described above.
130 -ipcp_insert_stage() is the third phase driver.
134 #include "config.h"
135 #include "system.h"
136 #include "coretypes.h"
137 #include "tree.h"
138 #include "target.h"
139 #include "cgraph.h"
140 #include "ipa-prop.h"
141 #include "tree-flow.h"
142 #include "tree-pass.h"
143 #include "flags.h"
144 #include "timevar.h"
145 #include "diagnostic.h"
146 #include "tree-dump.h"
147 #include "tree-inline.h"
149 /* Get orig node field of ipa_node associated with method MT. */
150 static inline struct cgraph_node *
151 ipcp_method_orig_node (struct cgraph_node *mt)
153 return IPA_NODE_REF (mt)->ipcp_orig_node;
156 /* Return true if NODE is a cloned/versioned method. */
157 static inline bool
158 ipcp_method_is_cloned (struct cgraph_node *node)
160 return (ipcp_method_orig_node (node) != NULL);
163 /* Set ORIG_NODE in ipa_node associated with method NODE. */
164 static inline void
165 ipcp_method_set_orig_node (struct cgraph_node *node,
166 struct cgraph_node *orig_node)
168 IPA_NODE_REF (node)->ipcp_orig_node = orig_node;
171 /* Create ipa_node and its data structures for NEW_NODE.
172 Set ORIG_NODE as the orig_node field in ipa_node. */
173 static void
174 ipcp_cloned_create (struct cgraph_node *orig_node,
175 struct cgraph_node *new_node)
177 ipa_node_create (new_node);
178 ipcp_method_set_orig_node (new_node, orig_node);
179 ipa_method_formal_compute_count (new_node);
180 ipa_method_compute_tree_map (new_node);
183 /* Return cval_type field of CVAL. */
184 static inline enum cvalue_type
185 ipcp_cval_get_cvalue_type (struct ipcp_formal *cval)
187 return cval->cval_type;
190 /* Return scale for MT. */
191 static inline gcov_type
192 ipcp_method_get_scale (struct cgraph_node *mt)
194 return IPA_NODE_REF (mt)->count_scale;
197 /* Set COUNT as scale for MT. */
198 static inline void
199 ipcp_method_set_scale (struct cgraph_node *node, gcov_type count)
201 IPA_NODE_REF (node)->count_scale = count;
204 /* Set TYPE as cval_type field of CVAL. */
205 static inline void
206 ipcp_cval_set_cvalue_type (struct ipcp_formal *cval, enum cvalue_type type)
208 cval->cval_type = type;
211 /* Return cvalue field of CVAL. */
212 static inline union parameter_info *
213 ipcp_cval_get_cvalue (struct ipcp_formal *cval)
215 return &(cval->cvalue);
218 /* Set VALUE as cvalue field CVAL. */
219 static inline void
220 ipcp_cval_set_cvalue (struct ipcp_formal *cval, union parameter_info *value,
221 enum cvalue_type type)
223 if (type == CONST_VALUE || type == CONST_VALUE_REF)
224 cval->cvalue.value = value->value;
227 /* Return whether TYPE is a constant type. */
228 static bool
229 ipcp_type_is_const (enum cvalue_type type)
231 if (type == CONST_VALUE || type == CONST_VALUE_REF)
232 return true;
233 else
234 return false;
237 /* Return true if CONST_VAL1 and CONST_VAL2 are equal. */
238 static inline bool
239 ipcp_cval_equal_cvalues (union parameter_info *const_val1,
240 union parameter_info *const_val2,
241 enum cvalue_type type1, enum cvalue_type type2)
243 gcc_assert (ipcp_type_is_const (type1) && ipcp_type_is_const (type2));
244 if (type1 != type2)
245 return false;
247 if (operand_equal_p (const_val1->value, const_val2->value, 0))
248 return true;
250 return false;
253 /* Compute Meet arithmetics:
254 Meet (BOTTOM, x) = BOTTOM
255 Meet (TOP,x) = x
256 Meet (const_a,const_b) = BOTTOM, if const_a != const_b.
257 MEET (const_a,const_b) = const_a, if const_a == const_b.*/
258 static void
259 ipcp_cval_meet (struct ipcp_formal *cval, struct ipcp_formal *cval1,
260 struct ipcp_formal *cval2)
262 if (ipcp_cval_get_cvalue_type (cval1) == BOTTOM
263 || ipcp_cval_get_cvalue_type (cval2) == BOTTOM)
265 ipcp_cval_set_cvalue_type (cval, BOTTOM);
266 return;
268 if (ipcp_cval_get_cvalue_type (cval1) == TOP)
270 ipcp_cval_set_cvalue_type (cval, ipcp_cval_get_cvalue_type (cval2));
271 ipcp_cval_set_cvalue (cval, ipcp_cval_get_cvalue (cval2),
272 ipcp_cval_get_cvalue_type (cval2));
273 return;
275 if (ipcp_cval_get_cvalue_type (cval2) == TOP)
277 ipcp_cval_set_cvalue_type (cval, ipcp_cval_get_cvalue_type (cval1));
278 ipcp_cval_set_cvalue (cval, ipcp_cval_get_cvalue (cval1),
279 ipcp_cval_get_cvalue_type (cval1));
280 return;
282 if (!ipcp_cval_equal_cvalues (ipcp_cval_get_cvalue (cval1),
283 ipcp_cval_get_cvalue (cval2),
284 ipcp_cval_get_cvalue_type (cval1),
285 ipcp_cval_get_cvalue_type (cval2)))
287 ipcp_cval_set_cvalue_type (cval, BOTTOM);
288 return;
290 ipcp_cval_set_cvalue_type (cval, ipcp_cval_get_cvalue_type (cval1));
291 ipcp_cval_set_cvalue (cval, ipcp_cval_get_cvalue (cval1),
292 ipcp_cval_get_cvalue_type (cval1));
295 /* Return cval structure for the formal at index INFO_TYPE in MT. */
296 static inline struct ipcp_formal *
297 ipcp_method_cval (struct cgraph_node *mt, int info_type)
299 return &(IPA_NODE_REF (mt)->ipcp_cval[info_type]);
302 /* Given the jump function (TYPE, INFO_TYPE), compute a new value of CVAL.
303 If TYPE is FORMAL_IPA_TYPE, the cval of the corresponding formal is
304 drawn from MT. */
305 static void
306 ipcp_cval_compute (struct ipcp_formal *cval, struct cgraph_node *mt,
307 enum jump_func_type type, union parameter_info *info_type)
309 if (type == UNKNOWN_IPATYPE)
310 ipcp_cval_set_cvalue_type (cval, BOTTOM);
311 else if (type == CONST_IPATYPE)
313 ipcp_cval_set_cvalue_type (cval, CONST_VALUE);
314 ipcp_cval_set_cvalue (cval, info_type, CONST_VALUE);
316 else if (type == CONST_IPATYPE_REF)
318 ipcp_cval_set_cvalue_type (cval, CONST_VALUE_REF);
319 ipcp_cval_set_cvalue (cval, info_type, CONST_VALUE_REF);
321 else if (type == FORMAL_IPATYPE)
323 enum cvalue_type type =
324 ipcp_cval_get_cvalue_type (ipcp_method_cval
325 (mt, info_type->formal_id));
326 ipcp_cval_set_cvalue_type (cval, type);
327 ipcp_cval_set_cvalue (cval,
328 ipcp_cval_get_cvalue (ipcp_method_cval
329 (mt, info_type->formal_id)),
330 type);
334 /* True when CVAL1 and CVAL2 values are not the same. */
335 static bool
336 ipcp_cval_changed (struct ipcp_formal *cval1, struct ipcp_formal *cval2)
338 if (ipcp_cval_get_cvalue_type (cval1) == ipcp_cval_get_cvalue_type (cval2))
340 if (ipcp_cval_get_cvalue_type (cval1) != CONST_VALUE &&
341 ipcp_cval_get_cvalue_type (cval1) != CONST_VALUE_REF)
342 return false;
343 if (ipcp_cval_equal_cvalues (ipcp_cval_get_cvalue (cval1),
344 ipcp_cval_get_cvalue (cval2),
345 ipcp_cval_get_cvalue_type (cval1),
346 ipcp_cval_get_cvalue_type (cval2)))
347 return false;
349 return true;
352 /* Create cval structure for method MT. */
353 static inline void
354 ipcp_formal_create (struct cgraph_node *mt)
356 IPA_NODE_REF (mt)->ipcp_cval =
357 XCNEWVEC (struct ipcp_formal, ipa_method_formal_count (mt));
360 /* Set cval structure of I-th formal of MT to CVAL. */
361 static inline void
362 ipcp_method_cval_set (struct cgraph_node *mt, int i, struct ipcp_formal *cval)
364 IPA_NODE_REF (mt)->ipcp_cval[i].cval_type = cval->cval_type;
365 ipcp_cval_set_cvalue (ipcp_method_cval (mt, i),
366 ipcp_cval_get_cvalue (cval), cval->cval_type);
369 /* Set type of cval structure of formal I of MT to CVAL_TYPE1. */
370 static inline void
371 ipcp_method_cval_set_cvalue_type (struct cgraph_node *mt, int i,
372 enum cvalue_type cval_type1)
374 IPA_NODE_REF (mt)->ipcp_cval[i].cval_type = cval_type1;
377 /* Print ipcp_cval data structures to F. */
378 static void
379 ipcp_method_cval_print (FILE * f)
381 struct cgraph_node *node;
382 int i, count;
383 tree cvalue;
385 fprintf (f, "\nCVAL PRINT\n");
386 for (node = cgraph_nodes; node; node = node->next)
388 fprintf (f, "Printing cvals %s:\n", cgraph_node_name (node));
389 count = ipa_method_formal_count (node);
390 for (i = 0; i < count; i++)
392 if (ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i))
393 == CONST_VALUE
394 || ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i)) ==
395 CONST_VALUE_REF)
397 fprintf (f, " param [%d]: ", i);
398 fprintf (f, "type is CONST ");
399 cvalue =
400 ipcp_cval_get_cvalue (ipcp_method_cval (node, i))->value;
401 print_generic_expr (f, cvalue, 0);
402 fprintf (f, "\n");
404 else if (ipcp_method_cval (node, i)->cval_type == TOP)
405 fprintf (f, "param [%d]: type is TOP \n", i);
406 else
407 fprintf (f, "param [%d]: type is BOTTOM \n", i);
412 /* Initialize ipcp_cval array of MT with TOP values.
413 All cvals for a method's formal parameters are initialized to BOTTOM
414 The currently supported types are integer types, real types and
415 Fortran constants (i.e. references to constants defined as
416 const_decls). All other types are not analyzed and therefore are
417 assigned with BOTTOM. */
418 static void
419 ipcp_method_cval_init (struct cgraph_node *mt)
421 int i;
422 tree parm_tree;
424 ipcp_formal_create (mt);
425 for (i = 0; i < ipa_method_formal_count (mt); i++)
427 parm_tree = ipa_method_get_tree (mt, i);
428 if (INTEGRAL_TYPE_P (TREE_TYPE (parm_tree))
429 || SCALAR_FLOAT_TYPE_P (TREE_TYPE (parm_tree))
430 || POINTER_TYPE_P (TREE_TYPE (parm_tree)))
431 ipcp_method_cval_set_cvalue_type (mt, i, TOP);
432 else
433 ipcp_method_cval_set_cvalue_type (mt, i, BOTTOM);
437 /* Create a new assignment statment and make
438 it the first statement in the function FN
439 tree.
440 PARM1 is the lhs of the assignment and
441 VAL is the rhs. */
442 static void
443 constant_val_insert (tree parm1, tree val)
445 tree init_stmt = NULL;
446 edge e_step;
448 init_stmt = build_gimple_modify_stmt (parm1, val);
450 if (init_stmt)
452 e_step = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun));
453 bsi_insert_on_edge_immediate (e_step, init_stmt);
457 /* build INTEGER_CST tree with type TREE_TYPE and
458 value according to CVALUE. Return the tree. */
459 static tree
460 build_const_val (union parameter_info *cvalue, enum cvalue_type type,
461 tree tree_type)
463 tree const_val = NULL;
465 gcc_assert (ipcp_type_is_const (type));
466 const_val = fold_convert (tree_type, cvalue->value);
467 return const_val;
470 /* Build the tree representing the constant and call
471 constant_val_insert(). */
472 static void
473 ipcp_propagate_const (struct cgraph_node *mt, int param,
474 union parameter_info *cvalue, enum cvalue_type type)
476 tree const_val;
477 tree parm_tree;
479 if (dump_file)
480 fprintf (dump_file, "propagating const to %s\n", cgraph_node_name (mt));
481 parm_tree = ipa_method_get_tree (mt, param);
482 const_val = build_const_val (cvalue, type, TREE_TYPE (parm_tree));
483 constant_val_insert (parm_tree, const_val);
486 /* Compute the proper scale for NODE. It is the ratio between
487 the number of direct calls (represented on the incoming
488 cgraph_edges) and sum of all invocations of NODE (represented
489 as count in cgraph_node). */
490 static void
491 ipcp_method_compute_scale (struct cgraph_node *node)
493 gcov_type sum;
494 struct cgraph_edge *cs;
496 sum = 0;
497 /* Compute sum of all counts of callers. */
498 for (cs = node->callers; cs != NULL; cs = cs->next_caller)
499 sum += cs->count;
500 if (node->count == 0)
501 ipcp_method_set_scale (node, 0);
502 else
503 ipcp_method_set_scale (node, sum * REG_BR_PROB_BASE / node->count);
506 /* Initialization and computation of IPCP data structures.
507 It is an intraprocedural
508 analysis of methods, which gathers information to be propagated
509 later on. */
510 static void
511 ipcp_init_stage (void)
513 struct cgraph_node *node;
514 struct cgraph_edge *cs;
516 for (node = cgraph_nodes; node; node = node->next)
518 ipa_method_formal_compute_count (node);
519 ipa_method_compute_tree_map (node);
520 ipcp_method_cval_init (node);
521 ipa_method_compute_modify (node);
522 ipcp_method_compute_scale (node);
524 for (node = cgraph_nodes; node; node = node->next)
526 /* building jump functions */
527 for (cs = node->callees; cs; cs = cs->next_callee)
529 ipa_callsite_compute_count (cs);
530 if (ipa_callsite_param_count (cs)
531 != ipa_method_formal_count (cs->callee))
533 /* Handle cases of functions with
534 a variable number of parameters. */
535 ipa_callsite_param_count_set (cs, 0);
536 ipa_method_formal_count_set (cs->callee, 0);
538 else
539 ipa_callsite_compute_param (cs);
544 /* Return true if there are some formal parameters whose value is TOP.
545 Change their values to BOTTOM, since they weren't determined. */
546 static bool
547 ipcp_after_propagate (void)
549 int i, count;
550 struct cgraph_node *node;
551 bool prop_again;
553 prop_again = false;
554 for (node = cgraph_nodes; node; node = node->next)
556 count = ipa_method_formal_count (node);
557 for (i = 0; i < count; i++)
558 if (ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i)) == TOP)
560 prop_again = true;
561 ipcp_method_cval_set_cvalue_type (node, i, BOTTOM);
564 return prop_again;
567 /* Interprocedural analysis. The algorithm propagates constants from
568 the caller's parameters to the callee's arguments. */
569 static void
570 ipcp_propagate_stage (void)
572 int i;
573 struct ipcp_formal cval1 = { 0, {0} }, cval = { 0,{0} };
574 struct ipcp_formal *cval2;
575 struct cgraph_node *mt, *callee;
576 struct cgraph_edge *cs;
577 struct ipa_jump_func *jump_func;
578 enum jump_func_type type;
579 union parameter_info *info_type;
580 ipa_methodlist_p wl;
581 int count;
583 /* Initialize worklist to contain all methods. */
584 wl = ipa_methodlist_init ();
585 while (ipa_methodlist_not_empty (wl))
587 mt = ipa_remove_method (&wl);
588 for (cs = mt->callees; cs; cs = cs->next_callee)
590 callee = ipa_callsite_callee (cs);
591 count = ipa_callsite_param_count (cs);
592 for (i = 0; i < count; i++)
594 jump_func = ipa_callsite_param (cs, i);
595 type = get_type (jump_func);
596 info_type = ipa_jf_get_info_type (jump_func);
597 ipcp_cval_compute (&cval1, mt, type, info_type);
598 cval2 = ipcp_method_cval (callee, i);
599 ipcp_cval_meet (&cval, &cval1, cval2);
600 if (ipcp_cval_changed (&cval, cval2))
602 ipcp_method_cval_set (callee, i, &cval);
603 ipa_add_method (&wl, callee);
610 /* Call the constant propagation algorithm and re-call it if necessary
611 (if there are undetermined values left). */
612 static void
613 ipcp_iterate_stage (void)
615 ipcp_propagate_stage ();
616 if (ipcp_after_propagate ())
617 /* Some cvals have changed from TOP to BOTTOM.
618 This change should be propagated. */
619 ipcp_propagate_stage ();
622 /* Check conditions to forbid constant insertion to MT. */
623 static bool
624 ipcp_method_dont_insert_const (struct cgraph_node *mt)
626 /* ??? Handle pending sizes case. */
627 if (DECL_UNINLINABLE (mt->decl))
628 return true;
629 return false;
632 /* Print ipa_jump_func data structures to F. */
633 static void
634 ipcp_callsite_param_print (FILE * f)
636 struct cgraph_node *node;
637 int i, count;
638 struct cgraph_edge *cs;
639 struct ipa_jump_func *jump_func;
640 enum jump_func_type type;
641 tree info_type;
643 fprintf (f, "\nCALLSITE PARAM PRINT\n");
644 for (node = cgraph_nodes; node; node = node->next)
646 for (cs = node->callees; cs; cs = cs->next_callee)
648 fprintf (f, "callsite %s ", cgraph_node_name (node));
649 fprintf (f, "-> %s :: \n", cgraph_node_name (cs->callee));
650 count = ipa_callsite_param_count (cs);
651 for (i = 0; i < count; i++)
653 jump_func = ipa_callsite_param (cs, i);
654 type = get_type (jump_func);
656 fprintf (f, " param %d: ", i);
657 if (type == UNKNOWN_IPATYPE)
658 fprintf (f, "UNKNOWN\n");
659 else if (type == CONST_IPATYPE || type == CONST_IPATYPE_REF)
661 info_type = ipa_jf_get_info_type (jump_func)->value;
662 fprintf (f, "CONST : ");
663 print_generic_expr (f, info_type, 0);
664 fprintf (f, "\n");
666 else if (type == FORMAL_IPATYPE)
668 fprintf (f, "FORMAL : ");
669 fprintf (f, "%d\n",
670 ipa_jf_get_info_type (jump_func)->formal_id);
677 /* Print count scale data structures. */
678 static void
679 ipcp_method_scale_print (FILE * f)
681 struct cgraph_node *node;
683 for (node = cgraph_nodes; node; node = node->next)
685 fprintf (f, "printing scale for %s: ", cgraph_node_name (node));
686 fprintf (f, "value is " HOST_WIDE_INT_PRINT_DEC
687 " \n", (HOST_WIDE_INT) ipcp_method_get_scale (node));
691 /* Print counts of all cgraph nodes. */
692 static void
693 ipcp_profile_mt_count_print (FILE * f)
695 struct cgraph_node *node;
697 for (node = cgraph_nodes; node; node = node->next)
699 fprintf (f, "method %s: ", cgraph_node_name (node));
700 fprintf (f, "count is " HOST_WIDE_INT_PRINT_DEC
701 " \n", (HOST_WIDE_INT) node->count);
705 /* Print counts of all cgraph edges. */
706 static void
707 ipcp_profile_cs_count_print (FILE * f)
709 struct cgraph_node *node;
710 struct cgraph_edge *cs;
712 for (node = cgraph_nodes; node; node = node->next)
714 for (cs = node->callees; cs; cs = cs->next_callee)
716 fprintf (f, "%s -> %s ", cgraph_node_name (cs->caller),
717 cgraph_node_name (cs->callee));
718 fprintf (f, "count is " HOST_WIDE_INT_PRINT_DEC " \n",
719 (HOST_WIDE_INT) cs->count);
724 /* Print all counts and probabilities of cfg edges of all methods. */
725 static void
726 ipcp_profile_edge_print (FILE * f)
728 struct cgraph_node *node;
729 basic_block bb;
730 edge_iterator ei;
731 edge e;
733 for (node = cgraph_nodes; node; node = node->next)
735 fprintf (f, "method %s: \n", cgraph_node_name (node));
736 if (DECL_SAVED_TREE (node->decl))
738 bb =
739 ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl));
740 fprintf (f, "ENTRY: ");
741 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
742 " %d\n", (HOST_WIDE_INT) bb->count, bb->frequency);
744 if (bb->succs)
745 FOR_EACH_EDGE (e, ei, bb->succs)
747 if (e->dest ==
748 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION
749 (node->decl)))
750 fprintf (f, "edge ENTRY -> EXIT, Count");
751 else
752 fprintf (f, "edge ENTRY -> %d, Count", e->dest->index);
753 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
754 " Prob %d\n", (HOST_WIDE_INT) e->count,
755 e->probability);
757 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
759 fprintf (f, "bb[%d]: ", bb->index);
760 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
761 " %d\n", (HOST_WIDE_INT) bb->count, bb->frequency);
762 FOR_EACH_EDGE (e, ei, bb->succs)
764 if (e->dest ==
765 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION
766 (node->decl)))
767 fprintf (f, "edge %d -> EXIT, Count", e->src->index);
768 else
769 fprintf (f, "edge %d -> %d, Count", e->src->index,
770 e->dest->index);
771 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC " Prob %d\n",
772 (HOST_WIDE_INT) e->count, e->probability);
779 /* Print counts and frequencies for all basic blocks of all methods. */
780 static void
781 ipcp_profile_bb_print (FILE * f)
783 basic_block bb;
784 struct cgraph_node *node;
786 for (node = cgraph_nodes; node; node = node->next)
788 fprintf (f, "method %s: \n", cgraph_node_name (node));
789 if (node->analyzed)
791 bb =
792 ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl));
793 fprintf (f, "ENTRY: Count");
794 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
795 " Frquency %d\n", (HOST_WIDE_INT) bb->count,
796 bb->frequency);
798 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
800 fprintf (f, "bb[%d]: Count", bb->index);
801 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
802 " Frequency %d\n", (HOST_WIDE_INT) bb->count,
803 bb->frequency);
805 bb =
806 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl));
807 fprintf (f, "EXIT: Count");
808 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
809 " Frequency %d\n", (HOST_WIDE_INT) bb->count,
810 bb->frequency);
816 /* Print all IPCP data structures to F. */
817 static void
818 ipcp_structures_print (FILE * f)
820 ipcp_method_cval_print (f);
821 ipcp_method_scale_print (f);
822 ipa_method_tree_print (f);
823 ipa_method_modify_print (f);
824 ipcp_callsite_param_print (f);
827 /* Print profile info for all methods. */
828 static void
829 ipcp_profile_print (FILE * f)
831 fprintf (f, "\nNODE COUNTS :\n");
832 ipcp_profile_mt_count_print (f);
833 fprintf (f, "\nCS COUNTS stage:\n");
834 ipcp_profile_cs_count_print (f);
835 fprintf (f, "\nBB COUNTS and FREQUENCIES :\n");
836 ipcp_profile_bb_print (f);
837 fprintf (f, "\nCFG EDGES COUNTS and PROBABILITIES :\n");
838 ipcp_profile_edge_print (f);
841 /* Build and initialize ipa_replace_map struct
842 according to TYPE. This struct is read by versioning, which
843 operates according to the flags sent. PARM_TREE is the
844 formal's tree found to be constant. CVALUE represents the constant. */
845 static struct ipa_replace_map *
846 ipcp_replace_map_create (struct function *func, enum cvalue_type type,
847 tree parm_tree, union parameter_info *cvalue)
849 struct ipa_replace_map *replace_map;
850 tree const_val;
852 replace_map = XCNEW (struct ipa_replace_map);
853 gcc_assert (ipcp_type_is_const (type));
854 if (type != CONST_VALUE_REF
855 && is_gimple_reg (parm_tree) && gimple_default_def (func, parm_tree)
856 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_default_def (func, parm_tree)))
858 if (dump_file)
859 fprintf (dump_file, "replacing param with const\n");
860 const_val = build_const_val (cvalue, type, TREE_TYPE (parm_tree));
861 replace_map->old_tree =gimple_default_def (func, parm_tree);
862 replace_map->new_tree = const_val;
863 replace_map->replace_p = true;
864 replace_map->ref_p = false;
866 else
868 replace_map->old_tree = NULL;
869 replace_map->new_tree = NULL;
870 replace_map->replace_p = false;
871 replace_map->ref_p = false;
874 return replace_map;
877 /* Return true if this callsite should be redirected to
878 the orig callee (instead of the cloned one). */
879 static bool
880 ipcp_redirect (struct cgraph_edge *cs)
882 struct cgraph_node *caller, *callee, *orig_callee;
883 int i, count;
884 struct ipa_jump_func *jump_func;
885 enum jump_func_type type;
886 enum cvalue_type cval_type;
888 caller = cs->caller;
889 callee = cs->callee;
890 orig_callee = ipcp_method_orig_node (callee);
891 count = ipa_method_formal_count (orig_callee);
892 for (i = 0; i < count; i++)
894 cval_type =
895 ipcp_cval_get_cvalue_type (ipcp_method_cval (orig_callee, i));
896 if (ipcp_type_is_const (cval_type))
898 jump_func = ipa_callsite_param (cs, i);
899 type = get_type (jump_func);
900 if (type != CONST_IPATYPE && type != CONST_IPATYPE_REF)
901 return true;
905 return false;
908 /* Fix the callsites and the callgraph after function cloning was done. */
909 static void
910 ipcp_update_callgraph (void)
912 struct cgraph_node *node, *orig_callee;
913 struct cgraph_edge *cs;
915 for (node = cgraph_nodes; node; node = node->next)
917 /* want to fix only original nodes */
918 if (ipcp_method_is_cloned (node))
919 continue;
920 for (cs = node->callees; cs; cs = cs->next_callee)
921 if (ipcp_method_is_cloned (cs->callee))
923 /* Callee is a cloned node */
924 orig_callee = ipcp_method_orig_node (cs->callee);
925 if (ipcp_redirect (cs))
927 cgraph_redirect_edge_callee (cs, orig_callee);
928 TREE_OPERAND (CALL_EXPR_FN (get_call_expr_in (cs->call_stmt)),
929 0) =
930 orig_callee->decl;
936 /* Update all cfg basic blocks in NODE according to SCALE. */
937 static void
938 ipcp_update_bb_counts (struct cgraph_node *node, gcov_type scale)
940 basic_block bb;
942 FOR_ALL_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
943 bb->count = bb->count * scale / REG_BR_PROB_BASE;
946 /* Update all cfg edges in NODE according to SCALE. */
947 static void
948 ipcp_update_edges_counts (struct cgraph_node *node, gcov_type scale)
950 basic_block bb;
951 edge_iterator ei;
952 edge e;
954 FOR_ALL_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
955 FOR_EACH_EDGE (e, ei, bb->succs)
956 e->count = e->count * scale / REG_BR_PROB_BASE;
959 /* Update profiling info for versioned methods and the
960 methods they were versioned from. */
961 static void
962 ipcp_update_profiling (void)
964 struct cgraph_node *node, *orig_node;
965 gcov_type scale, scale_complement;
966 struct cgraph_edge *cs;
968 for (node = cgraph_nodes; node; node = node->next)
970 if (ipcp_method_is_cloned (node))
972 orig_node = ipcp_method_orig_node (node);
973 scale = ipcp_method_get_scale (orig_node);
974 node->count = orig_node->count * scale / REG_BR_PROB_BASE;
975 scale_complement = REG_BR_PROB_BASE - scale;
976 orig_node->count =
977 orig_node->count * scale_complement / REG_BR_PROB_BASE;
978 for (cs = node->callees; cs; cs = cs->next_callee)
979 cs->count = cs->count * scale / REG_BR_PROB_BASE;
980 for (cs = orig_node->callees; cs; cs = cs->next_callee)
981 cs->count = cs->count * scale_complement / REG_BR_PROB_BASE;
982 ipcp_update_bb_counts (node, scale);
983 ipcp_update_bb_counts (orig_node, scale_complement);
984 ipcp_update_edges_counts (node, scale);
985 ipcp_update_edges_counts (orig_node, scale_complement);
990 /* Propagate the constant parameters found by ipcp_iterate_stage()
991 to the function's code. */
992 static void
993 ipcp_insert_stage (void)
995 struct cgraph_node *node, *node1 = NULL;
996 int i, const_param;
997 union parameter_info *cvalue;
998 VEC (cgraph_edge_p, heap) * redirect_callers;
999 varray_type replace_trees;
1000 struct cgraph_edge *cs;
1001 int node_callers, count;
1002 tree parm_tree;
1003 enum cvalue_type type;
1004 struct ipa_replace_map *replace_param;
1006 for (node = cgraph_nodes; node; node = node->next)
1008 /* Propagation of the constant is forbidden in
1009 certain conditions. */
1010 if (!node->analyzed || ipcp_method_dont_insert_const (node))
1011 continue;
1012 const_param = 0;
1013 count = ipa_method_formal_count (node);
1014 for (i = 0; i < count; i++)
1016 type = ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i));
1017 if (ipcp_type_is_const (type))
1018 const_param++;
1020 if (const_param == 0)
1021 continue;
1022 VARRAY_GENERIC_PTR_INIT (replace_trees, const_param, "replace_trees");
1023 for (i = 0; i < count; i++)
1025 type = ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i));
1026 if (ipcp_type_is_const (type))
1028 cvalue = ipcp_cval_get_cvalue (ipcp_method_cval (node, i));
1029 parm_tree = ipa_method_get_tree (node, i);
1030 replace_param =
1031 ipcp_replace_map_create (DECL_STRUCT_FUNCTION (node->decl),
1032 type, parm_tree, cvalue);
1033 VARRAY_PUSH_GENERIC_PTR (replace_trees, replace_param);
1036 /* Compute how many callers node has. */
1037 node_callers = 0;
1038 for (cs = node->callers; cs != NULL; cs = cs->next_caller)
1039 node_callers++;
1040 redirect_callers = VEC_alloc (cgraph_edge_p, heap, node_callers);
1041 for (cs = node->callers; cs != NULL; cs = cs->next_caller)
1042 VEC_quick_push (cgraph_edge_p, redirect_callers, cs);
1043 /* Redirecting all the callers of the node to the
1044 new versioned node. */
1045 node1 =
1046 cgraph_function_versioning (node, redirect_callers, replace_trees);
1047 VEC_free (cgraph_edge_p, heap, redirect_callers);
1048 VARRAY_CLEAR (replace_trees);
1049 if (node1 == NULL)
1050 continue;
1051 if (dump_file)
1052 fprintf (dump_file, "versioned function %s\n",
1053 cgraph_node_name (node));
1054 ipcp_cloned_create (node, node1);
1055 if (const_param > 0)
1057 push_cfun (DECL_STRUCT_FUNCTION (node1->decl));
1058 tree_register_cfg_hooks ();
1059 current_function_decl = node1->decl;
1061 for (i = 0; i < count; i++)
1063 type = ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i));
1064 if (ipcp_type_is_const (type))
1066 cvalue = ipcp_cval_get_cvalue (ipcp_method_cval (node, i));
1067 parm_tree = ipa_method_get_tree (node, i);
1068 if (type != CONST_VALUE_REF && !is_gimple_reg (parm_tree))
1069 ipcp_propagate_const (node1, i, cvalue, type);
1072 if (gimple_in_ssa_p (cfun))
1074 update_ssa (TODO_update_ssa);
1075 #ifdef ENABLE_CHECKING
1076 verify_ssa (true);
1077 #endif
1079 free_dominance_info (CDI_DOMINATORS);
1080 free_dominance_info (CDI_POST_DOMINATORS);
1081 pop_cfun ();
1082 current_function_decl = NULL;
1084 if (dump_file)
1085 dump_function_to_file (node1->decl, dump_file, dump_flags);
1087 ipcp_update_callgraph ();
1088 ipcp_update_profiling ();
1091 /* The IPCP driver. */
1092 static unsigned int
1093 ipcp_driver (void)
1095 if (dump_file)
1096 fprintf (dump_file, "\nIPA constant propagation start:\n");
1097 ipa_nodes_create ();
1098 ipa_edges_create ();
1099 /* 1. Call the init stage to initialize
1100 the ipa_node and ipa_edge structures. */
1101 ipcp_init_stage ();
1102 if (dump_file)
1104 fprintf (dump_file, "\nIPA structures before propagation:\n");
1105 ipcp_structures_print (dump_file);
1107 /* 2. Do the interprocedural propagation. */
1108 ipcp_iterate_stage ();
1109 if (dump_file)
1111 fprintf (dump_file, "\nIPA structures after propagation:\n");
1112 ipcp_structures_print (dump_file);
1113 fprintf (dump_file, "\nProfiling info before insert stage:\n");
1114 ipcp_profile_print (dump_file);
1116 /* 3. Insert the constants found to the functions. */
1117 ipcp_insert_stage ();
1118 if (dump_file)
1120 fprintf (dump_file, "\nProfiling info after insert stage:\n");
1121 ipcp_profile_print (dump_file);
1123 /* Free all IPCP structures. */
1124 ipa_free ();
1125 ipa_nodes_free ();
1126 ipa_edges_free ();
1127 if (dump_file)
1128 fprintf (dump_file, "\nIPA constant propagation end\n");
1129 cgraph_remove_unreachable_nodes (true, NULL);
1130 return 0;
1133 /* Gate for IPCP optimization. */
1134 static bool
1135 cgraph_gate_cp (void)
1137 return flag_ipa_cp;
1140 struct tree_opt_pass pass_ipa_cp = {
1141 "cp", /* name */
1142 cgraph_gate_cp, /* gate */
1143 ipcp_driver, /* execute */
1144 NULL, /* sub */
1145 NULL, /* next */
1146 0, /* static_pass_number */
1147 TV_IPA_CONSTANT_PROP, /* tv_id */
1148 0, /* properties_required */
1149 PROP_trees, /* properties_provided */
1150 0, /* properties_destroyed */
1151 0, /* todo_flags_start */
1152 TODO_dump_cgraph | TODO_dump_func, /* todo_flags_finish */
1153 0 /* letter */