1 /* Interprocedural analyses.
2 Copyright (C) 2005-2014 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
24 #include "basic-block.h"
25 #include "tree-ssa-alias.h"
26 #include "internal-fn.h"
27 #include "gimple-fold.h"
29 #include "gimple-expr.h"
33 #include "stor-layout.h"
34 #include "print-tree.h"
36 #include "gimple-iterator.h"
37 #include "gimplify-me.h"
38 #include "gimple-walk.h"
39 #include "langhooks.h"
43 #include "gimple-ssa.h"
45 #include "tree-phinodes.h"
46 #include "ssa-iterators.h"
47 #include "tree-into-ssa.h"
49 #include "tree-pass.h"
50 #include "tree-inline.h"
51 #include "ipa-inline.h"
53 #include "diagnostic.h"
54 #include "gimple-pretty-print.h"
55 #include "lto-streamer.h"
56 #include "data-streamer.h"
57 #include "tree-streamer.h"
59 #include "ipa-utils.h"
60 #include "stringpool.h"
61 #include "tree-ssanames.h"
67 /* Intermediate information that we get from alias analysis about a particular
68 parameter in a particular basic_block. When a parameter or the memory it
69 references is marked modified, we use that information in all dominatd
70 blocks without cosulting alias analysis oracle. */
72 struct param_aa_status
74 /* Set when this structure contains meaningful information. If not, the
75 structure describing a dominating BB should be used instead. */
78 /* Whether we have seen something which might have modified the data in
79 question. PARM is for the parameter itself, REF is for data it points to
80 but using the alias type of individual accesses and PT is the same thing
81 but for computing aggregate pass-through functions using a very inclusive
83 bool parm_modified
, ref_modified
, pt_modified
;
86 /* Information related to a given BB that used only when looking at function
91 /* Call graph edges going out of this BB. */
92 vec
<cgraph_edge
*> cg_edges
;
93 /* Alias analysis statuses of each formal parameter at this bb. */
94 vec
<param_aa_status
> param_aa_statuses
;
97 /* Structure with global information that is only used when looking at function
100 struct func_body_info
102 /* The node that is being analyzed. */
106 struct ipa_node_params
*info
;
108 /* Information about individual BBs. */
109 vec
<ipa_bb_info
> bb_infos
;
111 /* Number of parameters. */
114 /* Number of statements already walked by when analyzing this function. */
115 unsigned int aa_walked
;
118 /* Vector where the parameter infos are actually stored. */
119 vec
<ipa_node_params
> ipa_node_params_vector
;
120 /* Vector of known aggregate values in cloned nodes. */
121 vec
<ipa_agg_replacement_value_p
, va_gc
> *ipa_node_agg_replacements
;
122 /* Vector where the parameter infos are actually stored. */
123 vec
<ipa_edge_args
, va_gc
> *ipa_edge_args_vector
;
125 /* Holders of ipa cgraph hooks: */
126 static struct cgraph_edge_hook_list
*edge_removal_hook_holder
;
127 static struct cgraph_node_hook_list
*node_removal_hook_holder
;
128 static struct cgraph_2edge_hook_list
*edge_duplication_hook_holder
;
129 static struct cgraph_2node_hook_list
*node_duplication_hook_holder
;
130 static struct cgraph_node_hook_list
*function_insertion_hook_holder
;
132 /* Description of a reference to an IPA constant. */
133 struct ipa_cst_ref_desc
135 /* Edge that corresponds to the statement which took the reference. */
136 struct cgraph_edge
*cs
;
137 /* Linked list of duplicates created when call graph edges are cloned. */
138 struct ipa_cst_ref_desc
*next_duplicate
;
139 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
140 if out of control. */
144 /* Allocation pool for reference descriptions. */
146 static alloc_pool ipa_refdesc_pool
;
148 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
149 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
152 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node
*node
)
154 tree fs_opts
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node
->decl
);
155 struct cl_optimization
*os
;
159 os
= TREE_OPTIMIZATION (fs_opts
);
160 return !os
->x_optimize
|| !os
->x_flag_ipa_cp
;
163 /* Return index of the formal whose tree is PTREE in function which corresponds
167 ipa_get_param_decl_index_1 (vec
<ipa_param_descriptor
> descriptors
, tree ptree
)
171 count
= descriptors
.length ();
172 for (i
= 0; i
< count
; i
++)
173 if (descriptors
[i
].decl
== ptree
)
179 /* Return index of the formal whose tree is PTREE in function which corresponds
183 ipa_get_param_decl_index (struct ipa_node_params
*info
, tree ptree
)
185 return ipa_get_param_decl_index_1 (info
->descriptors
, ptree
);
188 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
192 ipa_populate_param_decls (struct cgraph_node
*node
,
193 vec
<ipa_param_descriptor
> &descriptors
)
201 gcc_assert (gimple_has_body_p (fndecl
));
202 fnargs
= DECL_ARGUMENTS (fndecl
);
204 for (parm
= fnargs
; parm
; parm
= DECL_CHAIN (parm
))
206 descriptors
[param_num
].decl
= parm
;
207 descriptors
[param_num
].move_cost
= estimate_move_cost (TREE_TYPE (parm
),
213 /* Return how many formal parameters FNDECL has. */
216 count_formal_params (tree fndecl
)
220 gcc_assert (gimple_has_body_p (fndecl
));
222 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
228 /* Return the declaration of Ith formal parameter of the function corresponding
229 to INFO. Note there is no setter function as this array is built just once
230 using ipa_initialize_node_params. */
233 ipa_dump_param (FILE *file
, struct ipa_node_params
*info
, int i
)
235 fprintf (file
, "param #%i", i
);
236 if (info
->descriptors
[i
].decl
)
239 print_generic_expr (file
, info
->descriptors
[i
].decl
, 0);
243 /* Initialize the ipa_node_params structure associated with NODE
244 to hold PARAM_COUNT parameters. */
247 ipa_alloc_node_params (struct cgraph_node
*node
, int param_count
)
249 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
251 if (!info
->descriptors
.exists () && param_count
)
252 info
->descriptors
.safe_grow_cleared (param_count
);
255 /* Initialize the ipa_node_params structure associated with NODE by counting
256 the function parameters, creating the descriptors and populating their
260 ipa_initialize_node_params (struct cgraph_node
*node
)
262 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
264 if (!info
->descriptors
.exists ())
266 ipa_alloc_node_params (node
, count_formal_params (node
->decl
));
267 ipa_populate_param_decls (node
, info
->descriptors
);
271 /* Print the jump functions associated with call graph edge CS to file F. */
274 ipa_print_node_jump_functions_for_edge (FILE *f
, struct cgraph_edge
*cs
)
278 count
= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
));
279 for (i
= 0; i
< count
; i
++)
281 struct ipa_jump_func
*jump_func
;
282 enum jump_func_type type
;
284 jump_func
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), i
);
285 type
= jump_func
->type
;
287 fprintf (f
, " param %d: ", i
);
288 if (type
== IPA_JF_UNKNOWN
)
289 fprintf (f
, "UNKNOWN\n");
290 else if (type
== IPA_JF_KNOWN_TYPE
)
292 fprintf (f
, "KNOWN TYPE: base ");
293 print_generic_expr (f
, jump_func
->value
.known_type
.base_type
, 0);
294 fprintf (f
, ", offset "HOST_WIDE_INT_PRINT_DEC
", component ",
295 jump_func
->value
.known_type
.offset
);
296 print_generic_expr (f
, jump_func
->value
.known_type
.component_type
, 0);
299 else if (type
== IPA_JF_CONST
)
301 tree val
= jump_func
->value
.constant
.value
;
302 fprintf (f
, "CONST: ");
303 print_generic_expr (f
, val
, 0);
304 if (TREE_CODE (val
) == ADDR_EXPR
305 && TREE_CODE (TREE_OPERAND (val
, 0)) == CONST_DECL
)
308 print_generic_expr (f
, DECL_INITIAL (TREE_OPERAND (val
, 0)),
313 else if (type
== IPA_JF_PASS_THROUGH
)
315 fprintf (f
, "PASS THROUGH: ");
316 fprintf (f
, "%d, op %s",
317 jump_func
->value
.pass_through
.formal_id
,
318 get_tree_code_name(jump_func
->value
.pass_through
.operation
));
319 if (jump_func
->value
.pass_through
.operation
!= NOP_EXPR
)
322 print_generic_expr (f
,
323 jump_func
->value
.pass_through
.operand
, 0);
325 if (jump_func
->value
.pass_through
.agg_preserved
)
326 fprintf (f
, ", agg_preserved");
327 if (jump_func
->value
.pass_through
.type_preserved
)
328 fprintf (f
, ", type_preserved");
331 else if (type
== IPA_JF_ANCESTOR
)
333 fprintf (f
, "ANCESTOR: ");
334 fprintf (f
, "%d, offset "HOST_WIDE_INT_PRINT_DEC
", ",
335 jump_func
->value
.ancestor
.formal_id
,
336 jump_func
->value
.ancestor
.offset
);
337 print_generic_expr (f
, jump_func
->value
.ancestor
.type
, 0);
338 if (jump_func
->value
.ancestor
.agg_preserved
)
339 fprintf (f
, ", agg_preserved");
340 if (jump_func
->value
.ancestor
.type_preserved
)
341 fprintf (f
, ", type_preserved");
345 if (jump_func
->agg
.items
)
347 struct ipa_agg_jf_item
*item
;
350 fprintf (f
, " Aggregate passed by %s:\n",
351 jump_func
->agg
.by_ref
? "reference" : "value");
352 FOR_EACH_VEC_SAFE_ELT (jump_func
->agg
.items
, j
, item
)
354 fprintf (f
, " offset: " HOST_WIDE_INT_PRINT_DEC
", ",
356 if (TYPE_P (item
->value
))
357 fprintf (f
, "clobber of " HOST_WIDE_INT_PRINT_DEC
" bits",
358 tree_to_uhwi (TYPE_SIZE (item
->value
)));
361 fprintf (f
, "cst: ");
362 print_generic_expr (f
, item
->value
, 0);
371 /* Print the jump functions of all arguments on all call graph edges going from
375 ipa_print_node_jump_functions (FILE *f
, struct cgraph_node
*node
)
377 struct cgraph_edge
*cs
;
379 fprintf (f
, " Jump functions of caller %s/%i:\n", node
->name (),
381 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
383 if (!ipa_edge_args_info_available_for_edge_p (cs
))
386 fprintf (f
, " callsite %s/%i -> %s/%i : \n",
387 xstrdup (node
->name ()), node
->order
,
388 xstrdup (cs
->callee
->name ()),
390 ipa_print_node_jump_functions_for_edge (f
, cs
);
393 for (cs
= node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
395 struct cgraph_indirect_call_info
*ii
;
396 if (!ipa_edge_args_info_available_for_edge_p (cs
))
399 ii
= cs
->indirect_info
;
400 if (ii
->agg_contents
)
401 fprintf (f
, " indirect %s callsite, calling param %i, "
402 "offset " HOST_WIDE_INT_PRINT_DEC
", %s",
403 ii
->member_ptr
? "member ptr" : "aggregate",
404 ii
->param_index
, ii
->offset
,
405 ii
->by_ref
? "by reference" : "by_value");
407 fprintf (f
, " indirect %s callsite, calling param %i, "
408 "offset " HOST_WIDE_INT_PRINT_DEC
,
409 ii
->polymorphic
? "polymorphic" : "simple", ii
->param_index
,
414 fprintf (f
, ", for stmt ");
415 print_gimple_stmt (f
, cs
->call_stmt
, 0, TDF_SLIM
);
419 ipa_print_node_jump_functions_for_edge (f
, cs
);
423 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
426 ipa_print_all_jump_functions (FILE *f
)
428 struct cgraph_node
*node
;
430 fprintf (f
, "\nJump functions:\n");
431 FOR_EACH_FUNCTION (node
)
433 ipa_print_node_jump_functions (f
, node
);
437 /* Set JFUNC to be a known type jump function. */
440 ipa_set_jf_known_type (struct ipa_jump_func
*jfunc
, HOST_WIDE_INT offset
,
441 tree base_type
, tree component_type
)
443 /* Recording and propagating main variants increases change that types
445 base_type
= TYPE_MAIN_VARIANT (base_type
);
446 component_type
= TYPE_MAIN_VARIANT (component_type
);
448 gcc_assert (contains_polymorphic_type_p (base_type
)
449 && contains_polymorphic_type_p (component_type
));
450 if (!flag_devirtualize
)
452 jfunc
->type
= IPA_JF_KNOWN_TYPE
;
453 jfunc
->value
.known_type
.offset
= offset
,
454 jfunc
->value
.known_type
.base_type
= base_type
;
455 jfunc
->value
.known_type
.component_type
= component_type
;
456 gcc_assert (component_type
);
459 /* Set JFUNC to be a copy of another jmp (to be used by jump function
460 combination code). The two functions will share their rdesc. */
463 ipa_set_jf_cst_copy (struct ipa_jump_func
*dst
,
464 struct ipa_jump_func
*src
)
467 gcc_checking_assert (src
->type
== IPA_JF_CONST
);
468 dst
->type
= IPA_JF_CONST
;
469 dst
->value
.constant
= src
->value
.constant
;
472 /* Set JFUNC to be a constant jmp function. */
475 ipa_set_jf_constant (struct ipa_jump_func
*jfunc
, tree constant
,
476 struct cgraph_edge
*cs
)
478 constant
= unshare_expr (constant
);
479 if (constant
&& EXPR_P (constant
))
480 SET_EXPR_LOCATION (constant
, UNKNOWN_LOCATION
);
481 jfunc
->type
= IPA_JF_CONST
;
482 jfunc
->value
.constant
.value
= unshare_expr_without_location (constant
);
484 if (TREE_CODE (constant
) == ADDR_EXPR
485 && TREE_CODE (TREE_OPERAND (constant
, 0)) == FUNCTION_DECL
)
487 struct ipa_cst_ref_desc
*rdesc
;
488 if (!ipa_refdesc_pool
)
489 ipa_refdesc_pool
= create_alloc_pool ("IPA-PROP ref descriptions",
490 sizeof (struct ipa_cst_ref_desc
), 32);
492 rdesc
= (struct ipa_cst_ref_desc
*) pool_alloc (ipa_refdesc_pool
);
494 rdesc
->next_duplicate
= NULL
;
496 jfunc
->value
.constant
.rdesc
= rdesc
;
499 jfunc
->value
.constant
.rdesc
= NULL
;
502 /* Set JFUNC to be a simple pass-through jump function. */
504 ipa_set_jf_simple_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
505 bool agg_preserved
, bool type_preserved
)
507 jfunc
->type
= IPA_JF_PASS_THROUGH
;
508 jfunc
->value
.pass_through
.operand
= NULL_TREE
;
509 jfunc
->value
.pass_through
.formal_id
= formal_id
;
510 jfunc
->value
.pass_through
.operation
= NOP_EXPR
;
511 jfunc
->value
.pass_through
.agg_preserved
= agg_preserved
;
512 jfunc
->value
.pass_through
.type_preserved
= type_preserved
;
515 /* Set JFUNC to be an arithmetic pass through jump function. */
518 ipa_set_jf_arith_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
519 tree operand
, enum tree_code operation
)
521 jfunc
->type
= IPA_JF_PASS_THROUGH
;
522 jfunc
->value
.pass_through
.operand
= unshare_expr_without_location (operand
);
523 jfunc
->value
.pass_through
.formal_id
= formal_id
;
524 jfunc
->value
.pass_through
.operation
= operation
;
525 jfunc
->value
.pass_through
.agg_preserved
= false;
526 jfunc
->value
.pass_through
.type_preserved
= false;
529 /* Set JFUNC to be an ancestor jump function. */
532 ipa_set_ancestor_jf (struct ipa_jump_func
*jfunc
, HOST_WIDE_INT offset
,
533 tree type
, int formal_id
, bool agg_preserved
,
536 if (!flag_devirtualize
)
537 type_preserved
= false;
541 type
= TYPE_MAIN_VARIANT (type
);
542 gcc_assert (!type_preserved
|| contains_polymorphic_type_p (type
));
543 jfunc
->type
= IPA_JF_ANCESTOR
;
544 jfunc
->value
.ancestor
.formal_id
= formal_id
;
545 jfunc
->value
.ancestor
.offset
= offset
;
546 jfunc
->value
.ancestor
.type
= type_preserved
? type
: NULL
;
547 jfunc
->value
.ancestor
.agg_preserved
= agg_preserved
;
548 jfunc
->value
.ancestor
.type_preserved
= type_preserved
;
551 /* Extract the acual BINFO being described by JFUNC which must be a known type
555 ipa_binfo_from_known_type_jfunc (struct ipa_jump_func
*jfunc
)
557 if (!RECORD_OR_UNION_TYPE_P (jfunc
->value
.known_type
.base_type
))
560 tree base_binfo
= TYPE_BINFO (jfunc
->value
.known_type
.base_type
);
564 /* FIXME: At LTO we can't propagate to non-polymorphic type, because
565 we have no ODR equivalency on those. This should be fixed by
566 propagating on types rather than binfos that would make type
567 matching here unnecesary. */
569 && (TREE_CODE (jfunc
->value
.known_type
.component_type
) != RECORD_TYPE
570 || !TYPE_BINFO (jfunc
->value
.known_type
.component_type
)
571 || !BINFO_VTABLE (TYPE_BINFO (jfunc
->value
.known_type
.component_type
))))
573 if (!jfunc
->value
.known_type
.offset
)
577 return get_binfo_at_offset (base_binfo
,
578 jfunc
->value
.known_type
.offset
,
579 jfunc
->value
.known_type
.component_type
);
582 /* Get IPA BB information about the given BB. FBI is the context of analyzis
583 of this function body. */
585 static struct ipa_bb_info
*
586 ipa_get_bb_info (struct func_body_info
*fbi
, basic_block bb
)
588 gcc_checking_assert (fbi
);
589 return &fbi
->bb_infos
[bb
->index
];
592 /* Structure to be passed in between detect_type_change and
593 check_stmt_for_type_change. */
595 struct prop_type_change_info
597 /* Offset into the object where there is the virtual method pointer we are
599 HOST_WIDE_INT offset
;
600 /* The declaration or SSA_NAME pointer of the base that we are checking for
603 /* If we actually can tell the type that the object has changed to, it is
604 stored in this field. Otherwise it remains NULL_TREE. */
605 tree known_current_type
;
606 /* Set to true if dynamic type change has been detected. */
607 bool type_maybe_changed
;
608 /* Set to true if multiple types have been encountered. known_current_type
609 must be disregarded in that case. */
610 bool multiple_types_encountered
;
613 /* Return true if STMT can modify a virtual method table pointer.
615 This function makes special assumptions about both constructors and
616 destructors which are all the functions that are allowed to alter the VMT
617 pointers. It assumes that destructors begin with assignment into all VMT
618 pointers and that constructors essentially look in the following way:
620 1) The very first thing they do is that they call constructors of ancestor
621 sub-objects that have them.
623 2) Then VMT pointers of this and all its ancestors is set to new values
624 corresponding to the type corresponding to the constructor.
626 3) Only afterwards, other stuff such as constructor of member sub-objects
627 and the code written by the user is run. Only this may include calling
628 virtual functions, directly or indirectly.
630 There is no way to call a constructor of an ancestor sub-object in any
633 This means that we do not have to care whether constructors get the correct
634 type information because they will always change it (in fact, if we define
635 the type to be given by the VMT pointer, it is undefined).
637 The most important fact to derive from the above is that if, for some
638 statement in the section 3, we try to detect whether the dynamic type has
639 changed, we can safely ignore all calls as we examine the function body
640 backwards until we reach statements in section 2 because these calls cannot
641 be ancestor constructors or destructors (if the input is not bogus) and so
642 do not change the dynamic type (this holds true only for automatically
643 allocated objects but at the moment we devirtualize only these). We then
644 must detect that statements in section 2 change the dynamic type and can try
645 to derive the new type. That is enough and we can stop, we will never see
646 the calls into constructors of sub-objects in this code. Therefore we can
647 safely ignore all call statements that we traverse.
651 stmt_may_be_vtbl_ptr_store (gimple stmt
)
653 if (is_gimple_call (stmt
))
655 if (gimple_clobber_p (stmt
))
657 else if (is_gimple_assign (stmt
))
659 tree lhs
= gimple_assign_lhs (stmt
);
661 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs
)))
663 if (flag_strict_aliasing
664 && !POINTER_TYPE_P (TREE_TYPE (lhs
)))
667 if (TREE_CODE (lhs
) == COMPONENT_REF
668 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs
, 1)))
670 /* In the future we might want to use get_base_ref_and_offset to find
671 if there is a field corresponding to the offset and if so, proceed
672 almost like if it was a component ref. */
678 /* If STMT can be proved to be an assignment to the virtual method table
679 pointer of ANALYZED_OBJ and the type associated with the new table
680 identified, return the type. Otherwise return NULL_TREE. */
683 extr_type_from_vtbl_ptr_store (gimple stmt
, struct prop_type_change_info
*tci
)
685 HOST_WIDE_INT offset
, size
, max_size
;
686 tree lhs
, rhs
, base
, binfo
;
688 if (!gimple_assign_single_p (stmt
))
691 lhs
= gimple_assign_lhs (stmt
);
692 rhs
= gimple_assign_rhs1 (stmt
);
693 if (TREE_CODE (lhs
) != COMPONENT_REF
694 || !DECL_VIRTUAL_P (TREE_OPERAND (lhs
, 1)))
697 base
= get_ref_base_and_extent (lhs
, &offset
, &size
, &max_size
);
698 if (offset
!= tci
->offset
699 || size
!= POINTER_SIZE
700 || max_size
!= POINTER_SIZE
)
702 if (TREE_CODE (base
) == MEM_REF
)
704 if (TREE_CODE (tci
->object
) != MEM_REF
705 || TREE_OPERAND (tci
->object
, 0) != TREE_OPERAND (base
, 0)
706 || !tree_int_cst_equal (TREE_OPERAND (tci
->object
, 1),
707 TREE_OPERAND (base
, 1)))
710 else if (tci
->object
!= base
)
713 binfo
= vtable_pointer_value_to_binfo (rhs
);
715 /* FIXME: vtable_pointer_value_to_binfo may return BINFO of a
716 base of outer type. In this case we would need to either
717 work on binfos or translate it back to outer type and offset.
718 KNOWN_TYPE jump functions are not ready for that, yet. */
719 if (!binfo
|| TYPE_BINFO (BINFO_TYPE (binfo
)) != binfo
)
722 return BINFO_TYPE (binfo
);
725 /* Callback of walk_aliased_vdefs and a helper function for
726 detect_type_change to check whether a particular statement may modify
727 the virtual table pointer, and if possible also determine the new type of
728 the (sub-)object. It stores its result into DATA, which points to a
729 prop_type_change_info structure. */
732 check_stmt_for_type_change (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef
, void *data
)
734 gimple stmt
= SSA_NAME_DEF_STMT (vdef
);
735 struct prop_type_change_info
*tci
= (struct prop_type_change_info
*) data
;
737 if (stmt_may_be_vtbl_ptr_store (stmt
))
741 type
= extr_type_from_vtbl_ptr_store (stmt
, tci
);
742 gcc_assert (!type
|| TYPE_MAIN_VARIANT (type
) == type
);
743 if (tci
->type_maybe_changed
744 && type
!= tci
->known_current_type
)
745 tci
->multiple_types_encountered
= true;
746 tci
->known_current_type
= type
;
747 tci
->type_maybe_changed
= true;
754 /* See if ARG is PARAM_DECl describing instance passed by pointer
755 or reference in FUNCTION. Return false if the dynamic type may change
756 in between beggining of the function until CALL is invoked.
758 Generally functions are not allowed to change type of such instances,
759 but they call destructors. We assume that methods can not destroy the THIS
760 pointer. Also as a special cases, constructor and destructors may change
761 type of the THIS pointer. */
764 param_type_may_change_p (tree function
, tree arg
, gimple call
)
766 /* Pure functions can not do any changes on the dynamic type;
767 that require writting to memory. */
768 if (flags_from_decl_or_type (function
) & (ECF_PURE
| ECF_CONST
))
770 /* We need to check if we are within inlined consturctor
771 or destructor (ideally we would have way to check that the
772 inline cdtor is actually working on ARG, but we don't have
773 easy tie on this, so punt on all non-pure cdtors.
774 We may also record the types of cdtors and once we know type
775 of the instance match them.
777 Also code unification optimizations may merge calls from
778 different blocks making return values unreliable. So
779 do nothing during late optimization. */
780 if (DECL_STRUCT_FUNCTION (function
)->after_inlining
)
782 if (TREE_CODE (arg
) == SSA_NAME
783 && SSA_NAME_IS_DEFAULT_DEF (arg
)
784 && TREE_CODE (SSA_NAME_VAR (arg
)) == PARM_DECL
)
786 /* Normal (non-THIS) argument. */
787 if ((SSA_NAME_VAR (arg
) != DECL_ARGUMENTS (function
)
788 || TREE_CODE (TREE_TYPE (function
)) != METHOD_TYPE
)
789 /* THIS pointer of an method - here we we want to watch constructors
790 and destructors as those definitely may change the dynamic
792 || (TREE_CODE (TREE_TYPE (function
)) == METHOD_TYPE
793 && !DECL_CXX_CONSTRUCTOR_P (function
)
794 && !DECL_CXX_DESTRUCTOR_P (function
)
795 && (SSA_NAME_VAR (arg
) == DECL_ARGUMENTS (function
))))
797 /* Walk the inline stack and watch out for ctors/dtors. */
798 for (tree block
= gimple_block (call
); block
&& TREE_CODE (block
) == BLOCK
;
799 block
= BLOCK_SUPERCONTEXT (block
))
800 if (BLOCK_ABSTRACT_ORIGIN (block
)
801 && TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block
)) == FUNCTION_DECL
)
803 tree fn
= BLOCK_ABSTRACT_ORIGIN (block
);
805 if (flags_from_decl_or_type (fn
) & (ECF_PURE
| ECF_CONST
))
807 if (TREE_CODE (TREE_TYPE (fn
)) == METHOD_TYPE
808 && (DECL_CXX_CONSTRUCTOR_P (fn
)
809 || DECL_CXX_DESTRUCTOR_P (fn
)))
818 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
819 callsite CALL) by looking for assignments to its virtual table pointer. If
820 it is, return true and fill in the jump function JFUNC with relevant type
821 information or set it to unknown. ARG is the object itself (not a pointer
822 to it, unless dereferenced). BASE is the base of the memory access as
823 returned by get_ref_base_and_extent, as is the offset.
825 This is helper function for detect_type_change and detect_type_change_ssa
826 that does the heavy work which is usually unnecesary. */
829 detect_type_change_from_memory_writes (tree arg
, tree base
, tree comp_type
,
830 gimple call
, struct ipa_jump_func
*jfunc
,
831 HOST_WIDE_INT offset
)
833 struct prop_type_change_info tci
;
835 bool entry_reached
= false;
837 gcc_checking_assert (DECL_P (arg
)
838 || TREE_CODE (arg
) == MEM_REF
839 || handled_component_p (arg
));
841 comp_type
= TYPE_MAIN_VARIANT (comp_type
);
843 /* Const calls cannot call virtual methods through VMT and so type changes do
845 if (!flag_devirtualize
|| !gimple_vuse (call
)
846 /* Be sure expected_type is polymorphic. */
848 || TREE_CODE (comp_type
) != RECORD_TYPE
849 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type
))
850 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type
))))
853 ao_ref_init (&ao
, arg
);
856 ao
.size
= POINTER_SIZE
;
857 ao
.max_size
= ao
.size
;
860 tci
.object
= get_base_address (arg
);
861 tci
.known_current_type
= NULL_TREE
;
862 tci
.type_maybe_changed
= false;
863 tci
.multiple_types_encountered
= false;
865 walk_aliased_vdefs (&ao
, gimple_vuse (call
), check_stmt_for_type_change
,
866 &tci
, NULL
, &entry_reached
);
867 if (!tci
.type_maybe_changed
)
870 if (!tci
.known_current_type
871 || tci
.multiple_types_encountered
873 /* When the walk reached function entry, it means that type
874 is set along some paths but not along others. */
876 jfunc
->type
= IPA_JF_UNKNOWN
;
878 ipa_set_jf_known_type (jfunc
, 0, tci
.known_current_type
, comp_type
);
883 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
884 If it is, return true and fill in the jump function JFUNC with relevant type
885 information or set it to unknown. ARG is the object itself (not a pointer
886 to it, unless dereferenced). BASE is the base of the memory access as
887 returned by get_ref_base_and_extent, as is the offset. */
890 detect_type_change (tree arg
, tree base
, tree comp_type
, gimple call
,
891 struct ipa_jump_func
*jfunc
, HOST_WIDE_INT offset
)
893 if (!flag_devirtualize
)
896 if (TREE_CODE (base
) == MEM_REF
897 && !param_type_may_change_p (current_function_decl
,
898 TREE_OPERAND (base
, 0),
901 return detect_type_change_from_memory_writes (arg
, base
, comp_type
,
902 call
, jfunc
, offset
);
905 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
906 SSA name (its dereference will become the base and the offset is assumed to
910 detect_type_change_ssa (tree arg
, tree comp_type
,
911 gimple call
, struct ipa_jump_func
*jfunc
)
913 gcc_checking_assert (TREE_CODE (arg
) == SSA_NAME
);
914 if (!flag_devirtualize
915 || !POINTER_TYPE_P (TREE_TYPE (arg
)))
918 if (!param_type_may_change_p (current_function_decl
, arg
, call
))
921 arg
= build2 (MEM_REF
, ptr_type_node
, arg
,
922 build_int_cst (ptr_type_node
, 0));
924 return detect_type_change_from_memory_writes (arg
, arg
, comp_type
,
928 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
929 boolean variable pointed to by DATA. */
932 mark_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
935 bool *b
= (bool *) data
;
940 /* Return true if we have already walked so many statements in AA that we
941 should really just start giving up. */
944 aa_overwalked (struct func_body_info
*fbi
)
946 gcc_checking_assert (fbi
);
947 return fbi
->aa_walked
> (unsigned) PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS
);
950 /* Find the nearest valid aa status for parameter specified by INDEX that
953 static struct param_aa_status
*
954 find_dominating_aa_status (struct func_body_info
*fbi
, basic_block bb
,
959 bb
= get_immediate_dominator (CDI_DOMINATORS
, bb
);
962 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
963 if (!bi
->param_aa_statuses
.is_empty ()
964 && bi
->param_aa_statuses
[index
].valid
)
965 return &bi
->param_aa_statuses
[index
];
969 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
970 structures and/or intialize the result with a dominating description as
973 static struct param_aa_status
*
974 parm_bb_aa_status_for_bb (struct func_body_info
*fbi
, basic_block bb
,
977 gcc_checking_assert (fbi
);
978 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
979 if (bi
->param_aa_statuses
.is_empty ())
980 bi
->param_aa_statuses
.safe_grow_cleared (fbi
->param_count
);
981 struct param_aa_status
*paa
= &bi
->param_aa_statuses
[index
];
984 gcc_checking_assert (!paa
->parm_modified
985 && !paa
->ref_modified
986 && !paa
->pt_modified
);
987 struct param_aa_status
*dom_paa
;
988 dom_paa
= find_dominating_aa_status (fbi
, bb
, index
);
998 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
999 a value known not to be modified in this function before reaching the
1000 statement STMT. FBI holds information about the function we have so far
1001 gathered but do not survive the summary building stage. */
1004 parm_preserved_before_stmt_p (struct func_body_info
*fbi
, int index
,
1005 gimple stmt
, tree parm_load
)
1007 struct param_aa_status
*paa
;
1008 bool modified
= false;
1011 /* FIXME: FBI can be NULL if we are being called from outside
1012 ipa_node_analysis or ipcp_transform_function, which currently happens
1013 during inlining analysis. It would be great to extend fbi's lifetime and
1014 always have it. Currently, we are just not afraid of too much walking in
1018 if (aa_overwalked (fbi
))
1020 paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (stmt
), index
);
1021 if (paa
->parm_modified
)
1027 gcc_checking_assert (gimple_vuse (stmt
) != NULL_TREE
);
1028 ao_ref_init (&refd
, parm_load
);
1029 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), mark_modified
,
1032 fbi
->aa_walked
+= walked
;
1033 if (paa
&& modified
)
1034 paa
->parm_modified
= true;
1038 /* If STMT is an assignment that loads a value from an parameter declaration,
1039 return the index of the parameter in ipa_node_params which has not been
1040 modified. Otherwise return -1. */
1043 load_from_unmodified_param (struct func_body_info
*fbi
,
1044 vec
<ipa_param_descriptor
> descriptors
,
1050 if (!gimple_assign_single_p (stmt
))
1053 op1
= gimple_assign_rhs1 (stmt
);
1054 if (TREE_CODE (op1
) != PARM_DECL
)
1057 index
= ipa_get_param_decl_index_1 (descriptors
, op1
);
1059 || !parm_preserved_before_stmt_p (fbi
, index
, stmt
, op1
))
1065 /* Return true if memory reference REF (which must be a load through parameter
1066 with INDEX) loads data that are known to be unmodified in this function
1067 before reaching statement STMT. */
1070 parm_ref_data_preserved_p (struct func_body_info
*fbi
,
1071 int index
, gimple stmt
, tree ref
)
1073 struct param_aa_status
*paa
;
1074 bool modified
= false;
1077 /* FIXME: FBI can be NULL if we are being called from outside
1078 ipa_node_analysis or ipcp_transform_function, which currently happens
1079 during inlining analysis. It would be great to extend fbi's lifetime and
1080 always have it. Currently, we are just not afraid of too much walking in
1084 if (aa_overwalked (fbi
))
1086 paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (stmt
), index
);
1087 if (paa
->ref_modified
)
1093 gcc_checking_assert (gimple_vuse (stmt
));
1094 ao_ref_init (&refd
, ref
);
1095 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), mark_modified
,
1098 fbi
->aa_walked
+= walked
;
1099 if (paa
&& modified
)
1100 paa
->ref_modified
= true;
1104 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
1105 is known to be unmodified in this function before reaching call statement
1106 CALL into which it is passed. FBI describes the function body. */
1109 parm_ref_data_pass_through_p (struct func_body_info
*fbi
, int index
,
1110 gimple call
, tree parm
)
1112 bool modified
= false;
1115 /* It's unnecessary to calculate anything about memory contnets for a const
1116 function because it is not goin to use it. But do not cache the result
1117 either. Also, no such calculations for non-pointers. */
1118 if (!gimple_vuse (call
)
1119 || !POINTER_TYPE_P (TREE_TYPE (parm
))
1120 || aa_overwalked (fbi
))
1123 struct param_aa_status
*paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (call
),
1125 if (paa
->pt_modified
)
1128 ao_ref_init_from_ptr_and_size (&refd
, parm
, NULL_TREE
);
1129 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (call
), mark_modified
,
1131 fbi
->aa_walked
+= walked
;
1133 paa
->pt_modified
= true;
1137 /* Return true if we can prove that OP is a memory reference loading unmodified
1138 data from an aggregate passed as a parameter and if the aggregate is passed
1139 by reference, that the alias type of the load corresponds to the type of the
1140 formal parameter (so that we can rely on this type for TBAA in callers).
1141 INFO and PARMS_AINFO describe parameters of the current function (but the
1142 latter can be NULL), STMT is the load statement. If function returns true,
1143 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1144 within the aggregate and whether it is a load from a value passed by
1145 reference respectively. */
1148 ipa_load_from_parm_agg_1 (struct func_body_info
*fbi
,
1149 vec
<ipa_param_descriptor
> descriptors
,
1150 gimple stmt
, tree op
, int *index_p
,
1151 HOST_WIDE_INT
*offset_p
, HOST_WIDE_INT
*size_p
,
1155 HOST_WIDE_INT size
, max_size
;
1156 tree base
= get_ref_base_and_extent (op
, offset_p
, &size
, &max_size
);
1158 if (max_size
== -1 || max_size
!= size
|| *offset_p
< 0)
1163 int index
= ipa_get_param_decl_index_1 (descriptors
, base
);
1165 && parm_preserved_before_stmt_p (fbi
, index
, stmt
, op
))
1176 if (TREE_CODE (base
) != MEM_REF
1177 || TREE_CODE (TREE_OPERAND (base
, 0)) != SSA_NAME
1178 || !integer_zerop (TREE_OPERAND (base
, 1)))
1181 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base
, 0)))
1183 tree parm
= SSA_NAME_VAR (TREE_OPERAND (base
, 0));
1184 index
= ipa_get_param_decl_index_1 (descriptors
, parm
);
1188 /* This branch catches situations where a pointer parameter is not a
1189 gimple register, for example:
1191 void hip7(S*) (struct S * p)
1193 void (*<T2e4>) (struct S *) D.1867;
1198 D.1867_2 = p.1_1->f;
1203 gimple def
= SSA_NAME_DEF_STMT (TREE_OPERAND (base
, 0));
1204 index
= load_from_unmodified_param (fbi
, descriptors
, def
);
1208 && parm_ref_data_preserved_p (fbi
, index
, stmt
, op
))
1219 /* Just like the previous function, just without the param_analysis_info
1220 pointer, for users outside of this file. */
1223 ipa_load_from_parm_agg (struct ipa_node_params
*info
, gimple stmt
,
1224 tree op
, int *index_p
, HOST_WIDE_INT
*offset_p
,
1227 return ipa_load_from_parm_agg_1 (NULL
, info
->descriptors
, stmt
, op
, index_p
,
1228 offset_p
, NULL
, by_ref_p
);
1231 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1232 of an assignment statement STMT, try to determine whether we are actually
1233 handling any of the following cases and construct an appropriate jump
1234 function into JFUNC if so:
1236 1) The passed value is loaded from a formal parameter which is not a gimple
1237 register (most probably because it is addressable, the value has to be
1238 scalar) and we can guarantee the value has not changed. This case can
1239 therefore be described by a simple pass-through jump function. For example:
1248 2) The passed value can be described by a simple arithmetic pass-through
1255 D.2064_4 = a.1(D) + 4;
1258 This case can also occur in combination of the previous one, e.g.:
1266 D.2064_4 = a.0_3 + 4;
1269 3) The passed value is an address of an object within another one (which
1270 also passed by reference). Such situations are described by an ancestor
1271 jump function and describe situations such as:
1273 B::foo() (struct B * const this)
1277 D.1845_2 = &this_1(D)->D.1748;
1280 INFO is the structure describing individual parameters access different
1281 stages of IPA optimizations. PARMS_AINFO contains the information that is
1282 only needed for intraprocedural analysis. */
1285 compute_complex_assign_jump_func (struct func_body_info
*fbi
,
1286 struct ipa_node_params
*info
,
1287 struct ipa_jump_func
*jfunc
,
1288 gimple call
, gimple stmt
, tree name
,
1291 HOST_WIDE_INT offset
, size
, max_size
;
1292 tree op1
, tc_ssa
, base
, ssa
;
1295 op1
= gimple_assign_rhs1 (stmt
);
1297 if (TREE_CODE (op1
) == SSA_NAME
)
1299 if (SSA_NAME_IS_DEFAULT_DEF (op1
))
1300 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (op1
));
1302 index
= load_from_unmodified_param (fbi
, info
->descriptors
,
1303 SSA_NAME_DEF_STMT (op1
));
1308 index
= load_from_unmodified_param (fbi
, info
->descriptors
, stmt
);
1309 tc_ssa
= gimple_assign_lhs (stmt
);
1314 tree op2
= gimple_assign_rhs2 (stmt
);
1318 if (!is_gimple_ip_invariant (op2
)
1319 || (TREE_CODE_CLASS (gimple_expr_code (stmt
)) != tcc_comparison
1320 && !useless_type_conversion_p (TREE_TYPE (name
),
1324 ipa_set_jf_arith_pass_through (jfunc
, index
, op2
,
1325 gimple_assign_rhs_code (stmt
));
1327 else if (gimple_assign_single_p (stmt
))
1329 bool agg_p
= parm_ref_data_pass_through_p (fbi
, index
, call
, tc_ssa
);
1330 bool type_p
= false;
1332 if (param_type
&& POINTER_TYPE_P (param_type
))
1333 type_p
= !detect_type_change_ssa (tc_ssa
, TREE_TYPE (param_type
),
1335 if (type_p
|| jfunc
->type
== IPA_JF_UNKNOWN
)
1336 ipa_set_jf_simple_pass_through (jfunc
, index
, agg_p
, type_p
);
1341 if (TREE_CODE (op1
) != ADDR_EXPR
)
1343 op1
= TREE_OPERAND (op1
, 0);
1344 if (TREE_CODE (TREE_TYPE (op1
)) != RECORD_TYPE
)
1346 base
= get_ref_base_and_extent (op1
, &offset
, &size
, &max_size
);
1347 if (TREE_CODE (base
) != MEM_REF
1348 /* If this is a varying address, punt. */
1350 || max_size
!= size
)
1352 offset
+= mem_ref_offset (base
).to_short_addr () * BITS_PER_UNIT
;
1353 ssa
= TREE_OPERAND (base
, 0);
1354 if (TREE_CODE (ssa
) != SSA_NAME
1355 || !SSA_NAME_IS_DEFAULT_DEF (ssa
)
1359 /* Dynamic types are changed in constructors and destructors. */
1360 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (ssa
));
1361 if (index
>= 0 && param_type
&& POINTER_TYPE_P (param_type
))
1363 bool type_p
= (contains_polymorphic_type_p (TREE_TYPE (param_type
))
1364 && !detect_type_change (op1
, base
, TREE_TYPE (param_type
),
1365 call
, jfunc
, offset
));
1366 if (type_p
|| jfunc
->type
== IPA_JF_UNKNOWN
)
1367 ipa_set_ancestor_jf (jfunc
, offset
,
1368 type_p
? TREE_TYPE (param_type
) : NULL
, index
,
1369 parm_ref_data_pass_through_p (fbi
, index
,
1370 call
, ssa
), type_p
);
1374 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1377 iftmp.1_3 = &obj_2(D)->D.1762;
1379 The base of the MEM_REF must be a default definition SSA NAME of a
1380 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1381 whole MEM_REF expression is returned and the offset calculated from any
1382 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1383 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1386 get_ancestor_addr_info (gimple assign
, tree
*obj_p
, HOST_WIDE_INT
*offset
)
1388 HOST_WIDE_INT size
, max_size
;
1389 tree expr
, parm
, obj
;
1391 if (!gimple_assign_single_p (assign
))
1393 expr
= gimple_assign_rhs1 (assign
);
1395 if (TREE_CODE (expr
) != ADDR_EXPR
)
1397 expr
= TREE_OPERAND (expr
, 0);
1399 expr
= get_ref_base_and_extent (expr
, offset
, &size
, &max_size
);
1401 if (TREE_CODE (expr
) != MEM_REF
1402 /* If this is a varying address, punt. */
1407 parm
= TREE_OPERAND (expr
, 0);
1408 if (TREE_CODE (parm
) != SSA_NAME
1409 || !SSA_NAME_IS_DEFAULT_DEF (parm
)
1410 || TREE_CODE (SSA_NAME_VAR (parm
)) != PARM_DECL
)
1413 *offset
+= mem_ref_offset (expr
).to_short_addr () * BITS_PER_UNIT
;
1419 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1420 statement PHI, try to find out whether NAME is in fact a
1421 multiple-inheritance typecast from a descendant into an ancestor of a formal
1422 parameter and thus can be described by an ancestor jump function and if so,
1423 write the appropriate function into JFUNC.
1425 Essentially we want to match the following pattern:
1433 iftmp.1_3 = &obj_2(D)->D.1762;
1436 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1437 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1441 compute_complex_ancestor_jump_func (struct func_body_info
*fbi
,
1442 struct ipa_node_params
*info
,
1443 struct ipa_jump_func
*jfunc
,
1444 gimple call
, gimple phi
, tree param_type
)
1446 HOST_WIDE_INT offset
;
1447 gimple assign
, cond
;
1448 basic_block phi_bb
, assign_bb
, cond_bb
;
1449 tree tmp
, parm
, expr
, obj
;
1452 if (gimple_phi_num_args (phi
) != 2)
1455 if (integer_zerop (PHI_ARG_DEF (phi
, 1)))
1456 tmp
= PHI_ARG_DEF (phi
, 0);
1457 else if (integer_zerop (PHI_ARG_DEF (phi
, 0)))
1458 tmp
= PHI_ARG_DEF (phi
, 1);
1461 if (TREE_CODE (tmp
) != SSA_NAME
1462 || SSA_NAME_IS_DEFAULT_DEF (tmp
)
1463 || !POINTER_TYPE_P (TREE_TYPE (tmp
))
1464 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp
))) != RECORD_TYPE
)
1467 assign
= SSA_NAME_DEF_STMT (tmp
);
1468 assign_bb
= gimple_bb (assign
);
1469 if (!single_pred_p (assign_bb
))
1471 expr
= get_ancestor_addr_info (assign
, &obj
, &offset
);
1474 parm
= TREE_OPERAND (expr
, 0);
1475 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (parm
));
1479 cond_bb
= single_pred (assign_bb
);
1480 cond
= last_stmt (cond_bb
);
1482 || gimple_code (cond
) != GIMPLE_COND
1483 || gimple_cond_code (cond
) != NE_EXPR
1484 || gimple_cond_lhs (cond
) != parm
1485 || !integer_zerop (gimple_cond_rhs (cond
)))
1488 phi_bb
= gimple_bb (phi
);
1489 for (i
= 0; i
< 2; i
++)
1491 basic_block pred
= EDGE_PRED (phi_bb
, i
)->src
;
1492 if (pred
!= assign_bb
&& pred
!= cond_bb
)
1496 bool type_p
= false;
1497 if (param_type
&& POINTER_TYPE_P (param_type
)
1498 && contains_polymorphic_type_p (TREE_TYPE (param_type
)))
1499 type_p
= !detect_type_change (obj
, expr
, TREE_TYPE (param_type
),
1500 call
, jfunc
, offset
);
1501 if (type_p
|| jfunc
->type
== IPA_JF_UNKNOWN
)
1502 ipa_set_ancestor_jf (jfunc
, offset
, type_p
? TREE_TYPE (param_type
) : NULL
,
1504 parm_ref_data_pass_through_p (fbi
, index
, call
, parm
),
1508 /* Given OP which is passed as an actual argument to a called function,
1509 determine if it is possible to construct a KNOWN_TYPE jump function for it
1510 and if so, create one and store it to JFUNC.
1511 EXPECTED_TYPE represents a type the argument should be in */
1514 compute_known_type_jump_func (tree op
, struct ipa_jump_func
*jfunc
,
1515 gimple call
, tree expected_type
)
1517 HOST_WIDE_INT offset
, size
, max_size
;
1520 if (!flag_devirtualize
1521 || TREE_CODE (op
) != ADDR_EXPR
1522 || !contains_polymorphic_type_p (TREE_TYPE (TREE_TYPE (op
)))
1523 /* Be sure expected_type is polymorphic. */
1525 || !contains_polymorphic_type_p (expected_type
))
1528 op
= TREE_OPERAND (op
, 0);
1529 base
= get_ref_base_and_extent (op
, &offset
, &size
, &max_size
);
1533 || !contains_polymorphic_type_p (TREE_TYPE (base
)))
1536 if (decl_maybe_in_construction_p (base
, TREE_TYPE (base
),
1537 call
, current_function_decl
)
1538 /* Even if the var seems to be in construction by inline call stack,
1539 we may work out the actual type by walking memory writes. */
1540 && (is_global_var (base
)
1541 || detect_type_change (op
, base
, expected_type
, call
, jfunc
, offset
)))
1544 ipa_set_jf_known_type (jfunc
, offset
, TREE_TYPE (base
),
1548 /* Inspect the given TYPE and return true iff it has the same structure (the
1549 same number of fields of the same types) as a C++ member pointer. If
1550 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1551 corresponding fields there. */
1554 type_like_member_ptr_p (tree type
, tree
*method_ptr
, tree
*delta
)
1558 if (TREE_CODE (type
) != RECORD_TYPE
)
1561 fld
= TYPE_FIELDS (type
);
1562 if (!fld
|| !POINTER_TYPE_P (TREE_TYPE (fld
))
1563 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld
))) != METHOD_TYPE
1564 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
1570 fld
= DECL_CHAIN (fld
);
1571 if (!fld
|| INTEGRAL_TYPE_P (fld
)
1572 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
1577 if (DECL_CHAIN (fld
))
1583 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1584 return the rhs of its defining statement. Otherwise return RHS as it
1588 get_ssa_def_if_simple_copy (tree rhs
)
1590 while (TREE_CODE (rhs
) == SSA_NAME
&& !SSA_NAME_IS_DEFAULT_DEF (rhs
))
1592 gimple def_stmt
= SSA_NAME_DEF_STMT (rhs
);
1594 if (gimple_assign_single_p (def_stmt
))
1595 rhs
= gimple_assign_rhs1 (def_stmt
);
1602 /* Simple linked list, describing known contents of an aggregate beforere
1605 struct ipa_known_agg_contents_list
1607 /* Offset and size of the described part of the aggregate. */
1608 HOST_WIDE_INT offset
, size
;
1609 /* Known constant value or NULL if the contents is known to be unknown. */
1611 /* Pointer to the next structure in the list. */
1612 struct ipa_known_agg_contents_list
*next
;
1615 /* Find the proper place in linked list of ipa_known_agg_contents_list
1616 structures where to put a new one with the given LHS_OFFSET and LHS_SIZE,
1617 unless there is a partial overlap, in which case return NULL, or such
1618 element is already there, in which case set *ALREADY_THERE to true. */
1620 static struct ipa_known_agg_contents_list
**
1621 get_place_in_agg_contents_list (struct ipa_known_agg_contents_list
**list
,
1622 HOST_WIDE_INT lhs_offset
,
1623 HOST_WIDE_INT lhs_size
,
1624 bool *already_there
)
1626 struct ipa_known_agg_contents_list
**p
= list
;
1627 while (*p
&& (*p
)->offset
< lhs_offset
)
1629 if ((*p
)->offset
+ (*p
)->size
> lhs_offset
)
1634 if (*p
&& (*p
)->offset
< lhs_offset
+ lhs_size
)
1636 if ((*p
)->offset
== lhs_offset
&& (*p
)->size
== lhs_size
)
1637 /* We already know this value is subsequently overwritten with
1639 *already_there
= true;
1641 /* Otherwise this is a partial overlap which we cannot
1648 /* Build aggregate jump function from LIST, assuming there are exactly
1649 CONST_COUNT constant entries there and that th offset of the passed argument
1650 is ARG_OFFSET and store it into JFUNC. */
1653 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list
*list
,
1654 int const_count
, HOST_WIDE_INT arg_offset
,
1655 struct ipa_jump_func
*jfunc
)
1657 vec_alloc (jfunc
->agg
.items
, const_count
);
1662 struct ipa_agg_jf_item item
;
1663 item
.offset
= list
->offset
- arg_offset
;
1664 gcc_assert ((item
.offset
% BITS_PER_UNIT
) == 0);
1665 item
.value
= unshare_expr_without_location (list
->constant
);
1666 jfunc
->agg
.items
->quick_push (item
);
1672 /* Traverse statements from CALL backwards, scanning whether an aggregate given
1673 in ARG is filled in with constant values. ARG can either be an aggregate
1674 expression or a pointer to an aggregate. ARG_TYPE is the type of the
1675 aggregate. JFUNC is the jump function into which the constants are
1676 subsequently stored. */
1679 determine_locally_known_aggregate_parts (gimple call
, tree arg
, tree arg_type
,
1680 struct ipa_jump_func
*jfunc
)
1682 struct ipa_known_agg_contents_list
*list
= NULL
;
1683 int item_count
= 0, const_count
= 0;
1684 HOST_WIDE_INT arg_offset
, arg_size
;
1685 gimple_stmt_iterator gsi
;
1687 bool check_ref
, by_ref
;
1690 /* The function operates in three stages. First, we prepare check_ref, r,
1691 arg_base and arg_offset based on what is actually passed as an actual
1694 if (POINTER_TYPE_P (arg_type
))
1697 if (TREE_CODE (arg
) == SSA_NAME
)
1700 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type
))))
1705 type_size
= TYPE_SIZE (TREE_TYPE (arg_type
));
1706 arg_size
= tree_to_uhwi (type_size
);
1707 ao_ref_init_from_ptr_and_size (&r
, arg_base
, NULL_TREE
);
1709 else if (TREE_CODE (arg
) == ADDR_EXPR
)
1711 HOST_WIDE_INT arg_max_size
;
1713 arg
= TREE_OPERAND (arg
, 0);
1714 arg_base
= get_ref_base_and_extent (arg
, &arg_offset
, &arg_size
,
1716 if (arg_max_size
== -1
1717 || arg_max_size
!= arg_size
1720 if (DECL_P (arg_base
))
1723 ao_ref_init (&r
, arg_base
);
1733 HOST_WIDE_INT arg_max_size
;
1735 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg
)));
1739 arg_base
= get_ref_base_and_extent (arg
, &arg_offset
, &arg_size
,
1741 if (arg_max_size
== -1
1742 || arg_max_size
!= arg_size
1746 ao_ref_init (&r
, arg
);
1749 /* Second stage walks back the BB, looks at individual statements and as long
1750 as it is confident of how the statements affect contents of the
1751 aggregates, it builds a sorted linked list of ipa_agg_jf_list structures
1753 gsi
= gsi_for_stmt (call
);
1755 for (; !gsi_end_p (gsi
); gsi_prev (&gsi
))
1757 struct ipa_known_agg_contents_list
*n
, **p
;
1758 gimple stmt
= gsi_stmt (gsi
);
1759 HOST_WIDE_INT lhs_offset
, lhs_size
, lhs_max_size
;
1760 tree lhs
, rhs
, lhs_base
;
1762 if (!stmt_may_clobber_ref_p_1 (stmt
, &r
))
1764 if (!gimple_assign_single_p (stmt
))
1767 lhs
= gimple_assign_lhs (stmt
);
1768 rhs
= gimple_assign_rhs1 (stmt
);
1769 if (!is_gimple_reg_type (TREE_TYPE (rhs
))
1770 || TREE_CODE (lhs
) == BIT_FIELD_REF
1771 || contains_bitfld_component_ref_p (lhs
))
1774 lhs_base
= get_ref_base_and_extent (lhs
, &lhs_offset
, &lhs_size
,
1776 if (lhs_max_size
== -1
1777 || lhs_max_size
!= lhs_size
)
1782 if (TREE_CODE (lhs_base
) != MEM_REF
1783 || TREE_OPERAND (lhs_base
, 0) != arg_base
1784 || !integer_zerop (TREE_OPERAND (lhs_base
, 1)))
1787 else if (lhs_base
!= arg_base
)
1789 if (DECL_P (lhs_base
))
1795 bool already_there
= false;
1796 p
= get_place_in_agg_contents_list (&list
, lhs_offset
, lhs_size
,
1803 rhs
= get_ssa_def_if_simple_copy (rhs
);
1804 n
= XALLOCA (struct ipa_known_agg_contents_list
);
1806 n
->offset
= lhs_offset
;
1807 if (is_gimple_ip_invariant (rhs
))
1813 n
->constant
= NULL_TREE
;
1818 if (const_count
== PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS
)
1819 || item_count
== 2 * PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS
))
1823 /* Third stage just goes over the list and creates an appropriate vector of
1824 ipa_agg_jf_item structures out of it, of sourse only if there are
1825 any known constants to begin with. */
1829 jfunc
->agg
.by_ref
= by_ref
;
1830 build_agg_jump_func_from_list (list
, const_count
, arg_offset
, jfunc
);
1835 ipa_get_callee_param_type (struct cgraph_edge
*e
, int i
)
1838 tree type
= (e
->callee
1839 ? TREE_TYPE (e
->callee
->decl
)
1840 : gimple_call_fntype (e
->call_stmt
));
1841 tree t
= TYPE_ARG_TYPES (type
);
1843 for (n
= 0; n
< i
; n
++)
1850 return TREE_VALUE (t
);
1853 t
= DECL_ARGUMENTS (e
->callee
->decl
);
1854 for (n
= 0; n
< i
; n
++)
1861 return TREE_TYPE (t
);
1865 /* Compute jump function for all arguments of callsite CS and insert the
1866 information in the jump_functions array in the ipa_edge_args corresponding
1867 to this callsite. */
1870 ipa_compute_jump_functions_for_edge (struct func_body_info
*fbi
,
1871 struct cgraph_edge
*cs
)
1873 struct ipa_node_params
*info
= IPA_NODE_REF (cs
->caller
);
1874 struct ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
1875 gimple call
= cs
->call_stmt
;
1876 int n
, arg_num
= gimple_call_num_args (call
);
1878 if (arg_num
== 0 || args
->jump_functions
)
1880 vec_safe_grow_cleared (args
->jump_functions
, arg_num
);
1882 if (gimple_call_internal_p (call
))
1884 if (ipa_func_spec_opts_forbid_analysis_p (cs
->caller
))
1887 for (n
= 0; n
< arg_num
; n
++)
1889 struct ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (args
, n
);
1890 tree arg
= gimple_call_arg (call
, n
);
1891 tree param_type
= ipa_get_callee_param_type (cs
, n
);
1893 if (is_gimple_ip_invariant (arg
))
1894 ipa_set_jf_constant (jfunc
, arg
, cs
);
1895 else if (!is_gimple_reg_type (TREE_TYPE (arg
))
1896 && TREE_CODE (arg
) == PARM_DECL
)
1898 int index
= ipa_get_param_decl_index (info
, arg
);
1900 gcc_assert (index
>=0);
1901 /* Aggregate passed by value, check for pass-through, otherwise we
1902 will attempt to fill in aggregate contents later in this
1904 if (parm_preserved_before_stmt_p (fbi
, index
, call
, arg
))
1906 ipa_set_jf_simple_pass_through (jfunc
, index
, false, false);
1910 else if (TREE_CODE (arg
) == SSA_NAME
)
1912 if (SSA_NAME_IS_DEFAULT_DEF (arg
))
1914 int index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (arg
));
1918 agg_p
= parm_ref_data_pass_through_p (fbi
, index
, call
, arg
);
1919 if (param_type
&& POINTER_TYPE_P (param_type
))
1920 type_p
= !detect_type_change_ssa (arg
, TREE_TYPE (param_type
),
1924 if (type_p
|| jfunc
->type
== IPA_JF_UNKNOWN
)
1925 ipa_set_jf_simple_pass_through (jfunc
, index
, agg_p
,
1931 gimple stmt
= SSA_NAME_DEF_STMT (arg
);
1932 if (is_gimple_assign (stmt
))
1933 compute_complex_assign_jump_func (fbi
, info
, jfunc
,
1934 call
, stmt
, arg
, param_type
);
1935 else if (gimple_code (stmt
) == GIMPLE_PHI
)
1936 compute_complex_ancestor_jump_func (fbi
, info
, jfunc
,
1937 call
, stmt
, param_type
);
1941 compute_known_type_jump_func (arg
, jfunc
, call
,
1943 && POINTER_TYPE_P (param_type
)
1944 ? TREE_TYPE (param_type
)
1947 /* If ARG is pointer, we can not use its type to determine the type of aggregate
1948 passed (because type conversions are ignored in gimple). Usually we can
1949 safely get type from function declaration, but in case of K&R prototypes or
1950 variadic functions we can try our luck with type of the pointer passed.
1951 TODO: Since we look for actual initialization of the memory object, we may better
1952 work out the type based on the memory stores we find. */
1954 param_type
= TREE_TYPE (arg
);
1956 if ((jfunc
->type
!= IPA_JF_PASS_THROUGH
1957 || !ipa_get_jf_pass_through_agg_preserved (jfunc
))
1958 && (jfunc
->type
!= IPA_JF_ANCESTOR
1959 || !ipa_get_jf_ancestor_agg_preserved (jfunc
))
1960 && (AGGREGATE_TYPE_P (TREE_TYPE (arg
))
1961 || POINTER_TYPE_P (param_type
)))
1962 determine_locally_known_aggregate_parts (call
, arg
, param_type
, jfunc
);
1966 /* Compute jump functions for all edges - both direct and indirect - outgoing
1970 ipa_compute_jump_functions_for_bb (struct func_body_info
*fbi
, basic_block bb
)
1972 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
1974 struct cgraph_edge
*cs
;
1976 FOR_EACH_VEC_ELT_REVERSE (bi
->cg_edges
, i
, cs
)
1978 struct cgraph_node
*callee
= cs
->callee
;
1982 callee
->ultimate_alias_target ();
1983 /* We do not need to bother analyzing calls to unknown functions
1984 unless they may become known during lto/whopr. */
1985 if (!callee
->definition
&& !flag_lto
)
1988 ipa_compute_jump_functions_for_edge (fbi
, cs
);
1992 /* If STMT looks like a statement loading a value from a member pointer formal
1993 parameter, return that parameter and store the offset of the field to
1994 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
1995 might be clobbered). If USE_DELTA, then we look for a use of the delta
1996 field rather than the pfn. */
1999 ipa_get_stmt_member_ptr_load_param (gimple stmt
, bool use_delta
,
2000 HOST_WIDE_INT
*offset_p
)
2002 tree rhs
, rec
, ref_field
, ref_offset
, fld
, ptr_field
, delta_field
;
2004 if (!gimple_assign_single_p (stmt
))
2007 rhs
= gimple_assign_rhs1 (stmt
);
2008 if (TREE_CODE (rhs
) == COMPONENT_REF
)
2010 ref_field
= TREE_OPERAND (rhs
, 1);
2011 rhs
= TREE_OPERAND (rhs
, 0);
2014 ref_field
= NULL_TREE
;
2015 if (TREE_CODE (rhs
) != MEM_REF
)
2017 rec
= TREE_OPERAND (rhs
, 0);
2018 if (TREE_CODE (rec
) != ADDR_EXPR
)
2020 rec
= TREE_OPERAND (rec
, 0);
2021 if (TREE_CODE (rec
) != PARM_DECL
2022 || !type_like_member_ptr_p (TREE_TYPE (rec
), &ptr_field
, &delta_field
))
2024 ref_offset
= TREE_OPERAND (rhs
, 1);
2031 *offset_p
= int_bit_position (fld
);
2035 if (integer_nonzerop (ref_offset
))
2037 return ref_field
== fld
? rec
: NULL_TREE
;
2040 return tree_int_cst_equal (byte_position (fld
), ref_offset
) ? rec
2044 /* Returns true iff T is an SSA_NAME defined by a statement. */
2047 ipa_is_ssa_with_stmt_def (tree t
)
2049 if (TREE_CODE (t
) == SSA_NAME
2050 && !SSA_NAME_IS_DEFAULT_DEF (t
))
2056 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2057 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2058 indirect call graph edge. */
2060 static struct cgraph_edge
*
2061 ipa_note_param_call (struct cgraph_node
*node
, int param_index
, gimple stmt
)
2063 struct cgraph_edge
*cs
;
2065 cs
= node
->get_edge (stmt
);
2066 cs
->indirect_info
->param_index
= param_index
;
2067 cs
->indirect_info
->agg_contents
= 0;
2068 cs
->indirect_info
->member_ptr
= 0;
2072 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2073 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2074 intermediate information about each formal parameter. Currently it checks
2075 whether the call calls a pointer that is a formal parameter and if so, the
2076 parameter is marked with the called flag and an indirect call graph edge
2077 describing the call is created. This is very simple for ordinary pointers
2078 represented in SSA but not-so-nice when it comes to member pointers. The
2079 ugly part of this function does nothing more than trying to match the
2080 pattern of such a call. An example of such a pattern is the gimple dump
2081 below, the call is on the last line:
2084 f$__delta_5 = f.__delta;
2085 f$__pfn_24 = f.__pfn;
2089 f$__delta_5 = MEM[(struct *)&f];
2090 f$__pfn_24 = MEM[(struct *)&f + 4B];
2092 and a few lines below:
2095 D.2496_3 = (int) f$__pfn_24;
2096 D.2497_4 = D.2496_3 & 1;
2103 D.2500_7 = (unsigned int) f$__delta_5;
2104 D.2501_8 = &S + D.2500_7;
2105 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2106 D.2503_10 = *D.2502_9;
2107 D.2504_12 = f$__pfn_24 + -1;
2108 D.2505_13 = (unsigned int) D.2504_12;
2109 D.2506_14 = D.2503_10 + D.2505_13;
2110 D.2507_15 = *D.2506_14;
2111 iftmp.11_16 = (String:: *) D.2507_15;
2114 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2115 D.2500_19 = (unsigned int) f$__delta_5;
2116 D.2508_20 = &S + D.2500_19;
2117 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2119 Such patterns are results of simple calls to a member pointer:
2121 int doprinting (int (MyString::* f)(int) const)
2123 MyString S ("somestring");
2128 Moreover, the function also looks for called pointers loaded from aggregates
2129 passed by value or reference. */
2132 ipa_analyze_indirect_call_uses (struct func_body_info
*fbi
, gimple call
,
2135 struct ipa_node_params
*info
= fbi
->info
;
2136 HOST_WIDE_INT offset
;
2139 if (SSA_NAME_IS_DEFAULT_DEF (target
))
2141 tree var
= SSA_NAME_VAR (target
);
2142 int index
= ipa_get_param_decl_index (info
, var
);
2144 ipa_note_param_call (fbi
->node
, index
, call
);
2149 gimple def
= SSA_NAME_DEF_STMT (target
);
2150 if (gimple_assign_single_p (def
)
2151 && ipa_load_from_parm_agg_1 (fbi
, info
->descriptors
, def
,
2152 gimple_assign_rhs1 (def
), &index
, &offset
,
2155 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
, call
);
2156 if (cs
->indirect_info
->offset
!= offset
)
2157 cs
->indirect_info
->outer_type
= NULL
;
2158 cs
->indirect_info
->offset
= offset
;
2159 cs
->indirect_info
->agg_contents
= 1;
2160 cs
->indirect_info
->by_ref
= by_ref
;
2164 /* Now we need to try to match the complex pattern of calling a member
2166 if (gimple_code (def
) != GIMPLE_PHI
2167 || gimple_phi_num_args (def
) != 2
2168 || !POINTER_TYPE_P (TREE_TYPE (target
))
2169 || TREE_CODE (TREE_TYPE (TREE_TYPE (target
))) != METHOD_TYPE
)
2172 /* First, we need to check whether one of these is a load from a member
2173 pointer that is a parameter to this function. */
2174 tree n1
= PHI_ARG_DEF (def
, 0);
2175 tree n2
= PHI_ARG_DEF (def
, 1);
2176 if (!ipa_is_ssa_with_stmt_def (n1
) || !ipa_is_ssa_with_stmt_def (n2
))
2178 gimple d1
= SSA_NAME_DEF_STMT (n1
);
2179 gimple d2
= SSA_NAME_DEF_STMT (n2
);
2182 basic_block bb
, virt_bb
;
2183 basic_block join
= gimple_bb (def
);
2184 if ((rec
= ipa_get_stmt_member_ptr_load_param (d1
, false, &offset
)))
2186 if (ipa_get_stmt_member_ptr_load_param (d2
, false, NULL
))
2189 bb
= EDGE_PRED (join
, 0)->src
;
2190 virt_bb
= gimple_bb (d2
);
2192 else if ((rec
= ipa_get_stmt_member_ptr_load_param (d2
, false, &offset
)))
2194 bb
= EDGE_PRED (join
, 1)->src
;
2195 virt_bb
= gimple_bb (d1
);
2200 /* Second, we need to check that the basic blocks are laid out in the way
2201 corresponding to the pattern. */
2203 if (!single_pred_p (virt_bb
) || !single_succ_p (virt_bb
)
2204 || single_pred (virt_bb
) != bb
2205 || single_succ (virt_bb
) != join
)
2208 /* Third, let's see that the branching is done depending on the least
2209 significant bit of the pfn. */
2211 gimple branch
= last_stmt (bb
);
2212 if (!branch
|| gimple_code (branch
) != GIMPLE_COND
)
2215 if ((gimple_cond_code (branch
) != NE_EXPR
2216 && gimple_cond_code (branch
) != EQ_EXPR
)
2217 || !integer_zerop (gimple_cond_rhs (branch
)))
2220 tree cond
= gimple_cond_lhs (branch
);
2221 if (!ipa_is_ssa_with_stmt_def (cond
))
2224 def
= SSA_NAME_DEF_STMT (cond
);
2225 if (!is_gimple_assign (def
)
2226 || gimple_assign_rhs_code (def
) != BIT_AND_EXPR
2227 || !integer_onep (gimple_assign_rhs2 (def
)))
2230 cond
= gimple_assign_rhs1 (def
);
2231 if (!ipa_is_ssa_with_stmt_def (cond
))
2234 def
= SSA_NAME_DEF_STMT (cond
);
2236 if (is_gimple_assign (def
)
2237 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def
)))
2239 cond
= gimple_assign_rhs1 (def
);
2240 if (!ipa_is_ssa_with_stmt_def (cond
))
2242 def
= SSA_NAME_DEF_STMT (cond
);
2246 rec2
= ipa_get_stmt_member_ptr_load_param (def
,
2247 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2248 == ptrmemfunc_vbit_in_delta
),
2253 index
= ipa_get_param_decl_index (info
, rec
);
2255 && parm_preserved_before_stmt_p (fbi
, index
, call
, rec
))
2257 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
, call
);
2258 if (cs
->indirect_info
->offset
!= offset
)
2259 cs
->indirect_info
->outer_type
= NULL
;
2260 cs
->indirect_info
->offset
= offset
;
2261 cs
->indirect_info
->agg_contents
= 1;
2262 cs
->indirect_info
->member_ptr
= 1;
2268 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2269 object referenced in the expression is a formal parameter of the caller
2270 FBI->node (described by FBI->info), create a call note for the
2274 ipa_analyze_virtual_call_uses (struct func_body_info
*fbi
,
2275 gimple call
, tree target
)
2277 tree obj
= OBJ_TYPE_REF_OBJECT (target
);
2279 HOST_WIDE_INT anc_offset
;
2281 if (!flag_devirtualize
)
2284 if (TREE_CODE (obj
) != SSA_NAME
)
2287 struct ipa_node_params
*info
= fbi
->info
;
2288 if (SSA_NAME_IS_DEFAULT_DEF (obj
))
2290 struct ipa_jump_func jfunc
;
2291 if (TREE_CODE (SSA_NAME_VAR (obj
)) != PARM_DECL
)
2295 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (obj
));
2296 gcc_assert (index
>= 0);
2297 if (detect_type_change_ssa (obj
, obj_type_ref_class (target
),
2303 struct ipa_jump_func jfunc
;
2304 gimple stmt
= SSA_NAME_DEF_STMT (obj
);
2307 expr
= get_ancestor_addr_info (stmt
, &obj
, &anc_offset
);
2310 index
= ipa_get_param_decl_index (info
,
2311 SSA_NAME_VAR (TREE_OPERAND (expr
, 0)));
2312 gcc_assert (index
>= 0);
2313 if (detect_type_change (obj
, expr
, obj_type_ref_class (target
),
2314 call
, &jfunc
, anc_offset
))
2318 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
, call
);
2319 struct cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
2320 ii
->offset
= anc_offset
;
2321 ii
->otr_token
= tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target
));
2322 ii
->otr_type
= obj_type_ref_class (target
);
2323 ii
->polymorphic
= 1;
2326 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2327 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2328 containing intermediate information about each formal parameter. */
2331 ipa_analyze_call_uses (struct func_body_info
*fbi
, gimple call
)
2333 tree target
= gimple_call_fn (call
);
2336 || (TREE_CODE (target
) != SSA_NAME
2337 && !virtual_method_call_p (target
)))
2340 struct cgraph_edge
*cs
= fbi
->node
->get_edge (call
);
2341 /* If we previously turned the call into a direct call, there is
2342 no need to analyze. */
2343 if (cs
&& !cs
->indirect_unknown_callee
)
2346 if (cs
->indirect_info
->polymorphic
)
2349 HOST_WIDE_INT otr_token
;
2351 tree target
= gimple_call_fn (call
);
2352 ipa_polymorphic_call_context
context (current_function_decl
,
2353 target
, call
, &instance
);
2355 otr_type
= obj_type_ref_class (target
);
2356 otr_token
= tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target
));
2358 if (context
.get_dynamic_type (instance
,
2359 OBJ_TYPE_REF_OBJECT (target
),
2361 && context
.offset
== cs
->indirect_info
->offset
)
2363 gcc_assert (TREE_CODE (otr_type
) == RECORD_TYPE
);
2364 cs
->indirect_info
->polymorphic
= true;
2365 cs
->indirect_info
->param_index
= -1;
2366 cs
->indirect_info
->otr_token
= otr_token
;
2367 cs
->indirect_info
->otr_type
= otr_type
;
2368 cs
->indirect_info
->outer_type
= context
.outer_type
;
2369 cs
->indirect_info
->speculative_outer_type
= context
.speculative_outer_type
;
2370 cs
->indirect_info
->offset
= context
.offset
;
2371 cs
->indirect_info
->speculative_offset
= context
.speculative_offset
;
2372 cs
->indirect_info
->maybe_in_construction
2373 = context
.maybe_in_construction
;
2374 cs
->indirect_info
->maybe_derived_type
= context
.maybe_derived_type
;
2375 cs
->indirect_info
->speculative_maybe_derived_type
2376 = context
.speculative_maybe_derived_type
;
2380 if (TREE_CODE (target
) == SSA_NAME
)
2381 ipa_analyze_indirect_call_uses (fbi
, call
, target
);
2382 else if (virtual_method_call_p (target
))
2383 ipa_analyze_virtual_call_uses (fbi
, call
, target
);
2387 /* Analyze the call statement STMT with respect to formal parameters (described
2388 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2389 formal parameters are called. */
2392 ipa_analyze_stmt_uses (struct func_body_info
*fbi
, gimple stmt
)
2394 if (is_gimple_call (stmt
))
2395 ipa_analyze_call_uses (fbi
, stmt
);
2398 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2399 If OP is a parameter declaration, mark it as used in the info structure
2403 visit_ref_for_mod_analysis (gimple
, tree op
, tree
, void *data
)
2405 struct ipa_node_params
*info
= (struct ipa_node_params
*) data
;
2407 op
= get_base_address (op
);
2409 && TREE_CODE (op
) == PARM_DECL
)
2411 int index
= ipa_get_param_decl_index (info
, op
);
2412 gcc_assert (index
>= 0);
2413 ipa_set_param_used (info
, index
, true);
2419 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2420 the findings in various structures of the associated ipa_node_params
2421 structure, such as parameter flags, notes etc. FBI holds various data about
2422 the function being analyzed. */
2425 ipa_analyze_params_uses_in_bb (struct func_body_info
*fbi
, basic_block bb
)
2427 gimple_stmt_iterator gsi
;
2428 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2430 gimple stmt
= gsi_stmt (gsi
);
2432 if (is_gimple_debug (stmt
))
2435 ipa_analyze_stmt_uses (fbi
, stmt
);
2436 walk_stmt_load_store_addr_ops (stmt
, fbi
->info
,
2437 visit_ref_for_mod_analysis
,
2438 visit_ref_for_mod_analysis
,
2439 visit_ref_for_mod_analysis
);
2441 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2442 walk_stmt_load_store_addr_ops (gsi_stmt (gsi
), fbi
->info
,
2443 visit_ref_for_mod_analysis
,
2444 visit_ref_for_mod_analysis
,
2445 visit_ref_for_mod_analysis
);
2448 /* Calculate controlled uses of parameters of NODE. */
2451 ipa_analyze_controlled_uses (struct cgraph_node
*node
)
2453 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
2455 for (int i
= 0; i
< ipa_get_param_count (info
); i
++)
2457 tree parm
= ipa_get_param (info
, i
);
2458 int controlled_uses
= 0;
2460 /* For SSA regs see if parameter is used. For non-SSA we compute
2461 the flag during modification analysis. */
2462 if (is_gimple_reg (parm
))
2464 tree ddef
= ssa_default_def (DECL_STRUCT_FUNCTION (node
->decl
),
2466 if (ddef
&& !has_zero_uses (ddef
))
2468 imm_use_iterator imm_iter
;
2469 use_operand_p use_p
;
2471 ipa_set_param_used (info
, i
, true);
2472 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, ddef
)
2473 if (!is_gimple_call (USE_STMT (use_p
)))
2475 if (!is_gimple_debug (USE_STMT (use_p
)))
2477 controlled_uses
= IPA_UNDESCRIBED_USE
;
2485 controlled_uses
= 0;
2488 controlled_uses
= IPA_UNDESCRIBED_USE
;
2489 ipa_set_controlled_uses (info
, i
, controlled_uses
);
2493 /* Free stuff in BI. */
2496 free_ipa_bb_info (struct ipa_bb_info
*bi
)
2498 bi
->cg_edges
.release ();
2499 bi
->param_aa_statuses
.release ();
2502 /* Dominator walker driving the analysis. */
2504 class analysis_dom_walker
: public dom_walker
2507 analysis_dom_walker (struct func_body_info
*fbi
)
2508 : dom_walker (CDI_DOMINATORS
), m_fbi (fbi
) {}
2510 virtual void before_dom_children (basic_block
);
2513 struct func_body_info
*m_fbi
;
2517 analysis_dom_walker::before_dom_children (basic_block bb
)
2519 ipa_analyze_params_uses_in_bb (m_fbi
, bb
);
2520 ipa_compute_jump_functions_for_bb (m_fbi
, bb
);
2523 /* Initialize the array describing properties of of formal parameters
2524 of NODE, analyze their uses and compute jump functions associated
2525 with actual arguments of calls from within NODE. */
2528 ipa_analyze_node (struct cgraph_node
*node
)
2530 struct func_body_info fbi
;
2531 struct ipa_node_params
*info
;
2533 ipa_check_create_node_params ();
2534 ipa_check_create_edge_args ();
2535 info
= IPA_NODE_REF (node
);
2537 if (info
->analysis_done
)
2539 info
->analysis_done
= 1;
2541 if (ipa_func_spec_opts_forbid_analysis_p (node
))
2543 for (int i
= 0; i
< ipa_get_param_count (info
); i
++)
2545 ipa_set_param_used (info
, i
, true);
2546 ipa_set_controlled_uses (info
, i
, IPA_UNDESCRIBED_USE
);
2551 struct function
*func
= DECL_STRUCT_FUNCTION (node
->decl
);
2553 calculate_dominance_info (CDI_DOMINATORS
);
2554 ipa_initialize_node_params (node
);
2555 ipa_analyze_controlled_uses (node
);
2558 fbi
.info
= IPA_NODE_REF (node
);
2559 fbi
.bb_infos
= vNULL
;
2560 fbi
.bb_infos
.safe_grow_cleared (last_basic_block_for_fn (cfun
));
2561 fbi
.param_count
= ipa_get_param_count (info
);
2564 for (struct cgraph_edge
*cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
2566 ipa_bb_info
*bi
= ipa_get_bb_info (&fbi
, gimple_bb (cs
->call_stmt
));
2567 bi
->cg_edges
.safe_push (cs
);
2570 for (struct cgraph_edge
*cs
= node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
2572 ipa_bb_info
*bi
= ipa_get_bb_info (&fbi
, gimple_bb (cs
->call_stmt
));
2573 bi
->cg_edges
.safe_push (cs
);
2576 analysis_dom_walker (&fbi
).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
2579 struct ipa_bb_info
*bi
;
2580 FOR_EACH_VEC_ELT (fbi
.bb_infos
, i
, bi
)
2581 free_ipa_bb_info (bi
);
2582 fbi
.bb_infos
.release ();
2583 free_dominance_info (CDI_DOMINATORS
);
2587 /* Given a statement CALL which must be a GIMPLE_CALL calling an OBJ_TYPE_REF
2588 attempt a type-based devirtualization. If successful, return the
2589 target function declaration, otherwise return NULL. */
2592 ipa_intraprocedural_devirtualization (gimple call
)
2594 tree binfo
, token
, fndecl
;
2595 struct ipa_jump_func jfunc
;
2596 tree otr
= gimple_call_fn (call
);
2598 jfunc
.type
= IPA_JF_UNKNOWN
;
2599 compute_known_type_jump_func (OBJ_TYPE_REF_OBJECT (otr
), &jfunc
,
2600 call
, obj_type_ref_class (otr
));
2601 if (jfunc
.type
!= IPA_JF_KNOWN_TYPE
)
2603 binfo
= ipa_binfo_from_known_type_jfunc (&jfunc
);
2606 token
= OBJ_TYPE_REF_TOKEN (otr
);
2607 fndecl
= gimple_get_virt_method_for_binfo (tree_to_uhwi (token
),
2609 #ifdef ENABLE_CHECKING
2611 gcc_assert (possible_polymorphic_call_target_p
2612 (otr
, call
, cgraph_node::get (fndecl
)));
2617 /* Update the jump function DST when the call graph edge corresponding to SRC is
2618 is being inlined, knowing that DST is of type ancestor and src of known
2622 combine_known_type_and_ancestor_jfs (struct ipa_jump_func
*src
,
2623 struct ipa_jump_func
*dst
)
2625 HOST_WIDE_INT combined_offset
;
2628 if (!ipa_get_jf_ancestor_type_preserved (dst
))
2630 dst
->type
= IPA_JF_UNKNOWN
;
2634 combined_offset
= ipa_get_jf_known_type_offset (src
)
2635 + ipa_get_jf_ancestor_offset (dst
);
2636 combined_type
= ipa_get_jf_ancestor_type (dst
);
2638 ipa_set_jf_known_type (dst
, combined_offset
,
2639 ipa_get_jf_known_type_base_type (src
),
2643 /* Update the jump functions associated with call graph edge E when the call
2644 graph edge CS is being inlined, assuming that E->caller is already (possibly
2645 indirectly) inlined into CS->callee and that E has not been inlined. */
2648 update_jump_functions_after_inlining (struct cgraph_edge
*cs
,
2649 struct cgraph_edge
*e
)
2651 struct ipa_edge_args
*top
= IPA_EDGE_REF (cs
);
2652 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
2653 int count
= ipa_get_cs_argument_count (args
);
2656 for (i
= 0; i
< count
; i
++)
2658 struct ipa_jump_func
*dst
= ipa_get_ith_jump_func (args
, i
);
2660 if (dst
->type
== IPA_JF_ANCESTOR
)
2662 struct ipa_jump_func
*src
;
2663 int dst_fid
= dst
->value
.ancestor
.formal_id
;
2665 /* Variable number of arguments can cause havoc if we try to access
2666 one that does not exist in the inlined edge. So make sure we
2668 if (dst_fid
>= ipa_get_cs_argument_count (top
))
2670 dst
->type
= IPA_JF_UNKNOWN
;
2674 src
= ipa_get_ith_jump_func (top
, dst_fid
);
2677 && (dst
->value
.ancestor
.agg_preserved
|| !src
->agg
.by_ref
))
2679 struct ipa_agg_jf_item
*item
;
2682 /* Currently we do not produce clobber aggregate jump functions,
2683 replace with merging when we do. */
2684 gcc_assert (!dst
->agg
.items
);
2686 dst
->agg
.items
= vec_safe_copy (src
->agg
.items
);
2687 dst
->agg
.by_ref
= src
->agg
.by_ref
;
2688 FOR_EACH_VEC_SAFE_ELT (dst
->agg
.items
, j
, item
)
2689 item
->offset
-= dst
->value
.ancestor
.offset
;
2692 if (src
->type
== IPA_JF_KNOWN_TYPE
)
2693 combine_known_type_and_ancestor_jfs (src
, dst
);
2694 else if (src
->type
== IPA_JF_PASS_THROUGH
2695 && src
->value
.pass_through
.operation
== NOP_EXPR
)
2697 dst
->value
.ancestor
.formal_id
= src
->value
.pass_through
.formal_id
;
2698 dst
->value
.ancestor
.agg_preserved
&=
2699 src
->value
.pass_through
.agg_preserved
;
2700 dst
->value
.ancestor
.type_preserved
&=
2701 src
->value
.pass_through
.type_preserved
;
2703 else if (src
->type
== IPA_JF_ANCESTOR
)
2705 dst
->value
.ancestor
.formal_id
= src
->value
.ancestor
.formal_id
;
2706 dst
->value
.ancestor
.offset
+= src
->value
.ancestor
.offset
;
2707 dst
->value
.ancestor
.agg_preserved
&=
2708 src
->value
.ancestor
.agg_preserved
;
2709 dst
->value
.ancestor
.type_preserved
&=
2710 src
->value
.ancestor
.type_preserved
;
2713 dst
->type
= IPA_JF_UNKNOWN
;
2715 else if (dst
->type
== IPA_JF_PASS_THROUGH
)
2717 struct ipa_jump_func
*src
;
2718 /* We must check range due to calls with variable number of arguments
2719 and we cannot combine jump functions with operations. */
2720 if (dst
->value
.pass_through
.operation
== NOP_EXPR
2721 && (dst
->value
.pass_through
.formal_id
2722 < ipa_get_cs_argument_count (top
)))
2724 int dst_fid
= dst
->value
.pass_through
.formal_id
;
2725 src
= ipa_get_ith_jump_func (top
, dst_fid
);
2726 bool dst_agg_p
= ipa_get_jf_pass_through_agg_preserved (dst
);
2730 case IPA_JF_UNKNOWN
:
2731 dst
->type
= IPA_JF_UNKNOWN
;
2733 case IPA_JF_KNOWN_TYPE
:
2734 if (ipa_get_jf_pass_through_type_preserved (dst
))
2735 ipa_set_jf_known_type (dst
,
2736 ipa_get_jf_known_type_offset (src
),
2737 ipa_get_jf_known_type_base_type (src
),
2738 ipa_get_jf_known_type_component_type (src
));
2740 dst
->type
= IPA_JF_UNKNOWN
;
2743 ipa_set_jf_cst_copy (dst
, src
);
2746 case IPA_JF_PASS_THROUGH
:
2748 int formal_id
= ipa_get_jf_pass_through_formal_id (src
);
2749 enum tree_code operation
;
2750 operation
= ipa_get_jf_pass_through_operation (src
);
2752 if (operation
== NOP_EXPR
)
2756 && ipa_get_jf_pass_through_agg_preserved (src
);
2757 type_p
= ipa_get_jf_pass_through_type_preserved (src
)
2758 && ipa_get_jf_pass_through_type_preserved (dst
);
2759 ipa_set_jf_simple_pass_through (dst
, formal_id
,
2764 tree operand
= ipa_get_jf_pass_through_operand (src
);
2765 ipa_set_jf_arith_pass_through (dst
, formal_id
, operand
,
2770 case IPA_JF_ANCESTOR
:
2774 && ipa_get_jf_ancestor_agg_preserved (src
);
2775 type_p
= ipa_get_jf_ancestor_type_preserved (src
)
2776 && ipa_get_jf_pass_through_type_preserved (dst
);
2777 ipa_set_ancestor_jf (dst
,
2778 ipa_get_jf_ancestor_offset (src
),
2779 ipa_get_jf_ancestor_type (src
),
2780 ipa_get_jf_ancestor_formal_id (src
),
2789 && (dst_agg_p
|| !src
->agg
.by_ref
))
2791 /* Currently we do not produce clobber aggregate jump
2792 functions, replace with merging when we do. */
2793 gcc_assert (!dst
->agg
.items
);
2795 dst
->agg
.by_ref
= src
->agg
.by_ref
;
2796 dst
->agg
.items
= vec_safe_copy (src
->agg
.items
);
2800 dst
->type
= IPA_JF_UNKNOWN
;
2805 /* If TARGET is an addr_expr of a function declaration, make it the destination
2806 of an indirect edge IE and return the edge. Otherwise, return NULL. */
2808 struct cgraph_edge
*
2809 ipa_make_edge_direct_to_target (struct cgraph_edge
*ie
, tree target
)
2811 struct cgraph_node
*callee
;
2812 struct inline_edge_summary
*es
= inline_edge_summary (ie
);
2813 bool unreachable
= false;
2815 if (TREE_CODE (target
) == ADDR_EXPR
)
2816 target
= TREE_OPERAND (target
, 0);
2817 if (TREE_CODE (target
) != FUNCTION_DECL
)
2819 target
= canonicalize_constructor_val (target
, NULL
);
2820 if (!target
|| TREE_CODE (target
) != FUNCTION_DECL
)
2822 if (ie
->indirect_info
->member_ptr
)
2823 /* Member pointer call that goes through a VMT lookup. */
2826 if (dump_enabled_p ())
2828 location_t loc
= gimple_location_safe (ie
->call_stmt
);
2829 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, loc
,
2830 "discovered direct call to non-function in %s/%i, "
2831 "making it __builtin_unreachable\n",
2832 ie
->caller
->name (), ie
->caller
->order
);
2835 target
= builtin_decl_implicit (BUILT_IN_UNREACHABLE
);
2836 callee
= cgraph_node::get_create (target
);
2840 callee
= cgraph_node::get (target
);
2843 callee
= cgraph_node::get (target
);
2845 /* Because may-edges are not explicitely represented and vtable may be external,
2846 we may create the first reference to the object in the unit. */
2847 if (!callee
|| callee
->global
.inlined_to
)
2850 /* We are better to ensure we can refer to it.
2851 In the case of static functions we are out of luck, since we already
2852 removed its body. In the case of public functions we may or may
2853 not introduce the reference. */
2854 if (!canonicalize_constructor_val (target
, NULL
)
2855 || !TREE_PUBLIC (target
))
2858 fprintf (dump_file
, "ipa-prop: Discovered call to a known target "
2859 "(%s/%i -> %s/%i) but can not refer to it. Giving up.\n",
2860 xstrdup (ie
->caller
->name ()),
2862 xstrdup (ie
->callee
->name ()),
2866 callee
= cgraph_node::get_create (target
);
2869 if (!dbg_cnt (devirt
))
2872 ipa_check_create_node_params ();
2874 /* We can not make edges to inline clones. It is bug that someone removed
2875 the cgraph node too early. */
2876 gcc_assert (!callee
->global
.inlined_to
);
2878 if (dump_file
&& !unreachable
)
2880 fprintf (dump_file
, "ipa-prop: Discovered %s call to a known target "
2881 "(%s/%i -> %s/%i), for stmt ",
2882 ie
->indirect_info
->polymorphic
? "a virtual" : "an indirect",
2883 xstrdup (ie
->caller
->name ()),
2885 xstrdup (callee
->name ()),
2888 print_gimple_stmt (dump_file
, ie
->call_stmt
, 2, TDF_SLIM
);
2890 fprintf (dump_file
, "with uid %i\n", ie
->lto_stmt_uid
);
2892 if (dump_enabled_p ())
2894 location_t loc
= gimple_location_safe (ie
->call_stmt
);
2896 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, loc
,
2897 "converting indirect call in %s to direct call to %s\n",
2898 ie
->caller
->name (), callee
->name ());
2900 ie
= ie
->make_direct (callee
);
2901 es
= inline_edge_summary (ie
);
2902 es
->call_stmt_size
-= (eni_size_weights
.indirect_call_cost
2903 - eni_size_weights
.call_cost
);
2904 es
->call_stmt_time
-= (eni_time_weights
.indirect_call_cost
2905 - eni_time_weights
.call_cost
);
2910 /* Retrieve value from aggregate jump function AGG for the given OFFSET or
2911 return NULL if there is not any. BY_REF specifies whether the value has to
2912 be passed by reference or by value. */
2915 ipa_find_agg_cst_for_param (struct ipa_agg_jump_function
*agg
,
2916 HOST_WIDE_INT offset
, bool by_ref
)
2918 struct ipa_agg_jf_item
*item
;
2921 if (by_ref
!= agg
->by_ref
)
2924 FOR_EACH_VEC_SAFE_ELT (agg
->items
, i
, item
)
2925 if (item
->offset
== offset
)
2927 /* Currently we do not have clobber values, return NULL for them once
2929 gcc_checking_assert (is_gimple_ip_invariant (item
->value
));
2935 /* Remove a reference to SYMBOL from the list of references of a node given by
2936 reference description RDESC. Return true if the reference has been
2937 successfully found and removed. */
2940 remove_described_reference (symtab_node
*symbol
, struct ipa_cst_ref_desc
*rdesc
)
2942 struct ipa_ref
*to_del
;
2943 struct cgraph_edge
*origin
;
2948 to_del
= origin
->caller
->find_reference (symbol
, origin
->call_stmt
,
2949 origin
->lto_stmt_uid
);
2953 to_del
->remove_reference ();
2955 fprintf (dump_file
, "ipa-prop: Removed a reference from %s/%i to %s.\n",
2956 xstrdup (origin
->caller
->name ()),
2957 origin
->caller
->order
, xstrdup (symbol
->name ()));
2961 /* If JFUNC has a reference description with refcount different from
2962 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
2963 NULL. JFUNC must be a constant jump function. */
2965 static struct ipa_cst_ref_desc
*
2966 jfunc_rdesc_usable (struct ipa_jump_func
*jfunc
)
2968 struct ipa_cst_ref_desc
*rdesc
= ipa_get_jf_constant_rdesc (jfunc
);
2969 if (rdesc
&& rdesc
->refcount
!= IPA_UNDESCRIBED_USE
)
2975 /* If the value of constant jump function JFUNC is an address of a function
2976 declaration, return the associated call graph node. Otherwise return
2979 static cgraph_node
*
2980 cgraph_node_for_jfunc (struct ipa_jump_func
*jfunc
)
2982 gcc_checking_assert (jfunc
->type
== IPA_JF_CONST
);
2983 tree cst
= ipa_get_jf_constant (jfunc
);
2984 if (TREE_CODE (cst
) != ADDR_EXPR
2985 || TREE_CODE (TREE_OPERAND (cst
, 0)) != FUNCTION_DECL
)
2988 return cgraph_node::get (TREE_OPERAND (cst
, 0));
2992 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
2993 refcount and if it hits zero, remove reference to SYMBOL from the caller of
2994 the edge specified in the rdesc. Return false if either the symbol or the
2995 reference could not be found, otherwise return true. */
2998 try_decrement_rdesc_refcount (struct ipa_jump_func
*jfunc
)
3000 struct ipa_cst_ref_desc
*rdesc
;
3001 if (jfunc
->type
== IPA_JF_CONST
3002 && (rdesc
= jfunc_rdesc_usable (jfunc
))
3003 && --rdesc
->refcount
== 0)
3005 symtab_node
*symbol
= cgraph_node_for_jfunc (jfunc
);
3009 return remove_described_reference (symbol
, rdesc
);
3014 /* Try to find a destination for indirect edge IE that corresponds to a simple
3015 call or a call of a member function pointer and where the destination is a
3016 pointer formal parameter described by jump function JFUNC. If it can be
3017 determined, return the newly direct edge, otherwise return NULL.
3018 NEW_ROOT_INFO is the node info that JFUNC lattices are relative to. */
3020 static struct cgraph_edge
*
3021 try_make_edge_direct_simple_call (struct cgraph_edge
*ie
,
3022 struct ipa_jump_func
*jfunc
,
3023 struct ipa_node_params
*new_root_info
)
3025 struct cgraph_edge
*cs
;
3027 bool agg_contents
= ie
->indirect_info
->agg_contents
;
3029 if (ie
->indirect_info
->agg_contents
)
3030 target
= ipa_find_agg_cst_for_param (&jfunc
->agg
,
3031 ie
->indirect_info
->offset
,
3032 ie
->indirect_info
->by_ref
);
3034 target
= ipa_value_from_jfunc (new_root_info
, jfunc
);
3037 cs
= ipa_make_edge_direct_to_target (ie
, target
);
3039 if (cs
&& !agg_contents
)
3042 gcc_checking_assert (cs
->callee
3044 || jfunc
->type
!= IPA_JF_CONST
3045 || !cgraph_node_for_jfunc (jfunc
)
3046 || cs
->callee
== cgraph_node_for_jfunc (jfunc
)));
3047 ok
= try_decrement_rdesc_refcount (jfunc
);
3048 gcc_checking_assert (ok
);
3054 /* Return the target to be used in cases of impossible devirtualization. IE
3055 and target (the latter can be NULL) are dumped when dumping is enabled. */
3058 ipa_impossible_devirt_target (struct cgraph_edge
*ie
, tree target
)
3064 "Type inconsistent devirtualization: %s/%i->%s\n",
3065 ie
->caller
->name (), ie
->caller
->order
,
3066 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target
)));
3069 "No devirtualization target in %s/%i\n",
3070 ie
->caller
->name (), ie
->caller
->order
);
3072 tree new_target
= builtin_decl_implicit (BUILT_IN_UNREACHABLE
);
3073 cgraph_node::get_create (new_target
);
3077 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3078 call based on a formal parameter which is described by jump function JFUNC
3079 and if it can be determined, make it direct and return the direct edge.
3080 Otherwise, return NULL. NEW_ROOT_INFO is the node info that JFUNC lattices
3083 static struct cgraph_edge
*
3084 try_make_edge_direct_virtual_call (struct cgraph_edge
*ie
,
3085 struct ipa_jump_func
*jfunc
,
3086 struct ipa_node_params
*new_root_info
)
3090 if (!flag_devirtualize
)
3093 /* First try to do lookup via known virtual table pointer value. */
3094 if (!ie
->indirect_info
->by_ref
)
3097 unsigned HOST_WIDE_INT offset
;
3098 tree t
= ipa_find_agg_cst_for_param (&jfunc
->agg
,
3099 ie
->indirect_info
->offset
,
3101 if (t
&& vtable_pointer_value_to_vtable (t
, &vtable
, &offset
))
3103 target
= gimple_get_virt_method_for_vtable (ie
->indirect_info
->otr_token
,
3107 if ((TREE_CODE (TREE_TYPE (target
)) == FUNCTION_TYPE
3108 && DECL_FUNCTION_CODE (target
) == BUILT_IN_UNREACHABLE
)
3109 || !possible_polymorphic_call_target_p
3110 (ie
, cgraph_node::get (target
)))
3111 target
= ipa_impossible_devirt_target (ie
, target
);
3112 return ipa_make_edge_direct_to_target (ie
, target
);
3117 binfo
= ipa_value_from_jfunc (new_root_info
, jfunc
);
3122 if (TREE_CODE (binfo
) != TREE_BINFO
)
3124 ipa_polymorphic_call_context
context (binfo
,
3125 ie
->indirect_info
->otr_type
,
3126 ie
->indirect_info
->offset
);
3127 vec
<cgraph_node
*>targets
;
3130 targets
= possible_polymorphic_call_targets
3131 (ie
->indirect_info
->otr_type
,
3132 ie
->indirect_info
->otr_token
,
3134 if (!final
|| targets
.length () > 1)
3136 if (targets
.length () == 1)
3137 target
= targets
[0]->decl
;
3139 target
= ipa_impossible_devirt_target (ie
, NULL_TREE
);
3143 binfo
= get_binfo_at_offset (binfo
, ie
->indirect_info
->offset
,
3144 ie
->indirect_info
->otr_type
);
3146 target
= gimple_get_virt_method_for_binfo (ie
->indirect_info
->otr_token
,
3154 if (!possible_polymorphic_call_target_p (ie
, cgraph_node::get (target
)))
3155 target
= ipa_impossible_devirt_target (ie
, target
);
3156 return ipa_make_edge_direct_to_target (ie
, target
);
3162 /* Update the param called notes associated with NODE when CS is being inlined,
3163 assuming NODE is (potentially indirectly) inlined into CS->callee.
3164 Moreover, if the callee is discovered to be constant, create a new cgraph
3165 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
3166 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
3169 update_indirect_edges_after_inlining (struct cgraph_edge
*cs
,
3170 struct cgraph_node
*node
,
3171 vec
<cgraph_edge
*> *new_edges
)
3173 struct ipa_edge_args
*top
;
3174 struct cgraph_edge
*ie
, *next_ie
, *new_direct_edge
;
3175 struct ipa_node_params
*new_root_info
;
3178 ipa_check_create_edge_args ();
3179 top
= IPA_EDGE_REF (cs
);
3180 new_root_info
= IPA_NODE_REF (cs
->caller
->global
.inlined_to
3181 ? cs
->caller
->global
.inlined_to
3184 for (ie
= node
->indirect_calls
; ie
; ie
= next_ie
)
3186 struct cgraph_indirect_call_info
*ici
= ie
->indirect_info
;
3187 struct ipa_jump_func
*jfunc
;
3190 next_ie
= ie
->next_callee
;
3192 if (ici
->param_index
== -1)
3195 /* We must check range due to calls with variable number of arguments: */
3196 if (ici
->param_index
>= ipa_get_cs_argument_count (top
))
3198 ici
->param_index
= -1;
3202 param_index
= ici
->param_index
;
3203 jfunc
= ipa_get_ith_jump_func (top
, param_index
);
3205 if (!flag_indirect_inlining
)
3206 new_direct_edge
= NULL
;
3207 else if (ici
->polymorphic
)
3208 new_direct_edge
= try_make_edge_direct_virtual_call (ie
, jfunc
,
3211 new_direct_edge
= try_make_edge_direct_simple_call (ie
, jfunc
,
3213 /* If speculation was removed, then we need to do nothing. */
3214 if (new_direct_edge
&& new_direct_edge
!= ie
)
3216 new_direct_edge
->indirect_inlining_edge
= 1;
3217 top
= IPA_EDGE_REF (cs
);
3220 else if (new_direct_edge
)
3222 new_direct_edge
->indirect_inlining_edge
= 1;
3223 if (new_direct_edge
->call_stmt
)
3224 new_direct_edge
->call_stmt_cannot_inline_p
3225 = !gimple_check_call_matching_types (
3226 new_direct_edge
->call_stmt
,
3227 new_direct_edge
->callee
->decl
, false);
3230 new_edges
->safe_push (new_direct_edge
);
3233 top
= IPA_EDGE_REF (cs
);
3235 else if (jfunc
->type
== IPA_JF_PASS_THROUGH
3236 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
3238 if ((ici
->agg_contents
3239 && !ipa_get_jf_pass_through_agg_preserved (jfunc
))
3240 || (ici
->polymorphic
3241 && !ipa_get_jf_pass_through_type_preserved (jfunc
)))
3242 ici
->param_index
= -1;
3244 ici
->param_index
= ipa_get_jf_pass_through_formal_id (jfunc
);
3246 else if (jfunc
->type
== IPA_JF_ANCESTOR
)
3248 if ((ici
->agg_contents
3249 && !ipa_get_jf_ancestor_agg_preserved (jfunc
))
3250 || (ici
->polymorphic
3251 && !ipa_get_jf_ancestor_type_preserved (jfunc
)))
3252 ici
->param_index
= -1;
3255 ici
->param_index
= ipa_get_jf_ancestor_formal_id (jfunc
);
3256 if (ipa_get_jf_ancestor_offset (jfunc
))
3257 ici
->outer_type
= NULL
;
3258 ici
->offset
+= ipa_get_jf_ancestor_offset (jfunc
);
3262 /* Either we can find a destination for this edge now or never. */
3263 ici
->param_index
= -1;
3269 /* Recursively traverse subtree of NODE (including node) made of inlined
3270 cgraph_edges when CS has been inlined and invoke
3271 update_indirect_edges_after_inlining on all nodes and
3272 update_jump_functions_after_inlining on all non-inlined edges that lead out
3273 of this subtree. Newly discovered indirect edges will be added to
3274 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
3278 propagate_info_to_inlined_callees (struct cgraph_edge
*cs
,
3279 struct cgraph_node
*node
,
3280 vec
<cgraph_edge
*> *new_edges
)
3282 struct cgraph_edge
*e
;
3285 res
= update_indirect_edges_after_inlining (cs
, node
, new_edges
);
3287 for (e
= node
->callees
; e
; e
= e
->next_callee
)
3288 if (!e
->inline_failed
)
3289 res
|= propagate_info_to_inlined_callees (cs
, e
->callee
, new_edges
);
3291 update_jump_functions_after_inlining (cs
, e
);
3292 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
3293 update_jump_functions_after_inlining (cs
, e
);
3298 /* Combine two controlled uses counts as done during inlining. */
3301 combine_controlled_uses_counters (int c
, int d
)
3303 if (c
== IPA_UNDESCRIBED_USE
|| d
== IPA_UNDESCRIBED_USE
)
3304 return IPA_UNDESCRIBED_USE
;
3309 /* Propagate number of controlled users from CS->caleee to the new root of the
3310 tree of inlined nodes. */
3313 propagate_controlled_uses (struct cgraph_edge
*cs
)
3315 struct ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
3316 struct cgraph_node
*new_root
= cs
->caller
->global
.inlined_to
3317 ? cs
->caller
->global
.inlined_to
: cs
->caller
;
3318 struct ipa_node_params
*new_root_info
= IPA_NODE_REF (new_root
);
3319 struct ipa_node_params
*old_root_info
= IPA_NODE_REF (cs
->callee
);
3322 count
= MIN (ipa_get_cs_argument_count (args
),
3323 ipa_get_param_count (old_root_info
));
3324 for (i
= 0; i
< count
; i
++)
3326 struct ipa_jump_func
*jf
= ipa_get_ith_jump_func (args
, i
);
3327 struct ipa_cst_ref_desc
*rdesc
;
3329 if (jf
->type
== IPA_JF_PASS_THROUGH
)
3332 src_idx
= ipa_get_jf_pass_through_formal_id (jf
);
3333 c
= ipa_get_controlled_uses (new_root_info
, src_idx
);
3334 d
= ipa_get_controlled_uses (old_root_info
, i
);
3336 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf
)
3337 == NOP_EXPR
|| c
== IPA_UNDESCRIBED_USE
);
3338 c
= combine_controlled_uses_counters (c
, d
);
3339 ipa_set_controlled_uses (new_root_info
, src_idx
, c
);
3340 if (c
== 0 && new_root_info
->ipcp_orig_node
)
3342 struct cgraph_node
*n
;
3343 struct ipa_ref
*ref
;
3344 tree t
= new_root_info
->known_vals
[src_idx
];
3346 if (t
&& TREE_CODE (t
) == ADDR_EXPR
3347 && TREE_CODE (TREE_OPERAND (t
, 0)) == FUNCTION_DECL
3348 && (n
= cgraph_node::get (TREE_OPERAND (t
, 0)))
3349 && (ref
= new_root
->find_reference (n
, NULL
, 0)))
3352 fprintf (dump_file
, "ipa-prop: Removing cloning-created "
3353 "reference from %s/%i to %s/%i.\n",
3354 xstrdup (new_root
->name ()),
3356 xstrdup (n
->name ()), n
->order
);
3357 ref
->remove_reference ();
3361 else if (jf
->type
== IPA_JF_CONST
3362 && (rdesc
= jfunc_rdesc_usable (jf
)))
3364 int d
= ipa_get_controlled_uses (old_root_info
, i
);
3365 int c
= rdesc
->refcount
;
3366 rdesc
->refcount
= combine_controlled_uses_counters (c
, d
);
3367 if (rdesc
->refcount
== 0)
3369 tree cst
= ipa_get_jf_constant (jf
);
3370 struct cgraph_node
*n
;
3371 gcc_checking_assert (TREE_CODE (cst
) == ADDR_EXPR
3372 && TREE_CODE (TREE_OPERAND (cst
, 0))
3374 n
= cgraph_node::get (TREE_OPERAND (cst
, 0));
3377 struct cgraph_node
*clone
;
3379 ok
= remove_described_reference (n
, rdesc
);
3380 gcc_checking_assert (ok
);
3383 while (clone
->global
.inlined_to
3384 && clone
!= rdesc
->cs
->caller
3385 && IPA_NODE_REF (clone
)->ipcp_orig_node
)
3387 struct ipa_ref
*ref
;
3388 ref
= clone
->find_reference (n
, NULL
, 0);
3392 fprintf (dump_file
, "ipa-prop: Removing "
3393 "cloning-created reference "
3394 "from %s/%i to %s/%i.\n",
3395 xstrdup (clone
->name ()),
3397 xstrdup (n
->name ()),
3399 ref
->remove_reference ();
3401 clone
= clone
->callers
->caller
;
3408 for (i
= ipa_get_param_count (old_root_info
);
3409 i
< ipa_get_cs_argument_count (args
);
3412 struct ipa_jump_func
*jf
= ipa_get_ith_jump_func (args
, i
);
3414 if (jf
->type
== IPA_JF_CONST
)
3416 struct ipa_cst_ref_desc
*rdesc
= jfunc_rdesc_usable (jf
);
3418 rdesc
->refcount
= IPA_UNDESCRIBED_USE
;
3420 else if (jf
->type
== IPA_JF_PASS_THROUGH
)
3421 ipa_set_controlled_uses (new_root_info
,
3422 jf
->value
.pass_through
.formal_id
,
3423 IPA_UNDESCRIBED_USE
);
3427 /* Update jump functions and call note functions on inlining the call site CS.
3428 CS is expected to lead to a node already cloned by
3429 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
3430 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
3434 ipa_propagate_indirect_call_infos (struct cgraph_edge
*cs
,
3435 vec
<cgraph_edge
*> *new_edges
)
3438 /* Do nothing if the preparation phase has not been carried out yet
3439 (i.e. during early inlining). */
3440 if (!ipa_node_params_vector
.exists ())
3442 gcc_assert (ipa_edge_args_vector
);
3444 propagate_controlled_uses (cs
);
3445 changed
= propagate_info_to_inlined_callees (cs
, cs
->callee
, new_edges
);
3450 /* Frees all dynamically allocated structures that the argument info points
3454 ipa_free_edge_args_substructures (struct ipa_edge_args
*args
)
3456 vec_free (args
->jump_functions
);
3457 memset (args
, 0, sizeof (*args
));
3460 /* Free all ipa_edge structures. */
3463 ipa_free_all_edge_args (void)
3466 struct ipa_edge_args
*args
;
3468 if (!ipa_edge_args_vector
)
3471 FOR_EACH_VEC_ELT (*ipa_edge_args_vector
, i
, args
)
3472 ipa_free_edge_args_substructures (args
);
3474 vec_free (ipa_edge_args_vector
);
3477 /* Frees all dynamically allocated structures that the param info points
3481 ipa_free_node_params_substructures (struct ipa_node_params
*info
)
3483 info
->descriptors
.release ();
3484 free (info
->lattices
);
3485 /* Lattice values and their sources are deallocated with their alocation
3487 info
->known_vals
.release ();
3488 memset (info
, 0, sizeof (*info
));
3491 /* Free all ipa_node_params structures. */
3494 ipa_free_all_node_params (void)
3497 struct ipa_node_params
*info
;
3499 FOR_EACH_VEC_ELT (ipa_node_params_vector
, i
, info
)
3500 ipa_free_node_params_substructures (info
);
3502 ipa_node_params_vector
.release ();
3505 /* Set the aggregate replacements of NODE to be AGGVALS. */
3508 ipa_set_node_agg_value_chain (struct cgraph_node
*node
,
3509 struct ipa_agg_replacement_value
*aggvals
)
3511 if (vec_safe_length (ipa_node_agg_replacements
)
3512 <= (unsigned) symtab
->cgraph_max_uid
)
3513 vec_safe_grow_cleared (ipa_node_agg_replacements
,
3514 symtab
->cgraph_max_uid
+ 1);
3516 (*ipa_node_agg_replacements
)[node
->uid
] = aggvals
;
3519 /* Hook that is called by cgraph.c when an edge is removed. */
3522 ipa_edge_removal_hook (struct cgraph_edge
*cs
, void *data ATTRIBUTE_UNUSED
)
3524 struct ipa_edge_args
*args
;
3526 /* During IPA-CP updating we can be called on not-yet analyzed clones. */
3527 if (vec_safe_length (ipa_edge_args_vector
) <= (unsigned)cs
->uid
)
3530 args
= IPA_EDGE_REF (cs
);
3531 if (args
->jump_functions
)
3533 struct ipa_jump_func
*jf
;
3535 FOR_EACH_VEC_ELT (*args
->jump_functions
, i
, jf
)
3537 struct ipa_cst_ref_desc
*rdesc
;
3538 try_decrement_rdesc_refcount (jf
);
3539 if (jf
->type
== IPA_JF_CONST
3540 && (rdesc
= ipa_get_jf_constant_rdesc (jf
))
3546 ipa_free_edge_args_substructures (IPA_EDGE_REF (cs
));
3549 /* Hook that is called by cgraph.c when a node is removed. */
3552 ipa_node_removal_hook (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
3554 /* During IPA-CP updating we can be called on not-yet analyze clones. */
3555 if (ipa_node_params_vector
.length () > (unsigned)node
->uid
)
3556 ipa_free_node_params_substructures (IPA_NODE_REF (node
));
3557 if (vec_safe_length (ipa_node_agg_replacements
) > (unsigned)node
->uid
)
3558 (*ipa_node_agg_replacements
)[(unsigned)node
->uid
] = NULL
;
3561 /* Hook that is called by cgraph.c when an edge is duplicated. */
3564 ipa_edge_duplication_hook (struct cgraph_edge
*src
, struct cgraph_edge
*dst
,
3565 __attribute__((unused
)) void *data
)
3567 struct ipa_edge_args
*old_args
, *new_args
;
3570 ipa_check_create_edge_args ();
3572 old_args
= IPA_EDGE_REF (src
);
3573 new_args
= IPA_EDGE_REF (dst
);
3575 new_args
->jump_functions
= vec_safe_copy (old_args
->jump_functions
);
3577 for (i
= 0; i
< vec_safe_length (old_args
->jump_functions
); i
++)
3579 struct ipa_jump_func
*src_jf
= ipa_get_ith_jump_func (old_args
, i
);
3580 struct ipa_jump_func
*dst_jf
= ipa_get_ith_jump_func (new_args
, i
);
3582 dst_jf
->agg
.items
= vec_safe_copy (dst_jf
->agg
.items
);
3584 if (src_jf
->type
== IPA_JF_CONST
)
3586 struct ipa_cst_ref_desc
*src_rdesc
= jfunc_rdesc_usable (src_jf
);
3589 dst_jf
->value
.constant
.rdesc
= NULL
;
3590 else if (src
->caller
== dst
->caller
)
3592 struct ipa_ref
*ref
;
3593 symtab_node
*n
= cgraph_node_for_jfunc (src_jf
);
3594 gcc_checking_assert (n
);
3595 ref
= src
->caller
->find_reference (n
, src
->call_stmt
,
3597 gcc_checking_assert (ref
);
3598 dst
->caller
->clone_reference (ref
, ref
->stmt
);
3600 gcc_checking_assert (ipa_refdesc_pool
);
3601 struct ipa_cst_ref_desc
*dst_rdesc
3602 = (struct ipa_cst_ref_desc
*) pool_alloc (ipa_refdesc_pool
);
3603 dst_rdesc
->cs
= dst
;
3604 dst_rdesc
->refcount
= src_rdesc
->refcount
;
3605 dst_rdesc
->next_duplicate
= NULL
;
3606 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
3608 else if (src_rdesc
->cs
== src
)
3610 struct ipa_cst_ref_desc
*dst_rdesc
;
3611 gcc_checking_assert (ipa_refdesc_pool
);
3613 = (struct ipa_cst_ref_desc
*) pool_alloc (ipa_refdesc_pool
);
3614 dst_rdesc
->cs
= dst
;
3615 dst_rdesc
->refcount
= src_rdesc
->refcount
;
3616 dst_rdesc
->next_duplicate
= src_rdesc
->next_duplicate
;
3617 src_rdesc
->next_duplicate
= dst_rdesc
;
3618 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
3622 struct ipa_cst_ref_desc
*dst_rdesc
;
3623 /* This can happen during inlining, when a JFUNC can refer to a
3624 reference taken in a function up in the tree of inline clones.
3625 We need to find the duplicate that refers to our tree of
3628 gcc_assert (dst
->caller
->global
.inlined_to
);
3629 for (dst_rdesc
= src_rdesc
->next_duplicate
;
3631 dst_rdesc
= dst_rdesc
->next_duplicate
)
3633 struct cgraph_node
*top
;
3634 top
= dst_rdesc
->cs
->caller
->global
.inlined_to
3635 ? dst_rdesc
->cs
->caller
->global
.inlined_to
3636 : dst_rdesc
->cs
->caller
;
3637 if (dst
->caller
->global
.inlined_to
== top
)
3640 gcc_assert (dst_rdesc
);
3641 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
3644 else if (dst_jf
->type
== IPA_JF_PASS_THROUGH
3645 && src
->caller
== dst
->caller
)
3647 struct cgraph_node
*inline_root
= dst
->caller
->global
.inlined_to
3648 ? dst
->caller
->global
.inlined_to
: dst
->caller
;
3649 struct ipa_node_params
*root_info
= IPA_NODE_REF (inline_root
);
3650 int idx
= ipa_get_jf_pass_through_formal_id (dst_jf
);
3652 int c
= ipa_get_controlled_uses (root_info
, idx
);
3653 if (c
!= IPA_UNDESCRIBED_USE
)
3656 ipa_set_controlled_uses (root_info
, idx
, c
);
3662 /* Hook that is called by cgraph.c when a node is duplicated. */
3665 ipa_node_duplication_hook (struct cgraph_node
*src
, struct cgraph_node
*dst
,
3666 ATTRIBUTE_UNUSED
void *data
)
3668 struct ipa_node_params
*old_info
, *new_info
;
3669 struct ipa_agg_replacement_value
*old_av
, *new_av
;
3671 ipa_check_create_node_params ();
3672 old_info
= IPA_NODE_REF (src
);
3673 new_info
= IPA_NODE_REF (dst
);
3675 new_info
->descriptors
= old_info
->descriptors
.copy ();
3676 new_info
->lattices
= NULL
;
3677 new_info
->ipcp_orig_node
= old_info
->ipcp_orig_node
;
3679 new_info
->analysis_done
= old_info
->analysis_done
;
3680 new_info
->node_enqueued
= old_info
->node_enqueued
;
3682 old_av
= ipa_get_agg_replacements_for_node (src
);
3689 struct ipa_agg_replacement_value
*v
;
3691 v
= ggc_alloc
<ipa_agg_replacement_value
> ();
3692 memcpy (v
, old_av
, sizeof (*v
));
3695 old_av
= old_av
->next
;
3697 ipa_set_node_agg_value_chain (dst
, new_av
);
3701 /* Analyze newly added function into callgraph. */
3704 ipa_add_new_function (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
3706 if (node
->has_gimple_body_p ())
3707 ipa_analyze_node (node
);
3710 /* Register our cgraph hooks if they are not already there. */
3713 ipa_register_cgraph_hooks (void)
3715 if (!edge_removal_hook_holder
)
3716 edge_removal_hook_holder
=
3717 symtab
->add_edge_removal_hook (&ipa_edge_removal_hook
, NULL
);
3718 if (!node_removal_hook_holder
)
3719 node_removal_hook_holder
=
3720 symtab
->add_cgraph_removal_hook (&ipa_node_removal_hook
, NULL
);
3721 if (!edge_duplication_hook_holder
)
3722 edge_duplication_hook_holder
=
3723 symtab
->add_edge_duplication_hook (&ipa_edge_duplication_hook
, NULL
);
3724 if (!node_duplication_hook_holder
)
3725 node_duplication_hook_holder
=
3726 symtab
->add_cgraph_duplication_hook (&ipa_node_duplication_hook
, NULL
);
3727 function_insertion_hook_holder
=
3728 symtab
->add_cgraph_insertion_hook (&ipa_add_new_function
, NULL
);
3731 /* Unregister our cgraph hooks if they are not already there. */
3734 ipa_unregister_cgraph_hooks (void)
3736 symtab
->remove_edge_removal_hook (edge_removal_hook_holder
);
3737 edge_removal_hook_holder
= NULL
;
3738 symtab
->remove_cgraph_removal_hook (node_removal_hook_holder
);
3739 node_removal_hook_holder
= NULL
;
3740 symtab
->remove_edge_duplication_hook (edge_duplication_hook_holder
);
3741 edge_duplication_hook_holder
= NULL
;
3742 symtab
->remove_cgraph_duplication_hook (node_duplication_hook_holder
);
3743 node_duplication_hook_holder
= NULL
;
3744 symtab
->remove_cgraph_insertion_hook (function_insertion_hook_holder
);
3745 function_insertion_hook_holder
= NULL
;
3748 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
3749 longer needed after ipa-cp. */
3752 ipa_free_all_structures_after_ipa_cp (void)
3756 ipa_free_all_edge_args ();
3757 ipa_free_all_node_params ();
3758 free_alloc_pool (ipcp_sources_pool
);
3759 free_alloc_pool (ipcp_values_pool
);
3760 free_alloc_pool (ipcp_agg_lattice_pool
);
3761 ipa_unregister_cgraph_hooks ();
3762 if (ipa_refdesc_pool
)
3763 free_alloc_pool (ipa_refdesc_pool
);
3767 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
3768 longer needed after indirect inlining. */
3771 ipa_free_all_structures_after_iinln (void)
3773 ipa_free_all_edge_args ();
3774 ipa_free_all_node_params ();
3775 ipa_unregister_cgraph_hooks ();
3776 if (ipcp_sources_pool
)
3777 free_alloc_pool (ipcp_sources_pool
);
3778 if (ipcp_values_pool
)
3779 free_alloc_pool (ipcp_values_pool
);
3780 if (ipcp_agg_lattice_pool
)
3781 free_alloc_pool (ipcp_agg_lattice_pool
);
3782 if (ipa_refdesc_pool
)
3783 free_alloc_pool (ipa_refdesc_pool
);
3786 /* Print ipa_tree_map data structures of all functions in the
3790 ipa_print_node_params (FILE *f
, struct cgraph_node
*node
)
3793 struct ipa_node_params
*info
;
3795 if (!node
->definition
)
3797 info
= IPA_NODE_REF (node
);
3798 fprintf (f
, " function %s/%i parameter descriptors:\n",
3799 node
->name (), node
->order
);
3800 count
= ipa_get_param_count (info
);
3801 for (i
= 0; i
< count
; i
++)
3806 ipa_dump_param (f
, info
, i
);
3807 if (ipa_is_param_used (info
, i
))
3808 fprintf (f
, " used");
3809 c
= ipa_get_controlled_uses (info
, i
);
3810 if (c
== IPA_UNDESCRIBED_USE
)
3811 fprintf (f
, " undescribed_use");
3813 fprintf (f
, " controlled_uses=%i", c
);
3818 /* Print ipa_tree_map data structures of all functions in the
3822 ipa_print_all_params (FILE * f
)
3824 struct cgraph_node
*node
;
3826 fprintf (f
, "\nFunction parameters:\n");
3827 FOR_EACH_FUNCTION (node
)
3828 ipa_print_node_params (f
, node
);
3831 /* Return a heap allocated vector containing formal parameters of FNDECL. */
3834 ipa_get_vector_of_formal_parms (tree fndecl
)
3840 gcc_assert (!flag_wpa
);
3841 count
= count_formal_params (fndecl
);
3842 args
.create (count
);
3843 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
3844 args
.quick_push (parm
);
3849 /* Return a heap allocated vector containing types of formal parameters of
3850 function type FNTYPE. */
3853 ipa_get_vector_of_formal_parm_types (tree fntype
)
3859 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
3862 types
.create (count
);
3863 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
3864 types
.quick_push (TREE_VALUE (t
));
3869 /* Modify the function declaration FNDECL and its type according to the plan in
3870 ADJUSTMENTS. It also sets base fields of individual adjustments structures
3871 to reflect the actual parameters being modified which are determined by the
3872 base_index field. */
3875 ipa_modify_formal_parameters (tree fndecl
, ipa_parm_adjustment_vec adjustments
)
3877 vec
<tree
> oparms
= ipa_get_vector_of_formal_parms (fndecl
);
3878 tree orig_type
= TREE_TYPE (fndecl
);
3879 tree old_arg_types
= TYPE_ARG_TYPES (orig_type
);
3881 /* The following test is an ugly hack, some functions simply don't have any
3882 arguments in their type. This is probably a bug but well... */
3883 bool care_for_types
= (old_arg_types
!= NULL_TREE
);
3884 bool last_parm_void
;
3888 last_parm_void
= (TREE_VALUE (tree_last (old_arg_types
))
3890 otypes
= ipa_get_vector_of_formal_parm_types (orig_type
);
3892 gcc_assert (oparms
.length () + 1 == otypes
.length ());
3894 gcc_assert (oparms
.length () == otypes
.length ());
3898 last_parm_void
= false;
3902 int len
= adjustments
.length ();
3903 tree
*link
= &DECL_ARGUMENTS (fndecl
);
3904 tree new_arg_types
= NULL
;
3905 for (int i
= 0; i
< len
; i
++)
3907 struct ipa_parm_adjustment
*adj
;
3910 adj
= &adjustments
[i
];
3912 if (adj
->op
== IPA_PARM_OP_NEW
)
3915 parm
= oparms
[adj
->base_index
];
3918 if (adj
->op
== IPA_PARM_OP_COPY
)
3921 new_arg_types
= tree_cons (NULL_TREE
, otypes
[adj
->base_index
],
3924 link
= &DECL_CHAIN (parm
);
3926 else if (adj
->op
!= IPA_PARM_OP_REMOVE
)
3932 ptype
= build_pointer_type (adj
->type
);
3936 if (is_gimple_reg_type (ptype
))
3938 unsigned malign
= GET_MODE_ALIGNMENT (TYPE_MODE (ptype
));
3939 if (TYPE_ALIGN (ptype
) < malign
)
3940 ptype
= build_aligned_type (ptype
, malign
);
3945 new_arg_types
= tree_cons (NULL_TREE
, ptype
, new_arg_types
);
3947 new_parm
= build_decl (UNKNOWN_LOCATION
, PARM_DECL
, NULL_TREE
,
3949 const char *prefix
= adj
->arg_prefix
? adj
->arg_prefix
: "SYNTH";
3950 DECL_NAME (new_parm
) = create_tmp_var_name (prefix
);
3951 DECL_ARTIFICIAL (new_parm
) = 1;
3952 DECL_ARG_TYPE (new_parm
) = ptype
;
3953 DECL_CONTEXT (new_parm
) = fndecl
;
3954 TREE_USED (new_parm
) = 1;
3955 DECL_IGNORED_P (new_parm
) = 1;
3956 layout_decl (new_parm
, 0);
3958 if (adj
->op
== IPA_PARM_OP_NEW
)
3962 adj
->new_decl
= new_parm
;
3965 link
= &DECL_CHAIN (new_parm
);
3971 tree new_reversed
= NULL
;
3974 new_reversed
= nreverse (new_arg_types
);
3978 TREE_CHAIN (new_arg_types
) = void_list_node
;
3980 new_reversed
= void_list_node
;
3984 /* Use copy_node to preserve as much as possible from original type
3985 (debug info, attribute lists etc.)
3986 Exception is METHOD_TYPEs must have THIS argument.
3987 When we are asked to remove it, we need to build new FUNCTION_TYPE
3989 tree new_type
= NULL
;
3990 if (TREE_CODE (orig_type
) != METHOD_TYPE
3991 || (adjustments
[0].op
== IPA_PARM_OP_COPY
3992 && adjustments
[0].base_index
== 0))
3994 new_type
= build_distinct_type_copy (orig_type
);
3995 TYPE_ARG_TYPES (new_type
) = new_reversed
;
4000 = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type
),
4002 TYPE_CONTEXT (new_type
) = TYPE_CONTEXT (orig_type
);
4003 DECL_VINDEX (fndecl
) = NULL_TREE
;
4006 /* When signature changes, we need to clear builtin info. */
4007 if (DECL_BUILT_IN (fndecl
))
4009 DECL_BUILT_IN_CLASS (fndecl
) = NOT_BUILT_IN
;
4010 DECL_FUNCTION_CODE (fndecl
) = (enum built_in_function
) 0;
4013 /* This is a new type, not a copy of an old type. Need to reassociate
4014 variants. We can handle everything except the main variant lazily. */
4015 tree t
= TYPE_MAIN_VARIANT (orig_type
);
4018 TYPE_MAIN_VARIANT (new_type
) = t
;
4019 TYPE_NEXT_VARIANT (new_type
) = TYPE_NEXT_VARIANT (t
);
4020 TYPE_NEXT_VARIANT (t
) = new_type
;
4024 TYPE_MAIN_VARIANT (new_type
) = new_type
;
4025 TYPE_NEXT_VARIANT (new_type
) = NULL
;
4028 TREE_TYPE (fndecl
) = new_type
;
4029 DECL_VIRTUAL_P (fndecl
) = 0;
4030 DECL_LANG_SPECIFIC (fndecl
) = NULL
;
4035 /* Modify actual arguments of a function call CS as indicated in ADJUSTMENTS.
4036 If this is a directly recursive call, CS must be NULL. Otherwise it must
4037 contain the corresponding call graph edge. */
4040 ipa_modify_call_arguments (struct cgraph_edge
*cs
, gimple stmt
,
4041 ipa_parm_adjustment_vec adjustments
)
4043 struct cgraph_node
*current_node
= cgraph_node::get (current_function_decl
);
4045 vec
<tree
, va_gc
> **debug_args
= NULL
;
4047 gimple_stmt_iterator gsi
, prev_gsi
;
4051 len
= adjustments
.length ();
4053 callee_decl
= !cs
? gimple_call_fndecl (stmt
) : cs
->callee
->decl
;
4054 current_node
->remove_stmt_references (stmt
);
4056 gsi
= gsi_for_stmt (stmt
);
4058 gsi_prev (&prev_gsi
);
4059 for (i
= 0; i
< len
; i
++)
4061 struct ipa_parm_adjustment
*adj
;
4063 adj
= &adjustments
[i
];
4065 if (adj
->op
== IPA_PARM_OP_COPY
)
4067 tree arg
= gimple_call_arg (stmt
, adj
->base_index
);
4069 vargs
.quick_push (arg
);
4071 else if (adj
->op
!= IPA_PARM_OP_REMOVE
)
4073 tree expr
, base
, off
;
4075 unsigned int deref_align
= 0;
4076 bool deref_base
= false;
4078 /* We create a new parameter out of the value of the old one, we can
4079 do the following kind of transformations:
4081 - A scalar passed by reference is converted to a scalar passed by
4082 value. (adj->by_ref is false and the type of the original
4083 actual argument is a pointer to a scalar).
4085 - A part of an aggregate is passed instead of the whole aggregate.
4086 The part can be passed either by value or by reference, this is
4087 determined by value of adj->by_ref. Moreover, the code below
4088 handles both situations when the original aggregate is passed by
4089 value (its type is not a pointer) and when it is passed by
4090 reference (it is a pointer to an aggregate).
4092 When the new argument is passed by reference (adj->by_ref is true)
4093 it must be a part of an aggregate and therefore we form it by
4094 simply taking the address of a reference inside the original
4097 gcc_checking_assert (adj
->offset
% BITS_PER_UNIT
== 0);
4098 base
= gimple_call_arg (stmt
, adj
->base_index
);
4099 loc
= DECL_P (base
) ? DECL_SOURCE_LOCATION (base
)
4100 : EXPR_LOCATION (base
);
4102 if (TREE_CODE (base
) != ADDR_EXPR
4103 && POINTER_TYPE_P (TREE_TYPE (base
)))
4104 off
= build_int_cst (adj
->alias_ptr_type
,
4105 adj
->offset
/ BITS_PER_UNIT
);
4108 HOST_WIDE_INT base_offset
;
4112 if (TREE_CODE (base
) == ADDR_EXPR
)
4114 base
= TREE_OPERAND (base
, 0);
4120 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
4121 /* Aggregate arguments can have non-invariant addresses. */
4124 base
= build_fold_addr_expr (prev_base
);
4125 off
= build_int_cst (adj
->alias_ptr_type
,
4126 adj
->offset
/ BITS_PER_UNIT
);
4128 else if (TREE_CODE (base
) == MEM_REF
)
4133 deref_align
= TYPE_ALIGN (TREE_TYPE (base
));
4135 off
= build_int_cst (adj
->alias_ptr_type
,
4137 + adj
->offset
/ BITS_PER_UNIT
);
4138 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1),
4140 base
= TREE_OPERAND (base
, 0);
4144 off
= build_int_cst (adj
->alias_ptr_type
,
4146 + adj
->offset
/ BITS_PER_UNIT
);
4147 base
= build_fold_addr_expr (base
);
4153 tree type
= adj
->type
;
4155 unsigned HOST_WIDE_INT misalign
;
4159 align
= deref_align
;
4164 get_pointer_alignment_1 (base
, &align
, &misalign
);
4165 if (TYPE_ALIGN (type
) > align
)
4166 align
= TYPE_ALIGN (type
);
4168 misalign
+= (offset_int::from (off
, SIGNED
).to_short_addr ()
4170 misalign
= misalign
& (align
- 1);
4172 align
= (misalign
& -misalign
);
4173 if (align
< TYPE_ALIGN (type
))
4174 type
= build_aligned_type (type
, align
);
4175 base
= force_gimple_operand_gsi (&gsi
, base
,
4176 true, NULL
, true, GSI_SAME_STMT
);
4177 expr
= fold_build2_loc (loc
, MEM_REF
, type
, base
, off
);
4178 /* If expr is not a valid gimple call argument emit
4179 a load into a temporary. */
4180 if (is_gimple_reg_type (TREE_TYPE (expr
)))
4182 gimple tem
= gimple_build_assign (NULL_TREE
, expr
);
4183 if (gimple_in_ssa_p (cfun
))
4185 gimple_set_vuse (tem
, gimple_vuse (stmt
));
4186 expr
= make_ssa_name (TREE_TYPE (expr
), tem
);
4189 expr
= create_tmp_reg (TREE_TYPE (expr
), NULL
);
4190 gimple_assign_set_lhs (tem
, expr
);
4191 gsi_insert_before (&gsi
, tem
, GSI_SAME_STMT
);
4196 expr
= fold_build2_loc (loc
, MEM_REF
, adj
->type
, base
, off
);
4197 expr
= build_fold_addr_expr (expr
);
4198 expr
= force_gimple_operand_gsi (&gsi
, expr
,
4199 true, NULL
, true, GSI_SAME_STMT
);
4201 vargs
.quick_push (expr
);
4203 if (adj
->op
!= IPA_PARM_OP_COPY
&& MAY_HAVE_DEBUG_STMTS
)
4206 tree ddecl
= NULL_TREE
, origin
= DECL_ORIGIN (adj
->base
), arg
;
4209 arg
= gimple_call_arg (stmt
, adj
->base_index
);
4210 if (!useless_type_conversion_p (TREE_TYPE (origin
), TREE_TYPE (arg
)))
4212 if (!fold_convertible_p (TREE_TYPE (origin
), arg
))
4214 arg
= fold_convert_loc (gimple_location (stmt
),
4215 TREE_TYPE (origin
), arg
);
4217 if (debug_args
== NULL
)
4218 debug_args
= decl_debug_args_insert (callee_decl
);
4219 for (ix
= 0; vec_safe_iterate (*debug_args
, ix
, &ddecl
); ix
+= 2)
4220 if (ddecl
== origin
)
4222 ddecl
= (**debug_args
)[ix
+ 1];
4227 ddecl
= make_node (DEBUG_EXPR_DECL
);
4228 DECL_ARTIFICIAL (ddecl
) = 1;
4229 TREE_TYPE (ddecl
) = TREE_TYPE (origin
);
4230 DECL_MODE (ddecl
) = DECL_MODE (origin
);
4232 vec_safe_push (*debug_args
, origin
);
4233 vec_safe_push (*debug_args
, ddecl
);
4235 def_temp
= gimple_build_debug_bind (ddecl
, unshare_expr (arg
), stmt
);
4236 gsi_insert_before (&gsi
, def_temp
, GSI_SAME_STMT
);
4240 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4242 fprintf (dump_file
, "replacing stmt:");
4243 print_gimple_stmt (dump_file
, gsi_stmt (gsi
), 0, 0);
4246 new_stmt
= gimple_build_call_vec (callee_decl
, vargs
);
4248 if (gimple_call_lhs (stmt
))
4249 gimple_call_set_lhs (new_stmt
, gimple_call_lhs (stmt
));
4251 gimple_set_block (new_stmt
, gimple_block (stmt
));
4252 if (gimple_has_location (stmt
))
4253 gimple_set_location (new_stmt
, gimple_location (stmt
));
4254 gimple_call_set_chain (new_stmt
, gimple_call_chain (stmt
));
4255 gimple_call_copy_flags (new_stmt
, stmt
);
4256 if (gimple_in_ssa_p (cfun
))
4258 gimple_set_vuse (new_stmt
, gimple_vuse (stmt
));
4259 if (gimple_vdef (stmt
))
4261 gimple_set_vdef (new_stmt
, gimple_vdef (stmt
));
4262 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt
)) = new_stmt
;
4266 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4268 fprintf (dump_file
, "with stmt:");
4269 print_gimple_stmt (dump_file
, new_stmt
, 0, 0);
4270 fprintf (dump_file
, "\n");
4272 gsi_replace (&gsi
, new_stmt
, true);
4274 cs
->set_call_stmt (new_stmt
);
4277 current_node
->record_stmt_references (gsi_stmt (gsi
));
4280 while (gsi_stmt (gsi
) != gsi_stmt (prev_gsi
));
4283 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
4284 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
4285 specifies whether the function should care about type incompatibility the
4286 current and new expressions. If it is false, the function will leave
4287 incompatibility issues to the caller. Return true iff the expression
4291 ipa_modify_expr (tree
*expr
, bool convert
,
4292 ipa_parm_adjustment_vec adjustments
)
4294 struct ipa_parm_adjustment
*cand
4295 = ipa_get_adjustment_candidate (&expr
, &convert
, adjustments
, false);
4301 src
= build_simple_mem_ref (cand
->new_decl
);
4303 src
= cand
->new_decl
;
4305 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4307 fprintf (dump_file
, "About to replace expr ");
4308 print_generic_expr (dump_file
, *expr
, 0);
4309 fprintf (dump_file
, " with ");
4310 print_generic_expr (dump_file
, src
, 0);
4311 fprintf (dump_file
, "\n");
4314 if (convert
&& !useless_type_conversion_p (TREE_TYPE (*expr
), cand
->type
))
4316 tree vce
= build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (*expr
), src
);
4324 /* If T is an SSA_NAME, return NULL if it is not a default def or
4325 return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
4326 the base variable is always returned, regardless if it is a default
4327 def. Return T if it is not an SSA_NAME. */
4330 get_ssa_base_param (tree t
, bool ignore_default_def
)
4332 if (TREE_CODE (t
) == SSA_NAME
)
4334 if (ignore_default_def
|| SSA_NAME_IS_DEFAULT_DEF (t
))
4335 return SSA_NAME_VAR (t
);
4342 /* Given an expression, return an adjustment entry specifying the
4343 transformation to be done on EXPR. If no suitable adjustment entry
4344 was found, returns NULL.
4346 If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
4347 default def, otherwise bail on them.
4349 If CONVERT is non-NULL, this function will set *CONVERT if the
4350 expression provided is a component reference. ADJUSTMENTS is the
4351 adjustments vector. */
4353 ipa_parm_adjustment
*
4354 ipa_get_adjustment_candidate (tree
**expr
, bool *convert
,
4355 ipa_parm_adjustment_vec adjustments
,
4356 bool ignore_default_def
)
4358 if (TREE_CODE (**expr
) == BIT_FIELD_REF
4359 || TREE_CODE (**expr
) == IMAGPART_EXPR
4360 || TREE_CODE (**expr
) == REALPART_EXPR
)
4362 *expr
= &TREE_OPERAND (**expr
, 0);
4367 HOST_WIDE_INT offset
, size
, max_size
;
4368 tree base
= get_ref_base_and_extent (**expr
, &offset
, &size
, &max_size
);
4369 if (!base
|| size
== -1 || max_size
== -1)
4372 if (TREE_CODE (base
) == MEM_REF
)
4374 offset
+= mem_ref_offset (base
).to_short_addr () * BITS_PER_UNIT
;
4375 base
= TREE_OPERAND (base
, 0);
4378 base
= get_ssa_base_param (base
, ignore_default_def
);
4379 if (!base
|| TREE_CODE (base
) != PARM_DECL
)
4382 struct ipa_parm_adjustment
*cand
= NULL
;
4383 unsigned int len
= adjustments
.length ();
4384 for (unsigned i
= 0; i
< len
; i
++)
4386 struct ipa_parm_adjustment
*adj
= &adjustments
[i
];
4388 if (adj
->base
== base
4389 && (adj
->offset
== offset
|| adj
->op
== IPA_PARM_OP_REMOVE
))
4396 if (!cand
|| cand
->op
== IPA_PARM_OP_COPY
|| cand
->op
== IPA_PARM_OP_REMOVE
)
4401 /* Return true iff BASE_INDEX is in ADJUSTMENTS more than once. */
4404 index_in_adjustments_multiple_times_p (int base_index
,
4405 ipa_parm_adjustment_vec adjustments
)
4407 int i
, len
= adjustments
.length ();
4410 for (i
= 0; i
< len
; i
++)
4412 struct ipa_parm_adjustment
*adj
;
4413 adj
= &adjustments
[i
];
4415 if (adj
->base_index
== base_index
)
4427 /* Return adjustments that should have the same effect on function parameters
4428 and call arguments as if they were first changed according to adjustments in
4429 INNER and then by adjustments in OUTER. */
4431 ipa_parm_adjustment_vec
4432 ipa_combine_adjustments (ipa_parm_adjustment_vec inner
,
4433 ipa_parm_adjustment_vec outer
)
4435 int i
, outlen
= outer
.length ();
4436 int inlen
= inner
.length ();
4438 ipa_parm_adjustment_vec adjustments
, tmp
;
4441 for (i
= 0; i
< inlen
; i
++)
4443 struct ipa_parm_adjustment
*n
;
4446 if (n
->op
== IPA_PARM_OP_REMOVE
)
4450 /* FIXME: Handling of new arguments are not implemented yet. */
4451 gcc_assert (n
->op
!= IPA_PARM_OP_NEW
);
4452 tmp
.quick_push (*n
);
4456 adjustments
.create (outlen
+ removals
);
4457 for (i
= 0; i
< outlen
; i
++)
4459 struct ipa_parm_adjustment r
;
4460 struct ipa_parm_adjustment
*out
= &outer
[i
];
4461 struct ipa_parm_adjustment
*in
= &tmp
[out
->base_index
];
4463 memset (&r
, 0, sizeof (r
));
4464 gcc_assert (in
->op
!= IPA_PARM_OP_REMOVE
);
4465 if (out
->op
== IPA_PARM_OP_REMOVE
)
4467 if (!index_in_adjustments_multiple_times_p (in
->base_index
, tmp
))
4469 r
.op
= IPA_PARM_OP_REMOVE
;
4470 adjustments
.quick_push (r
);
4476 /* FIXME: Handling of new arguments are not implemented yet. */
4477 gcc_assert (out
->op
!= IPA_PARM_OP_NEW
);
4480 r
.base_index
= in
->base_index
;
4483 /* FIXME: Create nonlocal value too. */
4485 if (in
->op
== IPA_PARM_OP_COPY
&& out
->op
== IPA_PARM_OP_COPY
)
4486 r
.op
= IPA_PARM_OP_COPY
;
4487 else if (in
->op
== IPA_PARM_OP_COPY
)
4488 r
.offset
= out
->offset
;
4489 else if (out
->op
== IPA_PARM_OP_COPY
)
4490 r
.offset
= in
->offset
;
4492 r
.offset
= in
->offset
+ out
->offset
;
4493 adjustments
.quick_push (r
);
4496 for (i
= 0; i
< inlen
; i
++)
4498 struct ipa_parm_adjustment
*n
= &inner
[i
];
4500 if (n
->op
== IPA_PARM_OP_REMOVE
)
4501 adjustments
.quick_push (*n
);
4508 /* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
4509 friendly way, assuming they are meant to be applied to FNDECL. */
4512 ipa_dump_param_adjustments (FILE *file
, ipa_parm_adjustment_vec adjustments
,
4515 int i
, len
= adjustments
.length ();
4517 vec
<tree
> parms
= ipa_get_vector_of_formal_parms (fndecl
);
4519 fprintf (file
, "IPA param adjustments: ");
4520 for (i
= 0; i
< len
; i
++)
4522 struct ipa_parm_adjustment
*adj
;
4523 adj
= &adjustments
[i
];
4526 fprintf (file
, " ");
4530 fprintf (file
, "%i. base_index: %i - ", i
, adj
->base_index
);
4531 print_generic_expr (file
, parms
[adj
->base_index
], 0);
4534 fprintf (file
, ", base: ");
4535 print_generic_expr (file
, adj
->base
, 0);
4539 fprintf (file
, ", new_decl: ");
4540 print_generic_expr (file
, adj
->new_decl
, 0);
4542 if (adj
->new_ssa_base
)
4544 fprintf (file
, ", new_ssa_base: ");
4545 print_generic_expr (file
, adj
->new_ssa_base
, 0);
4548 if (adj
->op
== IPA_PARM_OP_COPY
)
4549 fprintf (file
, ", copy_param");
4550 else if (adj
->op
== IPA_PARM_OP_REMOVE
)
4551 fprintf (file
, ", remove_param");
4553 fprintf (file
, ", offset %li", (long) adj
->offset
);
4555 fprintf (file
, ", by_ref");
4556 print_node_brief (file
, ", type: ", adj
->type
, 0);
4557 fprintf (file
, "\n");
4562 /* Dump the AV linked list. */
4565 ipa_dump_agg_replacement_values (FILE *f
, struct ipa_agg_replacement_value
*av
)
4568 fprintf (f
, " Aggregate replacements:");
4569 for (; av
; av
= av
->next
)
4571 fprintf (f
, "%s %i[" HOST_WIDE_INT_PRINT_DEC
"]=", comma
? "," : "",
4572 av
->index
, av
->offset
);
4573 print_generic_expr (f
, av
->value
, 0);
4579 /* Stream out jump function JUMP_FUNC to OB. */
4582 ipa_write_jump_function (struct output_block
*ob
,
4583 struct ipa_jump_func
*jump_func
)
4585 struct ipa_agg_jf_item
*item
;
4586 struct bitpack_d bp
;
4589 streamer_write_uhwi (ob
, jump_func
->type
);
4590 switch (jump_func
->type
)
4592 case IPA_JF_UNKNOWN
:
4594 case IPA_JF_KNOWN_TYPE
:
4595 streamer_write_uhwi (ob
, jump_func
->value
.known_type
.offset
);
4596 stream_write_tree (ob
, jump_func
->value
.known_type
.base_type
, true);
4597 stream_write_tree (ob
, jump_func
->value
.known_type
.component_type
, true);
4601 EXPR_LOCATION (jump_func
->value
.constant
.value
) == UNKNOWN_LOCATION
);
4602 stream_write_tree (ob
, jump_func
->value
.constant
.value
, true);
4604 case IPA_JF_PASS_THROUGH
:
4605 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.operation
);
4606 if (jump_func
->value
.pass_through
.operation
== NOP_EXPR
)
4608 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4609 bp
= bitpack_create (ob
->main_stream
);
4610 bp_pack_value (&bp
, jump_func
->value
.pass_through
.agg_preserved
, 1);
4611 bp_pack_value (&bp
, jump_func
->value
.pass_through
.type_preserved
, 1);
4612 streamer_write_bitpack (&bp
);
4616 stream_write_tree (ob
, jump_func
->value
.pass_through
.operand
, true);
4617 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4620 case IPA_JF_ANCESTOR
:
4621 streamer_write_uhwi (ob
, jump_func
->value
.ancestor
.offset
);
4622 stream_write_tree (ob
, jump_func
->value
.ancestor
.type
, true);
4623 streamer_write_uhwi (ob
, jump_func
->value
.ancestor
.formal_id
);
4624 bp
= bitpack_create (ob
->main_stream
);
4625 bp_pack_value (&bp
, jump_func
->value
.ancestor
.agg_preserved
, 1);
4626 bp_pack_value (&bp
, jump_func
->value
.ancestor
.type_preserved
, 1);
4627 streamer_write_bitpack (&bp
);
4631 count
= vec_safe_length (jump_func
->agg
.items
);
4632 streamer_write_uhwi (ob
, count
);
4635 bp
= bitpack_create (ob
->main_stream
);
4636 bp_pack_value (&bp
, jump_func
->agg
.by_ref
, 1);
4637 streamer_write_bitpack (&bp
);
4640 FOR_EACH_VEC_SAFE_ELT (jump_func
->agg
.items
, i
, item
)
4642 streamer_write_uhwi (ob
, item
->offset
);
4643 stream_write_tree (ob
, item
->value
, true);
4647 /* Read in jump function JUMP_FUNC from IB. */
4650 ipa_read_jump_function (struct lto_input_block
*ib
,
4651 struct ipa_jump_func
*jump_func
,
4652 struct cgraph_edge
*cs
,
4653 struct data_in
*data_in
)
4655 enum jump_func_type jftype
;
4656 enum tree_code operation
;
4659 jftype
= (enum jump_func_type
) streamer_read_uhwi (ib
);
4662 case IPA_JF_UNKNOWN
:
4663 jump_func
->type
= IPA_JF_UNKNOWN
;
4665 case IPA_JF_KNOWN_TYPE
:
4667 HOST_WIDE_INT offset
= streamer_read_uhwi (ib
);
4668 tree base_type
= stream_read_tree (ib
, data_in
);
4669 tree component_type
= stream_read_tree (ib
, data_in
);
4671 ipa_set_jf_known_type (jump_func
, offset
, base_type
, component_type
);
4675 ipa_set_jf_constant (jump_func
, stream_read_tree (ib
, data_in
), cs
);
4677 case IPA_JF_PASS_THROUGH
:
4678 operation
= (enum tree_code
) streamer_read_uhwi (ib
);
4679 if (operation
== NOP_EXPR
)
4681 int formal_id
= streamer_read_uhwi (ib
);
4682 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4683 bool agg_preserved
= bp_unpack_value (&bp
, 1);
4684 bool type_preserved
= bp_unpack_value (&bp
, 1);
4685 ipa_set_jf_simple_pass_through (jump_func
, formal_id
, agg_preserved
,
4690 tree operand
= stream_read_tree (ib
, data_in
);
4691 int formal_id
= streamer_read_uhwi (ib
);
4692 ipa_set_jf_arith_pass_through (jump_func
, formal_id
, operand
,
4696 case IPA_JF_ANCESTOR
:
4698 HOST_WIDE_INT offset
= streamer_read_uhwi (ib
);
4699 tree type
= stream_read_tree (ib
, data_in
);
4700 int formal_id
= streamer_read_uhwi (ib
);
4701 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4702 bool agg_preserved
= bp_unpack_value (&bp
, 1);
4703 bool type_preserved
= bp_unpack_value (&bp
, 1);
4705 ipa_set_ancestor_jf (jump_func
, offset
, type
, formal_id
, agg_preserved
,
4711 count
= streamer_read_uhwi (ib
);
4712 vec_alloc (jump_func
->agg
.items
, count
);
4715 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4716 jump_func
->agg
.by_ref
= bp_unpack_value (&bp
, 1);
4718 for (i
= 0; i
< count
; i
++)
4720 struct ipa_agg_jf_item item
;
4721 item
.offset
= streamer_read_uhwi (ib
);
4722 item
.value
= stream_read_tree (ib
, data_in
);
4723 jump_func
->agg
.items
->quick_push (item
);
4727 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
4728 relevant to indirect inlining to OB. */
4731 ipa_write_indirect_edge_info (struct output_block
*ob
,
4732 struct cgraph_edge
*cs
)
4734 struct cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
4735 struct bitpack_d bp
;
4737 streamer_write_hwi (ob
, ii
->param_index
);
4738 streamer_write_hwi (ob
, ii
->offset
);
4739 bp
= bitpack_create (ob
->main_stream
);
4740 bp_pack_value (&bp
, ii
->polymorphic
, 1);
4741 bp_pack_value (&bp
, ii
->agg_contents
, 1);
4742 bp_pack_value (&bp
, ii
->member_ptr
, 1);
4743 bp_pack_value (&bp
, ii
->by_ref
, 1);
4744 bp_pack_value (&bp
, ii
->maybe_in_construction
, 1);
4745 bp_pack_value (&bp
, ii
->maybe_derived_type
, 1);
4746 bp_pack_value (&bp
, ii
->speculative_maybe_derived_type
, 1);
4747 streamer_write_bitpack (&bp
);
4749 if (ii
->polymorphic
)
4751 streamer_write_hwi (ob
, ii
->otr_token
);
4752 stream_write_tree (ob
, ii
->otr_type
, true);
4753 stream_write_tree (ob
, ii
->outer_type
, true);
4754 stream_write_tree (ob
, ii
->speculative_outer_type
, true);
4755 if (ii
->speculative_outer_type
)
4756 streamer_write_hwi (ob
, ii
->speculative_offset
);
4760 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
4761 relevant to indirect inlining from IB. */
4764 ipa_read_indirect_edge_info (struct lto_input_block
*ib
,
4765 struct data_in
*data_in ATTRIBUTE_UNUSED
,
4766 struct cgraph_edge
*cs
)
4768 struct cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
4769 struct bitpack_d bp
;
4771 ii
->param_index
= (int) streamer_read_hwi (ib
);
4772 ii
->offset
= (HOST_WIDE_INT
) streamer_read_hwi (ib
);
4773 bp
= streamer_read_bitpack (ib
);
4774 ii
->polymorphic
= bp_unpack_value (&bp
, 1);
4775 ii
->agg_contents
= bp_unpack_value (&bp
, 1);
4776 ii
->member_ptr
= bp_unpack_value (&bp
, 1);
4777 ii
->by_ref
= bp_unpack_value (&bp
, 1);
4778 ii
->maybe_in_construction
= bp_unpack_value (&bp
, 1);
4779 ii
->maybe_derived_type
= bp_unpack_value (&bp
, 1);
4780 ii
->speculative_maybe_derived_type
= bp_unpack_value (&bp
, 1);
4781 if (ii
->polymorphic
)
4783 ii
->otr_token
= (HOST_WIDE_INT
) streamer_read_hwi (ib
);
4784 ii
->otr_type
= stream_read_tree (ib
, data_in
);
4785 ii
->outer_type
= stream_read_tree (ib
, data_in
);
4786 ii
->speculative_outer_type
= stream_read_tree (ib
, data_in
);
4787 if (ii
->speculative_outer_type
)
4788 ii
->speculative_offset
= (HOST_WIDE_INT
) streamer_read_hwi (ib
);
4792 /* Stream out NODE info to OB. */
4795 ipa_write_node_info (struct output_block
*ob
, struct cgraph_node
*node
)
4798 lto_symtab_encoder_t encoder
;
4799 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
4801 struct cgraph_edge
*e
;
4802 struct bitpack_d bp
;
4804 encoder
= ob
->decl_state
->symtab_node_encoder
;
4805 node_ref
= lto_symtab_encoder_encode (encoder
, node
);
4806 streamer_write_uhwi (ob
, node_ref
);
4808 streamer_write_uhwi (ob
, ipa_get_param_count (info
));
4809 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
4810 streamer_write_uhwi (ob
, ipa_get_param_move_cost (info
, j
));
4811 bp
= bitpack_create (ob
->main_stream
);
4812 gcc_assert (info
->analysis_done
4813 || ipa_get_param_count (info
) == 0);
4814 gcc_assert (!info
->node_enqueued
);
4815 gcc_assert (!info
->ipcp_orig_node
);
4816 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
4817 bp_pack_value (&bp
, ipa_is_param_used (info
, j
), 1);
4818 streamer_write_bitpack (&bp
);
4819 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
4820 streamer_write_hwi (ob
, ipa_get_controlled_uses (info
, j
));
4821 for (e
= node
->callees
; e
; e
= e
->next_callee
)
4823 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4825 streamer_write_uhwi (ob
, ipa_get_cs_argument_count (args
));
4826 for (j
= 0; j
< ipa_get_cs_argument_count (args
); j
++)
4827 ipa_write_jump_function (ob
, ipa_get_ith_jump_func (args
, j
));
4829 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
4831 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4833 streamer_write_uhwi (ob
, ipa_get_cs_argument_count (args
));
4834 for (j
= 0; j
< ipa_get_cs_argument_count (args
); j
++)
4835 ipa_write_jump_function (ob
, ipa_get_ith_jump_func (args
, j
));
4836 ipa_write_indirect_edge_info (ob
, e
);
4840 /* Stream in NODE info from IB. */
4843 ipa_read_node_info (struct lto_input_block
*ib
, struct cgraph_node
*node
,
4844 struct data_in
*data_in
)
4846 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
4848 struct cgraph_edge
*e
;
4849 struct bitpack_d bp
;
4851 ipa_alloc_node_params (node
, streamer_read_uhwi (ib
));
4853 for (k
= 0; k
< ipa_get_param_count (info
); k
++)
4854 info
->descriptors
[k
].move_cost
= streamer_read_uhwi (ib
);
4856 bp
= streamer_read_bitpack (ib
);
4857 if (ipa_get_param_count (info
) != 0)
4858 info
->analysis_done
= true;
4859 info
->node_enqueued
= false;
4860 for (k
= 0; k
< ipa_get_param_count (info
); k
++)
4861 ipa_set_param_used (info
, k
, bp_unpack_value (&bp
, 1));
4862 for (k
= 0; k
< ipa_get_param_count (info
); k
++)
4863 ipa_set_controlled_uses (info
, k
, streamer_read_hwi (ib
));
4864 for (e
= node
->callees
; e
; e
= e
->next_callee
)
4866 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4867 int count
= streamer_read_uhwi (ib
);
4871 vec_safe_grow_cleared (args
->jump_functions
, count
);
4873 for (k
= 0; k
< ipa_get_cs_argument_count (args
); k
++)
4874 ipa_read_jump_function (ib
, ipa_get_ith_jump_func (args
, k
), e
,
4877 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
4879 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4880 int count
= streamer_read_uhwi (ib
);
4884 vec_safe_grow_cleared (args
->jump_functions
, count
);
4885 for (k
= 0; k
< ipa_get_cs_argument_count (args
); k
++)
4886 ipa_read_jump_function (ib
, ipa_get_ith_jump_func (args
, k
), e
,
4889 ipa_read_indirect_edge_info (ib
, data_in
, e
);
4893 /* Write jump functions for nodes in SET. */
4896 ipa_prop_write_jump_functions (void)
4898 struct cgraph_node
*node
;
4899 struct output_block
*ob
;
4900 unsigned int count
= 0;
4901 lto_symtab_encoder_iterator lsei
;
4902 lto_symtab_encoder_t encoder
;
4905 if (!ipa_node_params_vector
.exists ())
4908 ob
= create_output_block (LTO_section_jump_functions
);
4909 encoder
= ob
->decl_state
->symtab_node_encoder
;
4911 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
4912 lsei_next_function_in_partition (&lsei
))
4914 node
= lsei_cgraph_node (lsei
);
4915 if (node
->has_gimple_body_p ()
4916 && IPA_NODE_REF (node
) != NULL
)
4920 streamer_write_uhwi (ob
, count
);
4922 /* Process all of the functions. */
4923 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
4924 lsei_next_function_in_partition (&lsei
))
4926 node
= lsei_cgraph_node (lsei
);
4927 if (node
->has_gimple_body_p ()
4928 && IPA_NODE_REF (node
) != NULL
)
4929 ipa_write_node_info (ob
, node
);
4931 streamer_write_char_stream (ob
->main_stream
, 0);
4932 produce_asm (ob
, NULL
);
4933 destroy_output_block (ob
);
4936 /* Read section in file FILE_DATA of length LEN with data DATA. */
4939 ipa_prop_read_section (struct lto_file_decl_data
*file_data
, const char *data
,
4942 const struct lto_function_header
*header
=
4943 (const struct lto_function_header
*) data
;
4944 const int cfg_offset
= sizeof (struct lto_function_header
);
4945 const int main_offset
= cfg_offset
+ header
->cfg_size
;
4946 const int string_offset
= main_offset
+ header
->main_size
;
4947 struct data_in
*data_in
;
4951 lto_input_block
ib_main ((const char *) data
+ main_offset
,
4955 lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
4956 header
->string_size
, vNULL
);
4957 count
= streamer_read_uhwi (&ib_main
);
4959 for (i
= 0; i
< count
; i
++)
4962 struct cgraph_node
*node
;
4963 lto_symtab_encoder_t encoder
;
4965 index
= streamer_read_uhwi (&ib_main
);
4966 encoder
= file_data
->symtab_node_encoder
;
4967 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref (encoder
,
4969 gcc_assert (node
->definition
);
4970 ipa_read_node_info (&ib_main
, node
, data_in
);
4972 lto_free_section_data (file_data
, LTO_section_jump_functions
, NULL
, data
,
4974 lto_data_in_delete (data_in
);
4977 /* Read ipcp jump functions. */
4980 ipa_prop_read_jump_functions (void)
4982 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
4983 struct lto_file_decl_data
*file_data
;
4986 ipa_check_create_node_params ();
4987 ipa_check_create_edge_args ();
4988 ipa_register_cgraph_hooks ();
4990 while ((file_data
= file_data_vec
[j
++]))
4993 const char *data
= lto_get_section_data (file_data
, LTO_section_jump_functions
, NULL
, &len
);
4996 ipa_prop_read_section (file_data
, data
, len
);
5000 /* After merging units, we can get mismatch in argument counts.
5001 Also decl merging might've rendered parameter lists obsolete.
5002 Also compute called_with_variable_arg info. */
5005 ipa_update_after_lto_read (void)
5007 ipa_check_create_node_params ();
5008 ipa_check_create_edge_args ();
5012 write_agg_replacement_chain (struct output_block
*ob
, struct cgraph_node
*node
)
5015 unsigned int count
= 0;
5016 lto_symtab_encoder_t encoder
;
5017 struct ipa_agg_replacement_value
*aggvals
, *av
;
5019 aggvals
= ipa_get_agg_replacements_for_node (node
);
5020 encoder
= ob
->decl_state
->symtab_node_encoder
;
5021 node_ref
= lto_symtab_encoder_encode (encoder
, node
);
5022 streamer_write_uhwi (ob
, node_ref
);
5024 for (av
= aggvals
; av
; av
= av
->next
)
5026 streamer_write_uhwi (ob
, count
);
5028 for (av
= aggvals
; av
; av
= av
->next
)
5030 struct bitpack_d bp
;
5032 streamer_write_uhwi (ob
, av
->offset
);
5033 streamer_write_uhwi (ob
, av
->index
);
5034 stream_write_tree (ob
, av
->value
, true);
5036 bp
= bitpack_create (ob
->main_stream
);
5037 bp_pack_value (&bp
, av
->by_ref
, 1);
5038 streamer_write_bitpack (&bp
);
5042 /* Stream in the aggregate value replacement chain for NODE from IB. */
5045 read_agg_replacement_chain (struct lto_input_block
*ib
,
5046 struct cgraph_node
*node
,
5047 struct data_in
*data_in
)
5049 struct ipa_agg_replacement_value
*aggvals
= NULL
;
5050 unsigned int count
, i
;
5052 count
= streamer_read_uhwi (ib
);
5053 for (i
= 0; i
<count
; i
++)
5055 struct ipa_agg_replacement_value
*av
;
5056 struct bitpack_d bp
;
5058 av
= ggc_alloc
<ipa_agg_replacement_value
> ();
5059 av
->offset
= streamer_read_uhwi (ib
);
5060 av
->index
= streamer_read_uhwi (ib
);
5061 av
->value
= stream_read_tree (ib
, data_in
);
5062 bp
= streamer_read_bitpack (ib
);
5063 av
->by_ref
= bp_unpack_value (&bp
, 1);
5067 ipa_set_node_agg_value_chain (node
, aggvals
);
5070 /* Write all aggregate replacement for nodes in set. */
5073 ipa_prop_write_all_agg_replacement (void)
5075 struct cgraph_node
*node
;
5076 struct output_block
*ob
;
5077 unsigned int count
= 0;
5078 lto_symtab_encoder_iterator lsei
;
5079 lto_symtab_encoder_t encoder
;
5081 if (!ipa_node_agg_replacements
)
5084 ob
= create_output_block (LTO_section_ipcp_transform
);
5085 encoder
= ob
->decl_state
->symtab_node_encoder
;
5087 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5088 lsei_next_function_in_partition (&lsei
))
5090 node
= lsei_cgraph_node (lsei
);
5091 if (node
->has_gimple_body_p ()
5092 && ipa_get_agg_replacements_for_node (node
) != NULL
)
5096 streamer_write_uhwi (ob
, count
);
5098 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5099 lsei_next_function_in_partition (&lsei
))
5101 node
= lsei_cgraph_node (lsei
);
5102 if (node
->has_gimple_body_p ()
5103 && ipa_get_agg_replacements_for_node (node
) != NULL
)
5104 write_agg_replacement_chain (ob
, node
);
5106 streamer_write_char_stream (ob
->main_stream
, 0);
5107 produce_asm (ob
, NULL
);
5108 destroy_output_block (ob
);
5111 /* Read replacements section in file FILE_DATA of length LEN with data
5115 read_replacements_section (struct lto_file_decl_data
*file_data
,
5119 const struct lto_function_header
*header
=
5120 (const struct lto_function_header
*) data
;
5121 const int cfg_offset
= sizeof (struct lto_function_header
);
5122 const int main_offset
= cfg_offset
+ header
->cfg_size
;
5123 const int string_offset
= main_offset
+ header
->main_size
;
5124 struct data_in
*data_in
;
5128 lto_input_block
ib_main ((const char *) data
+ main_offset
,
5131 data_in
= lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
5132 header
->string_size
, vNULL
);
5133 count
= streamer_read_uhwi (&ib_main
);
5135 for (i
= 0; i
< count
; i
++)
5138 struct cgraph_node
*node
;
5139 lto_symtab_encoder_t encoder
;
5141 index
= streamer_read_uhwi (&ib_main
);
5142 encoder
= file_data
->symtab_node_encoder
;
5143 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref (encoder
,
5145 gcc_assert (node
->definition
);
5146 read_agg_replacement_chain (&ib_main
, node
, data_in
);
5148 lto_free_section_data (file_data
, LTO_section_jump_functions
, NULL
, data
,
5150 lto_data_in_delete (data_in
);
5153 /* Read IPA-CP aggregate replacements. */
5156 ipa_prop_read_all_agg_replacement (void)
5158 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
5159 struct lto_file_decl_data
*file_data
;
5162 while ((file_data
= file_data_vec
[j
++]))
5165 const char *data
= lto_get_section_data (file_data
,
5166 LTO_section_ipcp_transform
,
5169 read_replacements_section (file_data
, data
, len
);
5173 /* Adjust the aggregate replacements in AGGVAL to reflect parameters skipped in
5177 adjust_agg_replacement_values (struct cgraph_node
*node
,
5178 struct ipa_agg_replacement_value
*aggval
)
5180 struct ipa_agg_replacement_value
*v
;
5181 int i
, c
= 0, d
= 0, *adj
;
5183 if (!node
->clone
.combined_args_to_skip
)
5186 for (v
= aggval
; v
; v
= v
->next
)
5188 gcc_assert (v
->index
>= 0);
5194 adj
= XALLOCAVEC (int, c
);
5195 for (i
= 0; i
< c
; i
++)
5196 if (bitmap_bit_p (node
->clone
.combined_args_to_skip
, i
))
5204 for (v
= aggval
; v
; v
= v
->next
)
5205 v
->index
= adj
[v
->index
];
5208 /* Dominator walker driving the ipcp modification phase. */
5210 class ipcp_modif_dom_walker
: public dom_walker
5213 ipcp_modif_dom_walker (struct func_body_info
*fbi
,
5214 vec
<ipa_param_descriptor
> descs
,
5215 struct ipa_agg_replacement_value
*av
,
5217 : dom_walker (CDI_DOMINATORS
), m_fbi (fbi
), m_descriptors (descs
),
5218 m_aggval (av
), m_something_changed (sc
), m_cfg_changed (cc
) {}
5220 virtual void before_dom_children (basic_block
);
5223 struct func_body_info
*m_fbi
;
5224 vec
<ipa_param_descriptor
> m_descriptors
;
5225 struct ipa_agg_replacement_value
*m_aggval
;
5226 bool *m_something_changed
, *m_cfg_changed
;
5230 ipcp_modif_dom_walker::before_dom_children (basic_block bb
)
5232 gimple_stmt_iterator gsi
;
5233 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
5235 struct ipa_agg_replacement_value
*v
;
5236 gimple stmt
= gsi_stmt (gsi
);
5238 HOST_WIDE_INT offset
, size
;
5242 if (!gimple_assign_load_p (stmt
))
5244 rhs
= gimple_assign_rhs1 (stmt
);
5245 if (!is_gimple_reg_type (TREE_TYPE (rhs
)))
5250 while (handled_component_p (t
))
5252 /* V_C_E can do things like convert an array of integers to one
5253 bigger integer and similar things we do not handle below. */
5254 if (TREE_CODE (rhs
) == VIEW_CONVERT_EXPR
)
5259 t
= TREE_OPERAND (t
, 0);
5264 if (!ipa_load_from_parm_agg_1 (m_fbi
, m_descriptors
, stmt
, rhs
, &index
,
5265 &offset
, &size
, &by_ref
))
5267 for (v
= m_aggval
; v
; v
= v
->next
)
5268 if (v
->index
== index
5269 && v
->offset
== offset
)
5272 || v
->by_ref
!= by_ref
5273 || tree_to_shwi (TYPE_SIZE (TREE_TYPE (v
->value
))) != size
)
5276 gcc_checking_assert (is_gimple_ip_invariant (v
->value
));
5277 if (!useless_type_conversion_p (TREE_TYPE (rhs
), TREE_TYPE (v
->value
)))
5279 if (fold_convertible_p (TREE_TYPE (rhs
), v
->value
))
5280 val
= fold_build1 (NOP_EXPR
, TREE_TYPE (rhs
), v
->value
);
5281 else if (TYPE_SIZE (TREE_TYPE (rhs
))
5282 == TYPE_SIZE (TREE_TYPE (v
->value
)))
5283 val
= fold_build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (rhs
), v
->value
);
5288 fprintf (dump_file
, " const ");
5289 print_generic_expr (dump_file
, v
->value
, 0);
5290 fprintf (dump_file
, " can't be converted to type of ");
5291 print_generic_expr (dump_file
, rhs
, 0);
5292 fprintf (dump_file
, "\n");
5300 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5302 fprintf (dump_file
, "Modifying stmt:\n ");
5303 print_gimple_stmt (dump_file
, stmt
, 0, 0);
5305 gimple_assign_set_rhs_from_tree (&gsi
, val
);
5308 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5310 fprintf (dump_file
, "into:\n ");
5311 print_gimple_stmt (dump_file
, stmt
, 0, 0);
5312 fprintf (dump_file
, "\n");
5315 *m_something_changed
= true;
5316 if (maybe_clean_eh_stmt (stmt
)
5317 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
5318 *m_cfg_changed
= true;
5323 /* IPCP transformation phase doing propagation of aggregate values. */
5326 ipcp_transform_function (struct cgraph_node
*node
)
5328 vec
<ipa_param_descriptor
> descriptors
= vNULL
;
5329 struct func_body_info fbi
;
5330 struct ipa_agg_replacement_value
*aggval
;
5332 bool cfg_changed
= false, something_changed
= false;
5334 gcc_checking_assert (cfun
);
5335 gcc_checking_assert (current_function_decl
);
5338 fprintf (dump_file
, "Modification phase of node %s/%i\n",
5339 node
->name (), node
->order
);
5341 aggval
= ipa_get_agg_replacements_for_node (node
);
5344 param_count
= count_formal_params (node
->decl
);
5345 if (param_count
== 0)
5347 adjust_agg_replacement_values (node
, aggval
);
5349 ipa_dump_agg_replacement_values (dump_file
, aggval
);
5353 fbi
.bb_infos
= vNULL
;
5354 fbi
.bb_infos
.safe_grow_cleared (last_basic_block_for_fn (cfun
));
5355 fbi
.param_count
= param_count
;
5358 descriptors
.safe_grow_cleared (param_count
);
5359 ipa_populate_param_decls (node
, descriptors
);
5360 calculate_dominance_info (CDI_DOMINATORS
);
5361 ipcp_modif_dom_walker (&fbi
, descriptors
, aggval
, &something_changed
,
5362 &cfg_changed
).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
5365 struct ipa_bb_info
*bi
;
5366 FOR_EACH_VEC_ELT (fbi
.bb_infos
, i
, bi
)
5367 free_ipa_bb_info (bi
);
5368 fbi
.bb_infos
.release ();
5369 free_dominance_info (CDI_DOMINATORS
);
5370 (*ipa_node_agg_replacements
)[node
->uid
] = NULL
;
5371 descriptors
.release ();
5373 if (!something_changed
)
5375 else if (cfg_changed
)
5376 return TODO_update_ssa_only_virtuals
| TODO_cleanup_cfg
;
5378 return TODO_update_ssa_only_virtuals
;