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
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
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
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,
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,
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
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:
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
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
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.
136 #include "coretypes.h"
140 #include "ipa-prop.h"
141 #include "tree-flow.h"
142 #include "tree-pass.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. */
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. */
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. */
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. */
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. */
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. */
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. */
229 ipcp_type_is_const (enum cvalue_type type
)
231 if (type
== CONST_VALUE
|| type
== CONST_VALUE_REF
)
237 /* Return true if CONST_VAL1 and CONST_VAL2 are equal. */
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
));
247 if (operand_equal_p (const_val1
->value
, const_val2
->value
, 0))
253 /* Compute Meet arithmetics:
254 Meet (BOTTOM, x) = BOTTOM
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.*/
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
);
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
));
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
));
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
);
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
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
)),
334 /* True when CVAL1 and CVAL2 values are not the same. */
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
)
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
)))
352 /* Create cval structure for method MT. */
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. */
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. */
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. */
379 ipcp_method_cval_print (FILE * f
)
381 struct cgraph_node
*node
;
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
))
394 || ipcp_cval_get_cvalue_type (ipcp_method_cval (node
, i
)) ==
397 fprintf (f
, " param [%d]: ", i
);
398 fprintf (f
, "type is CONST ");
400 ipcp_cval_get_cvalue (ipcp_method_cval (node
, i
))->value
;
401 print_generic_expr (f
, cvalue
, 0);
404 else if (ipcp_method_cval (node
, i
)->cval_type
== TOP
)
405 fprintf (f
, "param [%d]: type is TOP \n", i
);
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. */
419 ipcp_method_cval_init (struct cgraph_node
*mt
)
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
);
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
440 PARM1 is the lhs of the assignment and
443 constant_val_insert (tree parm1
, tree val
)
445 tree init_stmt
= NULL
;
448 init_stmt
= build_gimple_modify_stmt (parm1
, val
);
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. */
460 build_const_val (union parameter_info
*cvalue
, enum cvalue_type type
,
463 tree const_val
= NULL
;
465 gcc_assert (ipcp_type_is_const (type
));
466 const_val
= fold_convert (tree_type
, cvalue
->value
);
470 /* Build the tree representing the constant and call
471 constant_val_insert(). */
473 ipcp_propagate_const (struct cgraph_node
*mt
, int param
,
474 union parameter_info
*cvalue
, enum cvalue_type type
)
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). */
491 ipcp_method_compute_scale (struct cgraph_node
*node
)
494 struct cgraph_edge
*cs
;
497 /* Compute sum of all counts of callers. */
498 for (cs
= node
->callers
; cs
!= NULL
; cs
= cs
->next_caller
)
500 if (node
->count
== 0)
501 ipcp_method_set_scale (node
, 0);
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
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);
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. */
547 ipcp_after_propagate (void)
550 struct cgraph_node
*node
;
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
)
561 ipcp_method_cval_set_cvalue_type (node
, i
, BOTTOM
);
567 /* Interprocedural analysis. The algorithm propagates constants from
568 the caller's parameters to the callee's arguments. */
570 ipcp_propagate_stage (void)
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
;
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). */
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. */
624 ipcp_method_dont_insert_const (struct cgraph_node
*mt
)
626 /* ??? Handle pending sizes case. */
627 if (DECL_UNINLINABLE (mt
->decl
))
632 /* Print ipa_jump_func data structures to F. */
634 ipcp_callsite_param_print (FILE * f
)
636 struct cgraph_node
*node
;
638 struct cgraph_edge
*cs
;
639 struct ipa_jump_func
*jump_func
;
640 enum jump_func_type 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);
666 else if (type
== FORMAL_IPATYPE
)
668 fprintf (f
, "FORMAL : ");
670 ipa_jf_get_info_type (jump_func
)->formal_id
);
677 /* Print count scale data structures. */
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. */
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. */
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. */
726 ipcp_profile_edge_print (FILE * f
)
728 struct cgraph_node
*node
;
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
))
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
);
745 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
748 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION
750 fprintf (f
, "edge ENTRY -> EXIT, Count");
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
,
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
)
765 EXIT_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION
767 fprintf (f
, "edge %d -> EXIT, Count", e
->src
->index
);
769 fprintf (f
, "edge %d -> %d, Count", e
->src
->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. */
781 ipcp_profile_bb_print (FILE * f
)
784 struct cgraph_node
*node
;
786 for (node
= cgraph_nodes
; node
; node
= node
->next
)
788 fprintf (f
, "method %s: \n", cgraph_node_name (node
));
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
,
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
,
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
,
816 /* Print all IPCP data structures to F. */
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. */
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
;
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
)))
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;
868 replace_map
->old_tree
= NULL
;
869 replace_map
->new_tree
= NULL
;
870 replace_map
->replace_p
= false;
871 replace_map
->ref_p
= false;
877 /* Return true if this callsite should be redirected to
878 the orig callee (instead of the cloned one). */
880 ipcp_redirect (struct cgraph_edge
*cs
)
882 struct cgraph_node
*caller
, *callee
, *orig_callee
;
884 struct ipa_jump_func
*jump_func
;
885 enum jump_func_type type
;
886 enum cvalue_type cval_type
;
890 orig_callee
= ipcp_method_orig_node (callee
);
891 count
= ipa_method_formal_count (orig_callee
);
892 for (i
= 0; i
< count
; i
++)
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
)
908 /* Fix the callsites and the callgraph after function cloning was done. */
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
))
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
)),
936 /* Update all cfg basic blocks in NODE according to SCALE. */
938 ipcp_update_bb_counts (struct cgraph_node
*node
, gcov_type scale
)
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. */
948 ipcp_update_edges_counts (struct cgraph_node
*node
, gcov_type scale
)
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. */
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
;
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. */
993 ipcp_insert_stage (void)
995 struct cgraph_node
*node
, *node1
= NULL
;
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
;
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
))
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
))
1020 if (const_param
== 0)
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
);
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. */
1038 for (cs
= node
->callers
; cs
!= NULL
; cs
= cs
->next_caller
)
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. */
1046 cgraph_function_versioning (node
, redirect_callers
, replace_trees
);
1047 VEC_free (cgraph_edge_p
, heap
, redirect_callers
);
1048 VARRAY_CLEAR (replace_trees
);
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
1079 free_dominance_info (CDI_DOMINATORS
);
1080 free_dominance_info (CDI_POST_DOMINATORS
);
1082 current_function_decl
= NULL
;
1085 dump_function_to_file (node1
->decl
, dump_file
, dump_flags
);
1087 ipcp_update_callgraph ();
1088 ipcp_update_profiling ();
1091 /* The IPCP driver. */
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. */
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 ();
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 ();
1120 fprintf (dump_file
, "\nProfiling info after insert stage:\n");
1121 ipcp_profile_print (dump_file
);
1123 /* Free all IPCP structures. */
1128 fprintf (dump_file
, "\nIPA constant propagation end\n");
1129 cgraph_remove_unreachable_nodes (true, NULL
);
1133 /* Gate for IPCP optimization. */
1135 cgraph_gate_cp (void)
1140 struct tree_opt_pass pass_ipa_cp
= {
1142 cgraph_gate_cp
, /* gate */
1143 ipcp_driver
, /* execute */
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 */