target-supports.exp (check_effective_target_mips_soft_float): Return true for MIPS16...
[official-gcc.git] / gcc / ipa-cp.c
blob088319dc65c1a3c157a310ab2e11f68d2d24abd5
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 3, 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 COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* Interprocedural constant propagation.
22 The aim of interprocedural constant propagation (IPCP) is to find which
23 function's argument has the same constant value in each invocation throughout
24 the whole program. For example, for an application consisting of two files,
25 foo1.c, foo2.c:
27 foo1.c contains :
29 int f (int x)
31 g (x);
33 void main (void)
35 f (3);
36 h (3);
39 foo2.c contains :
41 int h (int y)
43 g (y);
45 int g (int y)
47 printf ("value is %d",y);
50 The IPCP algorithm will find that g's formal argument y
51 is always called with the value 3.
53 The algorithm used is based on "Interprocedural Constant Propagation",
54 by Challahan David, Keith D Cooper, Ken Kennedy, Linda Torczon, Comp86,
55 pg 152-161
57 The optimization is divided into three stages:
59 First stage - intraprocedural analysis
60 =======================================
61 This phase computes jump_function and modify information.
63 A jump function for a callsite represents the values passed as actual
64 arguments
65 of the callsite. There are three types of values :
66 Formal - the caller's formal parameter is passed as an actual argument.
67 Constant - a constant is passed as an actual argument.
68 Unknown - neither of the above.
70 In order to compute the jump functions, we need the modify information for
71 the formal parameters of methods.
73 The jump function info, ipa_jump_func, is defined in ipa_edge
74 structure (defined in ipa_prop.h and pointed to by cgraph_node->aux)
75 The modify info, ipa_modify, is defined in ipa_node structure
76 (defined in ipa_prop.h and pointed to by cgraph_edge->aux).
78 -ipcp_init_stage() is the first stage driver.
80 Second stage - interprocedural analysis
81 ========================================
82 This phase does the interprocedural constant propagation.
83 It computes for all formal parameters in the program
84 their cval value that may be:
85 TOP - unknown.
86 BOTTOM - non constant.
87 CONSTANT_TYPE - constant value.
89 Cval of formal f will have a constant value if all callsites to this
90 function have the same constant value passed to f.
92 The cval info, ipcp_formal, is defined in ipa_node structure
93 (defined in ipa_prop.h and pointed to by cgraph_edge->aux).
95 -ipcp_iterate_stage() is the second stage driver.
97 Third phase - transformation of methods code
98 ============================================
99 Propagates the constant-valued formals into the function.
100 For each method mt, whose parameters are consts, we create a clone/version.
102 We use two ways to annotate the versioned function with the constant
103 formal information:
104 1. We insert an assignment statement 'parameter = const' at the beginning
105 of the cloned method.
106 2. For read-only formals whose address is not taken, we replace all uses
107 of the formal with the constant (we provide versioning with an
108 ipa_replace_map struct representing the trees we want to replace).
110 We also need to modify some callsites to call to the cloned methods instead
111 of the original ones. For a callsite passing an argument found to be a
112 constant by IPCP, there are two different cases to handle:
113 1. A constant is passed as an argument.
114 2. A parameter (of the caller) passed as an argument (pass through argument).
116 In the first case, the callsite in the original caller should be redirected
117 to call the cloned callee.
118 In the second case, both the caller and the callee have clones
119 and the callsite of the cloned caller would be redirected to call to
120 the cloned callee.
122 The callgraph is updated accordingly.
124 This update is done in two stages:
125 First all cloned methods are created during a traversal of the callgraph,
126 during which all callsites are redirected to call the cloned method.
127 Then the callsites are traversed and updated as described above.
129 -ipcp_insert_stage() is the third phase driver.
133 #include "config.h"
134 #include "system.h"
135 #include "coretypes.h"
136 #include "tree.h"
137 #include "target.h"
138 #include "cgraph.h"
139 #include "ipa-prop.h"
140 #include "tree-flow.h"
141 #include "tree-pass.h"
142 #include "flags.h"
143 #include "timevar.h"
144 #include "diagnostic.h"
145 #include "tree-dump.h"
146 #include "tree-inline.h"
148 /* Get orig node field of ipa_node associated with method MT. */
149 static inline struct cgraph_node *
150 ipcp_method_orig_node (struct cgraph_node *mt)
152 return IPA_NODE_REF (mt)->ipcp_orig_node;
155 /* Return true if NODE is a cloned/versioned method. */
156 static inline bool
157 ipcp_method_is_cloned (struct cgraph_node *node)
159 return (ipcp_method_orig_node (node) != NULL);
162 /* Set ORIG_NODE in ipa_node associated with method NODE. */
163 static inline void
164 ipcp_method_set_orig_node (struct cgraph_node *node,
165 struct cgraph_node *orig_node)
167 IPA_NODE_REF (node)->ipcp_orig_node = orig_node;
170 /* Create ipa_node and its data structures for NEW_NODE.
171 Set ORIG_NODE as the orig_node field in ipa_node. */
172 static void
173 ipcp_cloned_create (struct cgraph_node *orig_node,
174 struct cgraph_node *new_node)
176 ipa_node_create (new_node);
177 ipcp_method_set_orig_node (new_node, orig_node);
178 ipa_method_formal_compute_count (new_node);
179 ipa_method_compute_tree_map (new_node);
182 /* Return cval_type field of CVAL. */
183 static inline enum cvalue_type
184 ipcp_cval_get_cvalue_type (struct ipcp_formal *cval)
186 return cval->cval_type;
189 /* Return scale for MT. */
190 static inline gcov_type
191 ipcp_method_get_scale (struct cgraph_node *mt)
193 return IPA_NODE_REF (mt)->count_scale;
196 /* Set COUNT as scale for MT. */
197 static inline void
198 ipcp_method_set_scale (struct cgraph_node *node, gcov_type count)
200 IPA_NODE_REF (node)->count_scale = count;
203 /* Set TYPE as cval_type field of CVAL. */
204 static inline void
205 ipcp_cval_set_cvalue_type (struct ipcp_formal *cval, enum cvalue_type type)
207 cval->cval_type = type;
210 /* Return cvalue field of CVAL. */
211 static inline union parameter_info *
212 ipcp_cval_get_cvalue (struct ipcp_formal *cval)
214 return &(cval->cvalue);
217 /* Set VALUE as cvalue field CVAL. */
218 static inline void
219 ipcp_cval_set_cvalue (struct ipcp_formal *cval, union parameter_info *value,
220 enum cvalue_type type)
222 if (type == CONST_VALUE || type == CONST_VALUE_REF)
223 cval->cvalue.value = value->value;
226 /* Return whether TYPE is a constant type. */
227 static bool
228 ipcp_type_is_const (enum cvalue_type type)
230 if (type == CONST_VALUE || type == CONST_VALUE_REF)
231 return true;
232 else
233 return false;
236 /* Return true if CONST_VAL1 and CONST_VAL2 are equal. */
237 static inline bool
238 ipcp_cval_equal_cvalues (union parameter_info *const_val1,
239 union parameter_info *const_val2,
240 enum cvalue_type type1, enum cvalue_type type2)
242 gcc_assert (ipcp_type_is_const (type1) && ipcp_type_is_const (type2));
243 if (type1 != type2)
244 return false;
246 if (operand_equal_p (const_val1->value, const_val2->value, 0))
247 return true;
249 return false;
252 /* Compute Meet arithmetics:
253 Meet (BOTTOM, x) = BOTTOM
254 Meet (TOP,x) = x
255 Meet (const_a,const_b) = BOTTOM, if const_a != const_b.
256 MEET (const_a,const_b) = const_a, if const_a == const_b.*/
257 static void
258 ipcp_cval_meet (struct ipcp_formal *cval, struct ipcp_formal *cval1,
259 struct ipcp_formal *cval2)
261 if (ipcp_cval_get_cvalue_type (cval1) == BOTTOM
262 || ipcp_cval_get_cvalue_type (cval2) == BOTTOM)
264 ipcp_cval_set_cvalue_type (cval, BOTTOM);
265 return;
267 if (ipcp_cval_get_cvalue_type (cval1) == TOP)
269 ipcp_cval_set_cvalue_type (cval, ipcp_cval_get_cvalue_type (cval2));
270 ipcp_cval_set_cvalue (cval, ipcp_cval_get_cvalue (cval2),
271 ipcp_cval_get_cvalue_type (cval2));
272 return;
274 if (ipcp_cval_get_cvalue_type (cval2) == TOP)
276 ipcp_cval_set_cvalue_type (cval, ipcp_cval_get_cvalue_type (cval1));
277 ipcp_cval_set_cvalue (cval, ipcp_cval_get_cvalue (cval1),
278 ipcp_cval_get_cvalue_type (cval1));
279 return;
281 if (!ipcp_cval_equal_cvalues (ipcp_cval_get_cvalue (cval1),
282 ipcp_cval_get_cvalue (cval2),
283 ipcp_cval_get_cvalue_type (cval1),
284 ipcp_cval_get_cvalue_type (cval2)))
286 ipcp_cval_set_cvalue_type (cval, BOTTOM);
287 return;
289 ipcp_cval_set_cvalue_type (cval, ipcp_cval_get_cvalue_type (cval1));
290 ipcp_cval_set_cvalue (cval, ipcp_cval_get_cvalue (cval1),
291 ipcp_cval_get_cvalue_type (cval1));
294 /* Return cval structure for the formal at index INFO_TYPE in MT. */
295 static inline struct ipcp_formal *
296 ipcp_method_cval (struct cgraph_node *mt, int info_type)
298 return &(IPA_NODE_REF (mt)->ipcp_cval[info_type]);
301 /* Given the jump function (TYPE, INFO_TYPE), compute a new value of CVAL.
302 If TYPE is FORMAL_IPA_TYPE, the cval of the corresponding formal is
303 drawn from MT. */
304 static void
305 ipcp_cval_compute (struct ipcp_formal *cval, struct cgraph_node *mt,
306 enum jump_func_type type, union parameter_info *info_type)
308 if (type == UNKNOWN_IPATYPE)
309 ipcp_cval_set_cvalue_type (cval, BOTTOM);
310 else if (type == CONST_IPATYPE)
312 ipcp_cval_set_cvalue_type (cval, CONST_VALUE);
313 ipcp_cval_set_cvalue (cval, info_type, CONST_VALUE);
315 else if (type == CONST_IPATYPE_REF)
317 ipcp_cval_set_cvalue_type (cval, CONST_VALUE_REF);
318 ipcp_cval_set_cvalue (cval, info_type, CONST_VALUE_REF);
320 else if (type == FORMAL_IPATYPE)
322 enum cvalue_type type =
323 ipcp_cval_get_cvalue_type (ipcp_method_cval
324 (mt, info_type->formal_id));
325 ipcp_cval_set_cvalue_type (cval, type);
326 ipcp_cval_set_cvalue (cval,
327 ipcp_cval_get_cvalue (ipcp_method_cval
328 (mt, info_type->formal_id)),
329 type);
333 /* True when CVAL1 and CVAL2 values are not the same. */
334 static bool
335 ipcp_cval_changed (struct ipcp_formal *cval1, struct ipcp_formal *cval2)
337 if (ipcp_cval_get_cvalue_type (cval1) == ipcp_cval_get_cvalue_type (cval2))
339 if (ipcp_cval_get_cvalue_type (cval1) != CONST_VALUE &&
340 ipcp_cval_get_cvalue_type (cval1) != CONST_VALUE_REF)
341 return false;
342 if (ipcp_cval_equal_cvalues (ipcp_cval_get_cvalue (cval1),
343 ipcp_cval_get_cvalue (cval2),
344 ipcp_cval_get_cvalue_type (cval1),
345 ipcp_cval_get_cvalue_type (cval2)))
346 return false;
348 return true;
351 /* Create cval structure for method MT. */
352 static inline void
353 ipcp_formal_create (struct cgraph_node *mt)
355 IPA_NODE_REF (mt)->ipcp_cval =
356 XCNEWVEC (struct ipcp_formal, ipa_method_formal_count (mt));
359 /* Set cval structure of I-th formal of MT to CVAL. */
360 static inline void
361 ipcp_method_cval_set (struct cgraph_node *mt, int i, struct ipcp_formal *cval)
363 IPA_NODE_REF (mt)->ipcp_cval[i].cval_type = cval->cval_type;
364 ipcp_cval_set_cvalue (ipcp_method_cval (mt, i),
365 ipcp_cval_get_cvalue (cval), cval->cval_type);
368 /* Set type of cval structure of formal I of MT to CVAL_TYPE1. */
369 static inline void
370 ipcp_method_cval_set_cvalue_type (struct cgraph_node *mt, int i,
371 enum cvalue_type cval_type1)
373 IPA_NODE_REF (mt)->ipcp_cval[i].cval_type = cval_type1;
376 /* Print ipcp_cval data structures to F. */
377 static void
378 ipcp_method_cval_print (FILE * f)
380 struct cgraph_node *node;
381 int i, count;
382 tree cvalue;
384 fprintf (f, "\nCVAL PRINT\n");
385 for (node = cgraph_nodes; node; node = node->next)
387 fprintf (f, "Printing cvals %s:\n", cgraph_node_name (node));
388 count = ipa_method_formal_count (node);
389 for (i = 0; i < count; i++)
391 if (ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i))
392 == CONST_VALUE
393 || ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i)) ==
394 CONST_VALUE_REF)
396 fprintf (f, " param [%d]: ", i);
397 fprintf (f, "type is CONST ");
398 cvalue =
399 ipcp_cval_get_cvalue (ipcp_method_cval (node, i))->value;
400 print_generic_expr (f, cvalue, 0);
401 fprintf (f, "\n");
403 else if (ipcp_method_cval (node, i)->cval_type == TOP)
404 fprintf (f, "param [%d]: type is TOP \n", i);
405 else
406 fprintf (f, "param [%d]: type is BOTTOM \n", i);
411 /* Initialize ipcp_cval array of MT with TOP values.
412 All cvals for a method's formal parameters are initialized to BOTTOM
413 The currently supported types are integer types, real types and
414 Fortran constants (i.e. references to constants defined as
415 const_decls). All other types are not analyzed and therefore are
416 assigned with BOTTOM. */
417 static void
418 ipcp_method_cval_init (struct cgraph_node *mt)
420 int i;
421 tree parm_tree;
423 ipcp_formal_create (mt);
424 for (i = 0; i < ipa_method_formal_count (mt); i++)
426 parm_tree = ipa_method_get_tree (mt, i);
427 if (INTEGRAL_TYPE_P (TREE_TYPE (parm_tree))
428 || SCALAR_FLOAT_TYPE_P (TREE_TYPE (parm_tree))
429 || POINTER_TYPE_P (TREE_TYPE (parm_tree)))
430 ipcp_method_cval_set_cvalue_type (mt, i, TOP);
431 else
432 ipcp_method_cval_set_cvalue_type (mt, i, BOTTOM);
436 /* Create a new assignment statment and make
437 it the first statement in the function FN
438 tree.
439 PARM1 is the lhs of the assignment and
440 VAL is the rhs. */
441 static void
442 constant_val_insert (tree parm1, tree val)
444 tree init_stmt = NULL;
445 edge e_step;
447 init_stmt = build_gimple_modify_stmt (parm1, val);
449 if (init_stmt)
451 e_step = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun));
452 bsi_insert_on_edge_immediate (e_step, init_stmt);
456 /* build INTEGER_CST tree with type TREE_TYPE and
457 value according to CVALUE. Return the tree. */
458 static tree
459 build_const_val (union parameter_info *cvalue, enum cvalue_type type,
460 tree tree_type)
462 tree const_val = NULL;
464 gcc_assert (ipcp_type_is_const (type));
465 const_val = fold_convert (tree_type, cvalue->value);
466 return const_val;
469 /* Build the tree representing the constant and call
470 constant_val_insert(). */
471 static void
472 ipcp_propagate_const (struct cgraph_node *mt, int param,
473 union parameter_info *cvalue, enum cvalue_type type)
475 tree const_val;
476 tree parm_tree;
478 if (dump_file)
479 fprintf (dump_file, "propagating const to %s\n", cgraph_node_name (mt));
480 parm_tree = ipa_method_get_tree (mt, param);
481 const_val = build_const_val (cvalue, type, TREE_TYPE (parm_tree));
482 constant_val_insert (parm_tree, const_val);
485 /* Compute the proper scale for NODE. It is the ratio between
486 the number of direct calls (represented on the incoming
487 cgraph_edges) and sum of all invocations of NODE (represented
488 as count in cgraph_node). */
489 static void
490 ipcp_method_compute_scale (struct cgraph_node *node)
492 gcov_type sum;
493 struct cgraph_edge *cs;
495 sum = 0;
496 /* Compute sum of all counts of callers. */
497 for (cs = node->callers; cs != NULL; cs = cs->next_caller)
498 sum += cs->count;
499 if (node->count == 0)
500 ipcp_method_set_scale (node, 0);
501 else
502 ipcp_method_set_scale (node, sum * REG_BR_PROB_BASE / node->count);
505 /* Initialization and computation of IPCP data structures.
506 It is an intraprocedural
507 analysis of methods, which gathers information to be propagated
508 later on. */
509 static void
510 ipcp_init_stage (void)
512 struct cgraph_node *node;
513 struct cgraph_edge *cs;
515 for (node = cgraph_nodes; node; node = node->next)
517 ipa_method_formal_compute_count (node);
518 ipa_method_compute_tree_map (node);
519 ipcp_method_cval_init (node);
520 ipa_method_compute_modify (node);
521 ipcp_method_compute_scale (node);
523 for (node = cgraph_nodes; node; node = node->next)
525 /* building jump functions */
526 for (cs = node->callees; cs; cs = cs->next_callee)
528 ipa_callsite_compute_count (cs);
529 if (ipa_callsite_param_count (cs)
530 != ipa_method_formal_count (cs->callee))
532 /* Handle cases of functions with
533 a variable number of parameters. */
534 ipa_callsite_param_count_set (cs, 0);
535 ipa_method_formal_count_set (cs->callee, 0);
537 else
538 ipa_callsite_compute_param (cs);
543 /* Return true if there are some formal parameters whose value is TOP.
544 Change their values to BOTTOM, since they weren't determined. */
545 static bool
546 ipcp_after_propagate (void)
548 int i, count;
549 struct cgraph_node *node;
550 bool prop_again;
552 prop_again = false;
553 for (node = cgraph_nodes; node; node = node->next)
555 count = ipa_method_formal_count (node);
556 for (i = 0; i < count; i++)
557 if (ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i)) == TOP)
559 prop_again = true;
560 ipcp_method_cval_set_cvalue_type (node, i, BOTTOM);
563 return prop_again;
566 /* Interprocedural analysis. The algorithm propagates constants from
567 the caller's parameters to the callee's arguments. */
568 static void
569 ipcp_propagate_stage (void)
571 int i;
572 struct ipcp_formal cval1 = { BOTTOM, {0} }, cval = { BOTTOM, {0} };
573 struct ipcp_formal *cval2;
574 struct cgraph_node *mt, *callee;
575 struct cgraph_edge *cs;
576 struct ipa_jump_func *jump_func;
577 enum jump_func_type type;
578 union parameter_info *info_type;
579 ipa_methodlist_p wl;
580 int count;
582 /* Initialize worklist to contain all methods. */
583 wl = ipa_methodlist_init ();
584 while (ipa_methodlist_not_empty (wl))
586 mt = ipa_remove_method (&wl);
587 for (cs = mt->callees; cs; cs = cs->next_callee)
589 callee = ipa_callsite_callee (cs);
590 count = ipa_callsite_param_count (cs);
591 for (i = 0; i < count; i++)
593 jump_func = ipa_callsite_param (cs, i);
594 type = get_type (jump_func);
595 info_type = ipa_jf_get_info_type (jump_func);
596 ipcp_cval_compute (&cval1, mt, type, info_type);
597 cval2 = ipcp_method_cval (callee, i);
598 ipcp_cval_meet (&cval, &cval1, cval2);
599 if (ipcp_cval_changed (&cval, cval2))
601 ipcp_method_cval_set (callee, i, &cval);
602 ipa_add_method (&wl, callee);
609 /* Call the constant propagation algorithm and re-call it if necessary
610 (if there are undetermined values left). */
611 static void
612 ipcp_iterate_stage (void)
614 ipcp_propagate_stage ();
615 if (ipcp_after_propagate ())
616 /* Some cvals have changed from TOP to BOTTOM.
617 This change should be propagated. */
618 ipcp_propagate_stage ();
621 /* Check conditions to forbid constant insertion to MT. */
622 static bool
623 ipcp_method_dont_insert_const (struct cgraph_node *mt)
625 /* ??? Handle pending sizes case. */
626 if (DECL_UNINLINABLE (mt->decl))
627 return true;
628 return false;
631 /* Print ipa_jump_func data structures to F. */
632 static void
633 ipcp_callsite_param_print (FILE * f)
635 struct cgraph_node *node;
636 int i, count;
637 struct cgraph_edge *cs;
638 struct ipa_jump_func *jump_func;
639 enum jump_func_type type;
640 tree info_type;
642 fprintf (f, "\nCALLSITE PARAM PRINT\n");
643 for (node = cgraph_nodes; node; node = node->next)
645 for (cs = node->callees; cs; cs = cs->next_callee)
647 fprintf (f, "callsite %s ", cgraph_node_name (node));
648 fprintf (f, "-> %s :: \n", cgraph_node_name (cs->callee));
649 count = ipa_callsite_param_count (cs);
650 for (i = 0; i < count; i++)
652 jump_func = ipa_callsite_param (cs, i);
653 type = get_type (jump_func);
655 fprintf (f, " param %d: ", i);
656 if (type == UNKNOWN_IPATYPE)
657 fprintf (f, "UNKNOWN\n");
658 else if (type == CONST_IPATYPE || type == CONST_IPATYPE_REF)
660 info_type = ipa_jf_get_info_type (jump_func)->value;
661 fprintf (f, "CONST : ");
662 print_generic_expr (f, info_type, 0);
663 fprintf (f, "\n");
665 else if (type == FORMAL_IPATYPE)
667 fprintf (f, "FORMAL : ");
668 fprintf (f, "%d\n",
669 ipa_jf_get_info_type (jump_func)->formal_id);
676 /* Print count scale data structures. */
677 static void
678 ipcp_method_scale_print (FILE * f)
680 struct cgraph_node *node;
682 for (node = cgraph_nodes; node; node = node->next)
684 fprintf (f, "printing scale for %s: ", cgraph_node_name (node));
685 fprintf (f, "value is " HOST_WIDE_INT_PRINT_DEC
686 " \n", (HOST_WIDE_INT) ipcp_method_get_scale (node));
690 /* Print counts of all cgraph nodes. */
691 static void
692 ipcp_profile_mt_count_print (FILE * f)
694 struct cgraph_node *node;
696 for (node = cgraph_nodes; node; node = node->next)
698 fprintf (f, "method %s: ", cgraph_node_name (node));
699 fprintf (f, "count is " HOST_WIDE_INT_PRINT_DEC
700 " \n", (HOST_WIDE_INT) node->count);
704 /* Print counts of all cgraph edges. */
705 static void
706 ipcp_profile_cs_count_print (FILE * f)
708 struct cgraph_node *node;
709 struct cgraph_edge *cs;
711 for (node = cgraph_nodes; node; node = node->next)
713 for (cs = node->callees; cs; cs = cs->next_callee)
715 fprintf (f, "%s -> %s ", cgraph_node_name (cs->caller),
716 cgraph_node_name (cs->callee));
717 fprintf (f, "count is " HOST_WIDE_INT_PRINT_DEC " \n",
718 (HOST_WIDE_INT) cs->count);
723 /* Print all counts and probabilities of cfg edges of all methods. */
724 static void
725 ipcp_profile_edge_print (FILE * f)
727 struct cgraph_node *node;
728 basic_block bb;
729 edge_iterator ei;
730 edge e;
732 for (node = cgraph_nodes; node; node = node->next)
734 fprintf (f, "method %s: \n", cgraph_node_name (node));
735 if (DECL_SAVED_TREE (node->decl))
737 bb =
738 ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl));
739 fprintf (f, "ENTRY: ");
740 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
741 " %d\n", (HOST_WIDE_INT) bb->count, bb->frequency);
743 if (bb->succs)
744 FOR_EACH_EDGE (e, ei, bb->succs)
746 if (e->dest ==
747 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION
748 (node->decl)))
749 fprintf (f, "edge ENTRY -> EXIT, Count");
750 else
751 fprintf (f, "edge ENTRY -> %d, Count", e->dest->index);
752 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
753 " Prob %d\n", (HOST_WIDE_INT) e->count,
754 e->probability);
756 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
758 fprintf (f, "bb[%d]: ", bb->index);
759 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
760 " %d\n", (HOST_WIDE_INT) bb->count, bb->frequency);
761 FOR_EACH_EDGE (e, ei, bb->succs)
763 if (e->dest ==
764 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION
765 (node->decl)))
766 fprintf (f, "edge %d -> EXIT, Count", e->src->index);
767 else
768 fprintf (f, "edge %d -> %d, Count", e->src->index,
769 e->dest->index);
770 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC " Prob %d\n",
771 (HOST_WIDE_INT) e->count, e->probability);
778 /* Print counts and frequencies for all basic blocks of all methods. */
779 static void
780 ipcp_profile_bb_print (FILE * f)
782 basic_block bb;
783 struct cgraph_node *node;
785 for (node = cgraph_nodes; node; node = node->next)
787 fprintf (f, "method %s: \n", cgraph_node_name (node));
788 if (node->analyzed)
790 bb =
791 ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl));
792 fprintf (f, "ENTRY: Count");
793 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
794 " Frequency %d\n", (HOST_WIDE_INT) bb->count,
795 bb->frequency);
797 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
799 fprintf (f, "bb[%d]: Count", bb->index);
800 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
801 " Frequency %d\n", (HOST_WIDE_INT) bb->count,
802 bb->frequency);
804 bb =
805 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl));
806 fprintf (f, "EXIT: Count");
807 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
808 " Frequency %d\n", (HOST_WIDE_INT) bb->count,
809 bb->frequency);
815 /* Print all IPCP data structures to F. */
816 static void
817 ipcp_structures_print (FILE * f)
819 ipcp_method_cval_print (f);
820 ipcp_method_scale_print (f);
821 ipa_method_tree_print (f);
822 ipa_method_modify_print (f);
823 ipcp_callsite_param_print (f);
826 /* Print profile info for all methods. */
827 static void
828 ipcp_profile_print (FILE * f)
830 fprintf (f, "\nNODE COUNTS :\n");
831 ipcp_profile_mt_count_print (f);
832 fprintf (f, "\nCS COUNTS stage:\n");
833 ipcp_profile_cs_count_print (f);
834 fprintf (f, "\nBB COUNTS and FREQUENCIES :\n");
835 ipcp_profile_bb_print (f);
836 fprintf (f, "\nCFG EDGES COUNTS and PROBABILITIES :\n");
837 ipcp_profile_edge_print (f);
840 /* Build and initialize ipa_replace_map struct
841 according to TYPE. This struct is read by versioning, which
842 operates according to the flags sent. PARM_TREE is the
843 formal's tree found to be constant. CVALUE represents the constant. */
844 static struct ipa_replace_map *
845 ipcp_replace_map_create (struct function *func, enum cvalue_type type,
846 tree parm_tree, union parameter_info *cvalue)
848 struct ipa_replace_map *replace_map;
849 tree const_val;
851 replace_map = XCNEW (struct ipa_replace_map);
852 gcc_assert (ipcp_type_is_const (type));
853 if (type != CONST_VALUE_REF
854 && is_gimple_reg (parm_tree) && gimple_default_def (func, parm_tree)
855 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_default_def (func, parm_tree)))
857 if (dump_file)
858 fprintf (dump_file, "replacing param with const\n");
859 const_val = build_const_val (cvalue, type, TREE_TYPE (parm_tree));
860 replace_map->old_tree =gimple_default_def (func, parm_tree);
861 replace_map->new_tree = const_val;
862 replace_map->replace_p = true;
863 replace_map->ref_p = false;
865 else
867 replace_map->old_tree = NULL;
868 replace_map->new_tree = NULL;
869 replace_map->replace_p = false;
870 replace_map->ref_p = false;
873 return replace_map;
876 /* Return true if this callsite should be redirected to
877 the orig callee (instead of the cloned one). */
878 static bool
879 ipcp_redirect (struct cgraph_edge *cs)
881 struct cgraph_node *caller, *callee, *orig_callee;
882 int i, count;
883 struct ipa_jump_func *jump_func;
884 enum jump_func_type type;
885 enum cvalue_type cval_type;
887 caller = cs->caller;
888 callee = cs->callee;
889 orig_callee = ipcp_method_orig_node (callee);
890 count = ipa_method_formal_count (orig_callee);
891 for (i = 0; i < count; i++)
893 cval_type =
894 ipcp_cval_get_cvalue_type (ipcp_method_cval (orig_callee, i));
895 if (ipcp_type_is_const (cval_type))
897 jump_func = ipa_callsite_param (cs, i);
898 type = get_type (jump_func);
899 if (type != CONST_IPATYPE && type != CONST_IPATYPE_REF)
900 return true;
904 return false;
907 /* Fix the callsites and the callgraph after function cloning was done. */
908 static void
909 ipcp_update_callgraph (void)
911 struct cgraph_node *node, *orig_callee;
912 struct cgraph_edge *cs;
914 for (node = cgraph_nodes; node; node = node->next)
916 /* want to fix only original nodes */
917 if (ipcp_method_is_cloned (node))
918 continue;
919 for (cs = node->callees; cs; cs = cs->next_callee)
920 if (ipcp_method_is_cloned (cs->callee))
922 /* Callee is a cloned node */
923 orig_callee = ipcp_method_orig_node (cs->callee);
924 if (ipcp_redirect (cs))
926 cgraph_redirect_edge_callee (cs, orig_callee);
927 TREE_OPERAND (CALL_EXPR_FN (get_call_expr_in (cs->call_stmt)),
928 0) =
929 orig_callee->decl;
935 /* Update all cfg basic blocks in NODE according to SCALE. */
936 static void
937 ipcp_update_bb_counts (struct cgraph_node *node, gcov_type scale)
939 basic_block bb;
941 FOR_ALL_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
942 bb->count = bb->count * scale / REG_BR_PROB_BASE;
945 /* Update all cfg edges in NODE according to SCALE. */
946 static void
947 ipcp_update_edges_counts (struct cgraph_node *node, gcov_type scale)
949 basic_block bb;
950 edge_iterator ei;
951 edge e;
953 FOR_ALL_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
954 FOR_EACH_EDGE (e, ei, bb->succs)
955 e->count = e->count * scale / REG_BR_PROB_BASE;
958 /* Update profiling info for versioned methods and the
959 methods they were versioned from. */
960 static void
961 ipcp_update_profiling (void)
963 struct cgraph_node *node, *orig_node;
964 gcov_type scale, scale_complement;
965 struct cgraph_edge *cs;
967 for (node = cgraph_nodes; node; node = node->next)
969 if (ipcp_method_is_cloned (node))
971 orig_node = ipcp_method_orig_node (node);
972 scale = ipcp_method_get_scale (orig_node);
973 node->count = orig_node->count * scale / REG_BR_PROB_BASE;
974 scale_complement = REG_BR_PROB_BASE - scale;
975 orig_node->count =
976 orig_node->count * scale_complement / REG_BR_PROB_BASE;
977 for (cs = node->callees; cs; cs = cs->next_callee)
978 cs->count = cs->count * scale / REG_BR_PROB_BASE;
979 for (cs = orig_node->callees; cs; cs = cs->next_callee)
980 cs->count = cs->count * scale_complement / REG_BR_PROB_BASE;
981 ipcp_update_bb_counts (node, scale);
982 ipcp_update_bb_counts (orig_node, scale_complement);
983 ipcp_update_edges_counts (node, scale);
984 ipcp_update_edges_counts (orig_node, scale_complement);
989 /* Propagate the constant parameters found by ipcp_iterate_stage()
990 to the function's code. */
991 static void
992 ipcp_insert_stage (void)
994 struct cgraph_node *node, *node1 = NULL;
995 int i, const_param;
996 union parameter_info *cvalue;
997 VEC (cgraph_edge_p, heap) * redirect_callers;
998 varray_type replace_trees;
999 struct cgraph_edge *cs;
1000 int node_callers, count;
1001 tree parm_tree;
1002 enum cvalue_type type;
1003 struct ipa_replace_map *replace_param;
1005 for (node = cgraph_nodes; node; node = node->next)
1007 /* Propagation of the constant is forbidden in
1008 certain conditions. */
1009 if (!node->analyzed || ipcp_method_dont_insert_const (node))
1010 continue;
1011 const_param = 0;
1012 count = ipa_method_formal_count (node);
1013 for (i = 0; i < count; i++)
1015 type = ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i));
1016 if (ipcp_type_is_const (type))
1017 const_param++;
1019 if (const_param == 0)
1020 continue;
1021 VARRAY_GENERIC_PTR_INIT (replace_trees, const_param, "replace_trees");
1022 for (i = 0; i < count; i++)
1024 type = ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i));
1025 if (ipcp_type_is_const (type))
1027 cvalue = ipcp_cval_get_cvalue (ipcp_method_cval (node, i));
1028 parm_tree = ipa_method_get_tree (node, i);
1029 replace_param =
1030 ipcp_replace_map_create (DECL_STRUCT_FUNCTION (node->decl),
1031 type, parm_tree, cvalue);
1032 VARRAY_PUSH_GENERIC_PTR (replace_trees, replace_param);
1035 /* Compute how many callers node has. */
1036 node_callers = 0;
1037 for (cs = node->callers; cs != NULL; cs = cs->next_caller)
1038 node_callers++;
1039 redirect_callers = VEC_alloc (cgraph_edge_p, heap, node_callers);
1040 for (cs = node->callers; cs != NULL; cs = cs->next_caller)
1041 VEC_quick_push (cgraph_edge_p, redirect_callers, cs);
1042 /* Redirecting all the callers of the node to the
1043 new versioned node. */
1044 node1 =
1045 cgraph_function_versioning (node, redirect_callers, replace_trees);
1046 VEC_free (cgraph_edge_p, heap, redirect_callers);
1047 VARRAY_CLEAR (replace_trees);
1048 if (node1 == NULL)
1049 continue;
1050 if (dump_file)
1051 fprintf (dump_file, "versioned function %s\n",
1052 cgraph_node_name (node));
1053 ipcp_cloned_create (node, node1);
1054 if (const_param > 0)
1056 push_cfun (DECL_STRUCT_FUNCTION (node1->decl));
1057 tree_register_cfg_hooks ();
1058 current_function_decl = node1->decl;
1060 for (i = 0; i < count; i++)
1062 type = ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i));
1063 if (ipcp_type_is_const (type))
1065 cvalue = ipcp_cval_get_cvalue (ipcp_method_cval (node, i));
1066 parm_tree = ipa_method_get_tree (node, i);
1067 if (type != CONST_VALUE_REF && !is_gimple_reg (parm_tree))
1068 ipcp_propagate_const (node1, i, cvalue, type);
1071 if (gimple_in_ssa_p (cfun))
1073 update_ssa (TODO_update_ssa);
1074 #ifdef ENABLE_CHECKING
1075 verify_ssa (true);
1076 #endif
1078 free_dominance_info (CDI_DOMINATORS);
1079 free_dominance_info (CDI_POST_DOMINATORS);
1080 pop_cfun ();
1081 current_function_decl = NULL;
1083 if (dump_file)
1084 dump_function_to_file (node1->decl, dump_file, dump_flags);
1086 ipcp_update_callgraph ();
1087 ipcp_update_profiling ();
1090 /* The IPCP driver. */
1091 static unsigned int
1092 ipcp_driver (void)
1094 if (dump_file)
1095 fprintf (dump_file, "\nIPA constant propagation start:\n");
1096 ipa_nodes_create ();
1097 ipa_edges_create ();
1098 /* 1. Call the init stage to initialize
1099 the ipa_node and ipa_edge structures. */
1100 ipcp_init_stage ();
1101 if (dump_file)
1103 fprintf (dump_file, "\nIPA structures before propagation:\n");
1104 ipcp_structures_print (dump_file);
1106 /* 2. Do the interprocedural propagation. */
1107 ipcp_iterate_stage ();
1108 if (dump_file)
1110 fprintf (dump_file, "\nIPA structures after propagation:\n");
1111 ipcp_structures_print (dump_file);
1112 fprintf (dump_file, "\nProfiling info before insert stage:\n");
1113 ipcp_profile_print (dump_file);
1115 /* 3. Insert the constants found to the functions. */
1116 ipcp_insert_stage ();
1117 if (dump_file)
1119 fprintf (dump_file, "\nProfiling info after insert stage:\n");
1120 ipcp_profile_print (dump_file);
1122 /* Free all IPCP structures. */
1123 ipa_free ();
1124 ipa_nodes_free ();
1125 ipa_edges_free ();
1126 if (dump_file)
1127 fprintf (dump_file, "\nIPA constant propagation end\n");
1128 cgraph_remove_unreachable_nodes (true, NULL);
1129 return 0;
1132 /* Gate for IPCP optimization. */
1133 static bool
1134 cgraph_gate_cp (void)
1136 return flag_ipa_cp;
1139 struct tree_opt_pass pass_ipa_cp = {
1140 "cp", /* name */
1141 cgraph_gate_cp, /* gate */
1142 ipcp_driver, /* execute */
1143 NULL, /* sub */
1144 NULL, /* next */
1145 0, /* static_pass_number */
1146 TV_IPA_CONSTANT_PROP, /* tv_id */
1147 0, /* properties_required */
1148 PROP_trees, /* properties_provided */
1149 0, /* properties_destroyed */
1150 0, /* todo_flags_start */
1151 TODO_dump_cgraph | TODO_dump_func, /* todo_flags_finish */
1152 0 /* letter */