configure.ac: Set insn to "nop" for spu-*-* also.
[official-gcc.git] / gcc / ipa-cp.c
blob0451667917c000cd8409c781d19c241f6455cedb
1 /* Interprocedural constant propagation
2 Copyright (C) 2005 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 a 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"
147 /* Get orig node field of ipa_node associated with method MT. */
148 static inline struct cgraph_node *
149 ipcp_method_orig_node (struct cgraph_node *mt)
151 return IPA_NODE_REF (mt)->ipcp_orig_node;
154 /* Return true if NODE is a cloned/versioned method. */
155 static inline bool
156 ipcp_method_is_cloned (struct cgraph_node *node)
158 return (ipcp_method_orig_node (node) != NULL);
161 /* Set ORIG_NODE in ipa_node associated with method NODE. */
162 static inline void
163 ipcp_method_set_orig_node (struct cgraph_node *node,
164 struct cgraph_node *orig_node)
166 IPA_NODE_REF (node)->ipcp_orig_node = orig_node;
169 /* Create ipa_node and its data structures for NEW_NODE.
170 Set ORIG_NODE as the orig_node field in ipa_node. */
171 static void
172 ipcp_cloned_create (struct cgraph_node *orig_node,
173 struct cgraph_node *new_node)
175 ipa_node_create (new_node);
176 ipcp_method_set_orig_node (new_node, orig_node);
177 ipa_method_formal_compute_count (new_node);
178 ipa_method_compute_tree_map (new_node);
181 /* Return cval_type field of CVAL. */
182 static inline enum cvalue_type
183 ipcp_cval_get_cvalue_type (struct ipcp_formal *cval)
185 return cval->cval_type;
188 /* Return scale for MT. */
189 static inline gcov_type
190 ipcp_method_get_scale (struct cgraph_node *mt)
192 return IPA_NODE_REF (mt)->count_scale;
195 /* Set COUNT as scale for MT. */
196 static inline void
197 ipcp_method_set_scale (struct cgraph_node *node, gcov_type count)
199 IPA_NODE_REF (node)->count_scale = count;
202 /* Set TYPE as cval_type field of CVAL. */
203 static inline void
204 ipcp_cval_set_cvalue_type (struct ipcp_formal *cval, enum cvalue_type type)
206 cval->cval_type = type;
209 /* Return cvalue field of CVAL. */
210 static inline union parameter_info *
211 ipcp_cval_get_cvalue (struct ipcp_formal *cval)
213 return &(cval->cvalue);
216 /* Set VALUE as cvalue field CVAL. */
217 static inline void
218 ipcp_cval_set_cvalue (struct ipcp_formal *cval, union parameter_info *value,
219 enum cvalue_type type)
221 if (type == CONST_VALUE || type == CONST_VALUE_REF)
222 cval->cvalue.value = value->value;
225 /* Return whether TYPE is a constant type. */
226 static bool
227 ipcp_type_is_const (enum cvalue_type type)
229 if (type == CONST_VALUE || type == CONST_VALUE_REF)
230 return true;
231 else
232 return false;
235 /* Return true if CONST_VAL1 and CONST_VAL2 are equal. */
236 static inline bool
237 ipcp_cval_equal_cvalues (union parameter_info *const_val1,
238 union parameter_info *const_val2,
239 enum cvalue_type type1, enum cvalue_type type2)
241 gcc_assert (ipcp_type_is_const (type1) && ipcp_type_is_const (type2));
242 if (type1 != type2)
243 return false;
245 if (operand_equal_p (const_val1->value, const_val2->value, 0))
246 return true;
248 return false;
251 /* Compute Meet arithmetics:
252 Meet (BOTTOM, x) = BOTTOM
253 Meet (TOP,x) = x
254 Meet (const_a,const_b) = BOTTOM, if const_a != const_b.
255 MEET (const_a,const_b) = const_a, if const_a == const_b.*/
256 static void
257 ipcp_cval_meet (struct ipcp_formal *cval, struct ipcp_formal *cval1,
258 struct ipcp_formal *cval2)
260 if (ipcp_cval_get_cvalue_type (cval1) == BOTTOM
261 || ipcp_cval_get_cvalue_type (cval2) == BOTTOM)
263 ipcp_cval_set_cvalue_type (cval, BOTTOM);
264 return;
266 if (ipcp_cval_get_cvalue_type (cval1) == TOP)
268 ipcp_cval_set_cvalue_type (cval, ipcp_cval_get_cvalue_type (cval2));
269 ipcp_cval_set_cvalue (cval, ipcp_cval_get_cvalue (cval2),
270 ipcp_cval_get_cvalue_type (cval2));
271 return;
273 if (ipcp_cval_get_cvalue_type (cval2) == TOP)
275 ipcp_cval_set_cvalue_type (cval, ipcp_cval_get_cvalue_type (cval1));
276 ipcp_cval_set_cvalue (cval, ipcp_cval_get_cvalue (cval1),
277 ipcp_cval_get_cvalue_type (cval1));
278 return;
280 if (!ipcp_cval_equal_cvalues (ipcp_cval_get_cvalue (cval1),
281 ipcp_cval_get_cvalue (cval2),
282 ipcp_cval_get_cvalue_type (cval1),
283 ipcp_cval_get_cvalue_type (cval2)))
285 ipcp_cval_set_cvalue_type (cval, BOTTOM);
286 return;
288 ipcp_cval_set_cvalue_type (cval, ipcp_cval_get_cvalue_type (cval1));
289 ipcp_cval_set_cvalue (cval, ipcp_cval_get_cvalue (cval1),
290 ipcp_cval_get_cvalue_type (cval1));
293 /* Return cval structure for the formal at index INFO_TYPE in MT. */
294 static inline struct ipcp_formal *
295 ipcp_method_cval (struct cgraph_node *mt, int info_type)
297 return &(IPA_NODE_REF (mt)->ipcp_cval[info_type]);
300 /* Given the jump function (TYPE, INFO_TYPE), compute a new value of CVAL.
301 If TYPE is FORMAL_IPA_TYPE, the cval of the corresponding formal is
302 drawn from MT. */
303 static void
304 ipcp_cval_compute (struct ipcp_formal *cval, struct cgraph_node *mt,
305 enum jump_func_type type, union parameter_info *info_type)
307 if (type == UNKNOWN_IPATYPE)
308 ipcp_cval_set_cvalue_type (cval, BOTTOM);
309 else if (type == CONST_IPATYPE)
311 ipcp_cval_set_cvalue_type (cval, CONST_VALUE);
312 ipcp_cval_set_cvalue (cval, info_type, CONST_VALUE);
314 else if (type == CONST_IPATYPE_REF)
316 ipcp_cval_set_cvalue_type (cval, CONST_VALUE_REF);
317 ipcp_cval_set_cvalue (cval, info_type, CONST_VALUE_REF);
319 else if (type == FORMAL_IPATYPE)
321 enum cvalue_type type =
322 ipcp_cval_get_cvalue_type (ipcp_method_cval
323 (mt, info_type->formal_id));
324 ipcp_cval_set_cvalue_type (cval, type);
325 ipcp_cval_set_cvalue (cval,
326 ipcp_cval_get_cvalue (ipcp_method_cval
327 (mt, info_type->formal_id)),
328 type);
332 /* True when CVAL1 and CVAL2 values are not the same. */
333 static bool
334 ipcp_cval_changed (struct ipcp_formal *cval1, struct ipcp_formal *cval2)
336 if (ipcp_cval_get_cvalue_type (cval1) == ipcp_cval_get_cvalue_type (cval2))
338 if (ipcp_cval_get_cvalue_type (cval1) != CONST_VALUE &&
339 ipcp_cval_get_cvalue_type (cval1) != CONST_VALUE_REF)
340 return false;
341 if (ipcp_cval_equal_cvalues (ipcp_cval_get_cvalue (cval1),
342 ipcp_cval_get_cvalue (cval2),
343 ipcp_cval_get_cvalue_type (cval1),
344 ipcp_cval_get_cvalue_type (cval2)))
345 return false;
347 return true;
350 /* Create cval structure for method MT. */
351 static inline void
352 ipcp_formal_create (struct cgraph_node *mt)
354 IPA_NODE_REF (mt)->ipcp_cval =
355 XCNEWVEC (struct ipcp_formal, ipa_method_formal_count (mt));
358 /* Set cval structure of I-th formal of MT to CVAL. */
359 static inline void
360 ipcp_method_cval_set (struct cgraph_node *mt, int i, struct ipcp_formal *cval)
362 IPA_NODE_REF (mt)->ipcp_cval[i].cval_type = cval->cval_type;
363 ipcp_cval_set_cvalue (ipcp_method_cval (mt, i),
364 ipcp_cval_get_cvalue (cval), cval->cval_type);
367 /* Set type of cval structure of formal I of MT to CVAL_TYPE1. */
368 static inline void
369 ipcp_method_cval_set_cvalue_type (struct cgraph_node *mt, int i,
370 enum cvalue_type cval_type1)
372 IPA_NODE_REF (mt)->ipcp_cval[i].cval_type = cval_type1;
375 /* Print ipcp_cval data structures to F. */
376 static void
377 ipcp_method_cval_print (FILE * f)
379 struct cgraph_node *node;
380 int i, count;
381 tree cvalue;
383 fprintf (f, "\nCVAL PRINT\n");
384 for (node = cgraph_nodes; node; node = node->next)
386 fprintf (f, "Printing cvals %s:\n", cgraph_node_name (node));
387 count = ipa_method_formal_count (node);
388 for (i = 0; i < count; i++)
390 if (ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i))
391 == CONST_VALUE
392 || ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i)) ==
393 CONST_VALUE_REF)
395 fprintf (f, " param [%d]: ", i);
396 fprintf (f, "type is CONST ");
397 cvalue =
398 ipcp_cval_get_cvalue (ipcp_method_cval (node, i))->
399 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 fn, tree parm1, tree val)
444 struct function *func;
445 tree init_stmt;
446 edge e_step;
447 edge_iterator ei;
449 init_stmt = build2 (GIMPLE_MODIFY_STMT, void_type_node, parm1, val);
450 func = DECL_STRUCT_FUNCTION (fn);
451 cfun = func;
452 current_function_decl = fn;
453 if (ENTRY_BLOCK_PTR_FOR_FUNCTION (func)->succs)
454 FOR_EACH_EDGE (e_step, ei, ENTRY_BLOCK_PTR_FOR_FUNCTION (func)->succs)
455 bsi_insert_on_edge_immediate (e_step, init_stmt);
456 current_function_decl = NULL;
457 cfun = NULL;
460 /* build INTEGER_CST tree with type TREE_TYPE and
461 value according to CVALUE. Return the tree. */
462 static tree
463 build_const_val (union parameter_info *cvalue, enum cvalue_type type,
464 tree tree_type)
466 tree const_val = NULL;
468 gcc_assert (ipcp_type_is_const (type));
469 const_val = fold_convert (tree_type, cvalue->value);
470 return const_val;
473 /* Build the tree representing the constant and call
474 constant_val_insert(). */
475 static void
476 ipcp_propagate_const (struct cgraph_node *mt, int param,
477 union parameter_info *cvalue ,enum cvalue_type type)
479 tree fndecl;
480 tree const_val;
481 tree parm_tree;
483 if (dump_file)
484 fprintf (dump_file, "propagating const to %s\n", cgraph_node_name (mt));
485 fndecl = mt->decl;
486 parm_tree = ipa_method_get_tree (mt, param);
487 const_val = build_const_val (cvalue, type, TREE_TYPE (parm_tree));
488 constant_val_insert (fndecl, parm_tree, const_val);
491 /* Compute the proper scale for NODE. It is the ratio between
492 the number of direct calls (represented on the incoming
493 cgraph_edges) and sum of all invocations of NODE (represented
494 as count in cgraph_node). */
495 static void
496 ipcp_method_compute_scale (struct cgraph_node *node)
498 gcov_type sum;
499 struct cgraph_edge *cs;
501 sum = 0;
502 /* Compute sum of all counts of callers. */
503 for (cs = node->callers; cs != NULL; cs = cs->next_caller)
504 sum += cs->count;
505 if (node->count == 0)
506 ipcp_method_set_scale (node, 0);
507 else
508 ipcp_method_set_scale (node, sum * REG_BR_PROB_BASE / node->count);
511 /* Initialization and computation of IPCP data structures.
512 It is an intraprocedural
513 analysis of methods, which gathers information to be propagated
514 later on. */
515 static void
516 ipcp_init_stage (void)
518 struct cgraph_node *node;
519 struct cgraph_edge *cs;
521 for (node = cgraph_nodes; node; node = node->next)
523 ipa_method_formal_compute_count (node);
524 ipa_method_compute_tree_map (node);
525 ipcp_method_cval_init (node);
526 ipa_method_compute_modify (node);
527 ipcp_method_compute_scale (node);
529 for (node = cgraph_nodes; node; node = node->next)
531 /* building jump functions */
532 for (cs = node->callees; cs; cs = cs->next_callee)
534 ipa_callsite_compute_count (cs);
535 if (ipa_callsite_param_count (cs)
536 != ipa_method_formal_count (cs->callee))
538 /* Handle cases of functions with
539 a variable number of parameters. */
540 ipa_callsite_param_count_set (cs, 0);
541 ipa_method_formal_count_set (cs->callee, 0);
543 else
544 ipa_callsite_compute_param (cs);
549 /* Return true if there are some formal parameters whose value is TOP.
550 Change their values to BOTTOM, since they weren't determined. */
551 static bool
552 ipcp_after_propagate (void)
554 int i, count;
555 struct cgraph_node *node;
556 bool prop_again;
558 prop_again = false;
559 for (node = cgraph_nodes; node; node = node->next)
561 count = ipa_method_formal_count (node);
562 for (i = 0; i < count; i++)
563 if (ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i)) == TOP)
565 prop_again = true;
566 ipcp_method_cval_set_cvalue_type (node, i, BOTTOM);
569 return prop_again;
572 /* Interprocedural analysis. The algorithm propagates constants from
573 the caller's parameters to the callee's arguments. */
574 static void
575 ipcp_propagate_stage (void)
577 int i;
578 struct ipcp_formal cval1 = { 0, {0} }, cval = { 0,{0} };
579 struct ipcp_formal *cval2;
580 struct cgraph_node *mt, *callee;
581 struct cgraph_edge *cs;
582 struct ipa_jump_func *jump_func;
583 enum jump_func_type type;
584 union parameter_info *info_type;
585 ipa_methodlist_p wl;
586 int count;
588 /* Initialize worklist to contain all methods. */
589 wl = ipa_methodlist_init ();
590 while (ipa_methodlist_not_empty (wl))
592 mt = ipa_remove_method (&wl);
593 for (cs = mt->callees; cs; cs = cs->next_callee)
595 callee = ipa_callsite_callee (cs);
596 count = ipa_callsite_param_count (cs);
597 for (i = 0; i < count; i++)
599 jump_func = ipa_callsite_param (cs, i);
600 type = get_type (jump_func);
601 info_type = ipa_jf_get_info_type (jump_func);
602 ipcp_cval_compute (&cval1, mt, type, info_type);
603 cval2 = ipcp_method_cval (callee, i);
604 ipcp_cval_meet (&cval, &cval1, cval2);
605 if (ipcp_cval_changed (&cval, cval2))
607 ipcp_method_cval_set (callee, i, &cval);
608 ipa_add_method (&wl, callee);
615 /* Call the constant propagation algorithm and re-call it if necessary
616 (if there are undetermined values left). */
617 static void
618 ipcp_iterate_stage (void)
620 ipcp_propagate_stage ();
621 if (ipcp_after_propagate ())
622 /* Some cvals have changed from TOP to BOTTOM.
623 This change should be propagated. */
624 ipcp_propagate_stage ();
627 /* Check conditions to forbid constant insertion to MT. */
628 static bool
629 ipcp_method_dont_insert_const (struct cgraph_node *mt)
631 /* ??? Handle pending sizes case. */
632 if (DECL_UNINLINABLE (mt->decl))
633 return true;
634 return false;
637 /* Print ipa_jump_func data structures to F. */
638 static void
639 ipcp_callsite_param_print (FILE * f)
641 struct cgraph_node *node;
642 int i, count;
643 struct cgraph_edge *cs;
644 struct ipa_jump_func *jump_func;
645 enum jump_func_type type;
646 tree info_type;
648 fprintf (f, "\nCALLSITE PARAM PRINT\n");
649 for (node = cgraph_nodes; node; node = node->next)
651 for (cs = node->callees; cs; cs = cs->next_callee)
653 fprintf (f, "callsite %s ", cgraph_node_name (node));
654 fprintf (f, "-> %s :: \n", cgraph_node_name (cs->callee));
655 count = ipa_callsite_param_count (cs);
656 for (i = 0; i < count; i++)
658 jump_func = ipa_callsite_param (cs, i);
659 type = get_type (jump_func);
661 fprintf (f, " param %d: ", i);
662 if (type == UNKNOWN_IPATYPE)
663 fprintf (f, "UNKNOWN\n");
664 else if (type == CONST_IPATYPE || type == CONST_IPATYPE_REF)
666 info_type =
667 ipa_jf_get_info_type (jump_func)->value;
668 fprintf (f, "CONST : ");
669 print_generic_expr (f, info_type, 0);
670 fprintf (f, "\n");
672 else if (type == FORMAL_IPATYPE)
674 fprintf (f, "FORMAL : ");
675 fprintf (f, "%d\n",
676 ipa_jf_get_info_type (jump_func)->formal_id);
683 /* Print count scale data structures. */
684 static void
685 ipcp_method_scale_print (FILE * f)
687 struct cgraph_node *node;
689 for (node = cgraph_nodes; node; node = node->next)
691 fprintf (f, "printing scale for %s: ", cgraph_node_name (node));
692 fprintf (f, "value is " HOST_WIDE_INT_PRINT_DEC
693 " \n", (HOST_WIDE_INT) ipcp_method_get_scale (node));
697 /* Print counts of all cgraph nodes. */
698 static void
699 ipcp_profile_mt_count_print (FILE * f)
701 struct cgraph_node *node;
703 for (node = cgraph_nodes; node; node = node->next)
705 fprintf (f, "method %s: ", cgraph_node_name (node));
706 fprintf (f, "count is " HOST_WIDE_INT_PRINT_DEC
707 " \n", (HOST_WIDE_INT) node->count);
711 /* Print counts of all cgraph edges. */
712 static void
713 ipcp_profile_cs_count_print (FILE * f)
715 struct cgraph_node *node;
716 struct cgraph_edge *cs;
718 for (node = cgraph_nodes; node; node = node->next)
720 for (cs = node->callees; cs; cs = cs->next_callee)
722 fprintf (f, "%s -> %s ", cgraph_node_name (cs->caller),
723 cgraph_node_name (cs->callee));
724 fprintf (f, "count is " HOST_WIDE_INT_PRINT_DEC " \n",
725 (HOST_WIDE_INT) cs->count);
730 /* Print all counts and probabilities of cfg edges of all methods. */
731 static void
732 ipcp_profile_edge_print (FILE * f)
734 struct cgraph_node *node;
735 basic_block bb;
736 edge_iterator ei;
737 edge e;
739 for (node = cgraph_nodes; node; node = node->next)
741 fprintf (f, "method %s: \n", cgraph_node_name (node));
742 if (DECL_SAVED_TREE (node->decl))
744 bb =
745 ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl));
746 fprintf (f, "ENTRY: ");
747 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
748 " %d\n", (HOST_WIDE_INT) bb->count, bb->frequency);
750 if (bb->succs)
751 FOR_EACH_EDGE (e, ei, bb->succs)
753 if (e->dest ==
754 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION
755 (node->decl)))
756 fprintf (f, "edge ENTRY -> EXIT, Count");
757 else
758 fprintf (f, "edge ENTRY -> %d, Count", e->dest->index);
759 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
760 " Prob %d\n", (HOST_WIDE_INT) e->count,
761 e->probability);
763 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
765 fprintf (f, "bb[%d]: ", bb->index);
766 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
767 " %d\n", (HOST_WIDE_INT) bb->count, bb->frequency);
768 FOR_EACH_EDGE (e, ei, bb->succs)
770 if (e->dest ==
771 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION
772 (node->decl)))
773 fprintf (f, "edge %d -> EXIT, Count", e->src->index);
774 else
775 fprintf (f, "edge %d -> %d, Count", e->src->index,
776 e->dest->index);
777 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC " Prob %d\n",
778 (HOST_WIDE_INT) e->count, e->probability);
785 /* Print counts and frequencies for all basic blocks of all methods. */
786 static void
787 ipcp_profile_bb_print (FILE * f)
789 basic_block bb;
790 struct cgraph_node *node;
792 for (node = cgraph_nodes; node; node = node->next)
794 fprintf (f, "method %s: \n", cgraph_node_name (node));
795 if (DECL_SAVED_TREE (node->decl))
797 bb =
798 ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl));
799 fprintf (f, "ENTRY: Count");
800 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
801 " Frquency %d\n", (HOST_WIDE_INT) bb->count,
802 bb->frequency);
804 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
806 fprintf (f, "bb[%d]: Count", bb->index);
807 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
808 " Frequency %d\n", (HOST_WIDE_INT) bb->count,
809 bb->frequency);
811 bb =
812 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl));
813 fprintf (f, "EXIT: Count");
814 fprintf (f, " " HOST_WIDE_INT_PRINT_DEC
815 " Frequency %d\n", (HOST_WIDE_INT) bb->count,
816 bb->frequency);
822 /* Print all IPCP data structures to F. */
823 static void
824 ipcp_structures_print (FILE * f)
826 ipcp_method_cval_print (f);
827 ipcp_method_scale_print (f);
828 ipa_method_tree_print (f);
829 ipa_method_modify_print (f);
830 ipcp_callsite_param_print (f);
833 /* Print profile info for all methods. */
834 static void
835 ipcp_profile_print (FILE * f)
837 fprintf (f, "\nNODE COUNTS :\n");
838 ipcp_profile_mt_count_print (f);
839 fprintf (f, "\nCS COUNTS stage:\n");
840 ipcp_profile_cs_count_print (f);
841 fprintf (f, "\nBB COUNTS and FREQUENCIES :\n");
842 ipcp_profile_bb_print (f);
843 fprintf (f, "\nCFG EDGES COUNTS and PROBABILITIES :\n");
844 ipcp_profile_edge_print (f);
847 /* Build and initialize ipa_replace_map struct
848 according to TYPE. This struct is read by versioning, which
849 operates according to the flags sent. PARM_TREE is the
850 formal's tree found to be constant. CVALUE represents the constant. */
851 static struct ipa_replace_map *
852 ipcp_replace_map_create (enum cvalue_type type, tree parm_tree,
853 union parameter_info *cvalue)
855 struct ipa_replace_map *replace_map;
856 tree const_val;
858 replace_map = XCNEW (struct ipa_replace_map);
859 gcc_assert (ipcp_type_is_const (type));
860 if (type == CONST_VALUE_REF )
862 const_val =
863 build_const_val (cvalue, type, TREE_TYPE (TREE_TYPE (parm_tree)));
864 replace_map->old_tree = parm_tree;
865 replace_map->new_tree = const_val;
866 replace_map->replace_p = true;
867 replace_map->ref_p = true;
869 else if (TREE_READONLY (parm_tree) && !TREE_ADDRESSABLE (parm_tree))
871 const_val = build_const_val (cvalue, type, TREE_TYPE (parm_tree));
872 replace_map->old_tree = parm_tree;
873 replace_map->new_tree = const_val;
874 replace_map->replace_p = true;
875 replace_map->ref_p = false;
877 else
879 replace_map->old_tree = NULL;
880 replace_map->new_tree = NULL;
881 replace_map->replace_p = false;
882 replace_map->ref_p = false;
885 return replace_map;
888 /* Return true if this callsite should be redirected to
889 the orig callee (instead of the cloned one). */
890 static bool
891 ipcp_redirect (struct cgraph_edge *cs)
893 struct cgraph_node *caller, *callee, *orig_callee;
894 int i, count;
895 struct ipa_jump_func *jump_func;
896 enum jump_func_type type;
897 enum cvalue_type cval_type;
899 caller = cs->caller;
900 callee = cs->callee;
901 orig_callee = ipcp_method_orig_node (callee);
902 count = ipa_method_formal_count (orig_callee);
903 for (i = 0; i < count; i++)
905 cval_type =
906 ipcp_cval_get_cvalue_type (ipcp_method_cval (orig_callee, i));
907 if (ipcp_type_is_const (cval_type))
909 jump_func = ipa_callsite_param (cs, i);
910 type = get_type (jump_func);
911 if (type != CONST_IPATYPE
912 && type != CONST_IPATYPE_REF)
913 return true;
917 return false;
920 /* Fix the callsites and the callgraph after function cloning was done. */
921 static void
922 ipcp_update_callgraph (void)
924 struct cgraph_node *node, *orig_callee;
925 struct cgraph_edge *cs;
927 for (node = cgraph_nodes; node; node = node->next)
929 /* want to fix only original nodes */
930 if (ipcp_method_is_cloned (node))
931 continue;
932 for (cs = node->callees; cs; cs = cs->next_callee)
933 if (ipcp_method_is_cloned (cs->callee))
935 /* Callee is a cloned node */
936 orig_callee = ipcp_method_orig_node (cs->callee);
937 if (ipcp_redirect (cs))
939 cgraph_redirect_edge_callee (cs, orig_callee);
940 TREE_OPERAND (TREE_OPERAND
941 (get_call_expr_in (cs->call_stmt), 0), 0) =
942 orig_callee->decl;
948 /* Update all cfg basic blocks in NODE according to SCALE. */
949 static void
950 ipcp_update_bb_counts (struct cgraph_node *node, gcov_type scale)
952 basic_block bb;
954 FOR_ALL_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
955 bb->count = bb->count * scale / REG_BR_PROB_BASE;
958 /* Update all cfg edges in NODE according to SCALE. */
959 static void
960 ipcp_update_edges_counts (struct cgraph_node *node, gcov_type scale)
962 basic_block bb;
963 edge_iterator ei;
964 edge e;
966 FOR_ALL_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
967 FOR_EACH_EDGE (e, ei, bb->succs)
968 e->count = e->count * scale / REG_BR_PROB_BASE;
971 /* Update profiling info for versioned methods and the
972 methods they were versioned from. */
973 static void
974 ipcp_update_profiling (void)
976 struct cgraph_node *node, *orig_node;
977 gcov_type scale, scale_complement;
978 struct cgraph_edge *cs;
980 for (node = cgraph_nodes; node; node = node->next)
982 if (ipcp_method_is_cloned (node))
984 orig_node = ipcp_method_orig_node (node);
985 scale = ipcp_method_get_scale (orig_node);
986 node->count = orig_node->count * scale / REG_BR_PROB_BASE;
987 scale_complement = REG_BR_PROB_BASE - scale;
988 orig_node->count =
989 orig_node->count * scale_complement / REG_BR_PROB_BASE;
990 for (cs = node->callees; cs; cs = cs->next_callee)
991 cs->count = cs->count * scale / REG_BR_PROB_BASE;
992 for (cs = orig_node->callees; cs; cs = cs->next_callee)
993 cs->count = cs->count * scale_complement / REG_BR_PROB_BASE;
994 ipcp_update_bb_counts (node, scale);
995 ipcp_update_bb_counts (orig_node, scale_complement);
996 ipcp_update_edges_counts (node, scale);
997 ipcp_update_edges_counts (orig_node, scale_complement);
1002 /* Propagate the constant parameters found by ipcp_iterate_stage()
1003 to the function's code. */
1004 static void
1005 ipcp_insert_stage (void)
1007 struct cgraph_node *node, *node1 = NULL;
1008 int i, const_param;
1009 union parameter_info *cvalue;
1010 VEC(cgraph_edge_p,heap) *redirect_callers;
1011 varray_type replace_trees;
1012 struct cgraph_edge *cs;
1013 int node_callers, count;
1014 tree parm_tree;
1015 enum cvalue_type type;
1016 struct ipa_replace_map *replace_param;
1018 for (node = cgraph_nodes; node; node = node->next)
1020 /* Propagation of the constant is forbidden in
1021 certain conditions. */
1022 if (ipcp_method_dont_insert_const (node))
1023 continue;
1024 const_param = 0;
1025 count = ipa_method_formal_count (node);
1026 for (i = 0; i < count; i++)
1028 type = ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i));
1029 if (ipcp_type_is_const (type))
1030 const_param++;
1032 if (const_param == 0)
1033 continue;
1034 VARRAY_GENERIC_PTR_INIT (replace_trees, const_param, "replace_trees");
1035 for (i = 0; i < count; i++)
1037 type = ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i));
1038 if (ipcp_type_is_const (type))
1040 cvalue = ipcp_cval_get_cvalue (ipcp_method_cval (node, i));
1041 parm_tree = ipa_method_get_tree (node, i);
1042 replace_param =
1043 ipcp_replace_map_create (type, parm_tree, cvalue);
1044 VARRAY_PUSH_GENERIC_PTR (replace_trees, replace_param);
1047 /* Compute how many callers node has. */
1048 node_callers = 0;
1049 for (cs = node->callers; cs != NULL; cs = cs->next_caller)
1050 node_callers++;
1051 redirect_callers = VEC_alloc (cgraph_edge_p, heap, node_callers);
1052 for (cs = node->callers; cs != NULL; cs = cs->next_caller)
1053 VEC_quick_push (cgraph_edge_p, redirect_callers, cs);
1054 /* Redirecting all the callers of the node to the
1055 new versioned node. */
1056 node1 =
1057 cgraph_function_versioning (node, redirect_callers, replace_trees);
1058 VEC_free (cgraph_edge_p, heap, redirect_callers);
1059 VARRAY_CLEAR (replace_trees);
1060 if (node1 == NULL)
1061 continue;
1062 if (dump_file)
1063 fprintf (dump_file, "versioned function %s\n",
1064 cgraph_node_name (node));
1065 ipcp_cloned_create (node, node1);
1066 for (i = 0; i < count; i++)
1068 type = ipcp_cval_get_cvalue_type (ipcp_method_cval (node, i));
1069 if (ipcp_type_is_const (type))
1071 cvalue = ipcp_cval_get_cvalue (ipcp_method_cval (node, i));
1072 parm_tree = ipa_method_get_tree (node, i);
1073 if (type != CONST_VALUE_REF
1074 && !TREE_READONLY (parm_tree))
1075 ipcp_propagate_const (node1, i, cvalue, type);
1079 ipcp_update_callgraph ();
1080 ipcp_update_profiling ();
1083 /* The IPCP driver. */
1084 unsigned int
1085 ipcp_driver (void)
1087 if (dump_file)
1088 fprintf (dump_file, "\nIPA constant propagation start:\n");
1089 ipa_nodes_create ();
1090 ipa_edges_create ();
1091 /* 1. Call the init stage to initialize
1092 the ipa_node and ipa_edge structures. */
1093 ipcp_init_stage ();
1094 if (dump_file)
1096 fprintf (dump_file, "\nIPA structures before propagation:\n");
1097 ipcp_structures_print (dump_file);
1099 /* 2. Do the interprocedural propagation. */
1100 ipcp_iterate_stage ();
1101 if (dump_file)
1103 fprintf (dump_file, "\nIPA structures after propagation:\n");
1104 ipcp_structures_print (dump_file);
1105 fprintf (dump_file, "\nProfiling info before insert stage:\n");
1106 ipcp_profile_print (dump_file);
1108 /* 3. Insert the constants found to the functions. */
1109 ipcp_insert_stage ();
1110 if (dump_file)
1112 fprintf (dump_file, "\nProfiling info after insert stage:\n");
1113 ipcp_profile_print (dump_file);
1115 /* Free all IPCP structures. */
1116 ipa_free ();
1117 ipa_nodes_free ();
1118 ipa_edges_free ();
1119 if (dump_file)
1120 fprintf (dump_file, "\nIPA constant propagation end\n");
1121 cgraph_remove_unreachable_nodes (true, NULL);
1122 return 0;
1125 /* Gate for IPCP optimization. */
1126 static bool
1127 cgraph_gate_cp (void)
1129 return flag_ipa_cp;
1132 struct tree_opt_pass pass_ipa_cp = {
1133 "cp", /* name */
1134 cgraph_gate_cp, /* gate */
1135 ipcp_driver, /* execute */
1136 NULL, /* sub */
1137 NULL, /* next */
1138 0, /* static_pass_number */
1139 TV_IPA_CONSTANT_PROP, /* tv_id */
1140 0, /* properties_required */
1141 PROP_trees, /* properties_provided */
1142 0, /* properties_destroyed */
1143 0, /* todo_flags_start */
1144 TODO_dump_cgraph | TODO_dump_func, /* todo_flags_finish */
1145 0 /* letter */