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"
30 #include "hard-reg-set.h"
33 #include "dominance.h"
35 #include "basic-block.h"
36 #include "tree-ssa-alias.h"
37 #include "internal-fn.h"
38 #include "gimple-fold.h"
40 #include "gimple-expr.h"
44 #include "stor-layout.h"
45 #include "print-tree.h"
47 #include "gimple-iterator.h"
48 #include "gimplify-me.h"
49 #include "gimple-walk.h"
50 #include "langhooks.h"
53 #include "plugin-api.h"
56 #include "alloc-pool.h"
59 #include "gimple-ssa.h"
61 #include "tree-phinodes.h"
62 #include "ssa-iterators.h"
63 #include "tree-into-ssa.h"
65 #include "tree-pass.h"
66 #include "tree-inline.h"
67 #include "ipa-inline.h"
69 #include "diagnostic.h"
70 #include "gimple-pretty-print.h"
71 #include "lto-streamer.h"
72 #include "data-streamer.h"
73 #include "tree-streamer.h"
75 #include "ipa-utils.h"
76 #include "stringpool.h"
77 #include "tree-ssanames.h"
83 /* Intermediate information that we get from alias analysis about a particular
84 parameter in a particular basic_block. When a parameter or the memory it
85 references is marked modified, we use that information in all dominatd
86 blocks without cosulting alias analysis oracle. */
88 struct param_aa_status
90 /* Set when this structure contains meaningful information. If not, the
91 structure describing a dominating BB should be used instead. */
94 /* Whether we have seen something which might have modified the data in
95 question. PARM is for the parameter itself, REF is for data it points to
96 but using the alias type of individual accesses and PT is the same thing
97 but for computing aggregate pass-through functions using a very inclusive
99 bool parm_modified
, ref_modified
, pt_modified
;
102 /* Information related to a given BB that used only when looking at function
107 /* Call graph edges going out of this BB. */
108 vec
<cgraph_edge
*> cg_edges
;
109 /* Alias analysis statuses of each formal parameter at this bb. */
110 vec
<param_aa_status
> param_aa_statuses
;
113 /* Structure with global information that is only used when looking at function
116 struct func_body_info
118 /* The node that is being analyzed. */
122 struct ipa_node_params
*info
;
124 /* Information about individual BBs. */
125 vec
<ipa_bb_info
> bb_infos
;
127 /* Number of parameters. */
130 /* Number of statements already walked by when analyzing this function. */
131 unsigned int aa_walked
;
134 /* Vector where the parameter infos are actually stored. */
135 vec
<ipa_node_params
> ipa_node_params_vector
;
136 /* Vector of known aggregate values in cloned nodes. */
137 vec
<ipa_agg_replacement_value_p
, va_gc
> *ipa_node_agg_replacements
;
138 /* Vector where the parameter infos are actually stored. */
139 vec
<ipa_edge_args
, va_gc
> *ipa_edge_args_vector
;
141 /* Holders of ipa cgraph hooks: */
142 static struct cgraph_edge_hook_list
*edge_removal_hook_holder
;
143 static struct cgraph_node_hook_list
*node_removal_hook_holder
;
144 static struct cgraph_2edge_hook_list
*edge_duplication_hook_holder
;
145 static struct cgraph_2node_hook_list
*node_duplication_hook_holder
;
146 static struct cgraph_node_hook_list
*function_insertion_hook_holder
;
148 /* Description of a reference to an IPA constant. */
149 struct ipa_cst_ref_desc
151 /* Edge that corresponds to the statement which took the reference. */
152 struct cgraph_edge
*cs
;
153 /* Linked list of duplicates created when call graph edges are cloned. */
154 struct ipa_cst_ref_desc
*next_duplicate
;
155 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
156 if out of control. */
160 /* Allocation pool for reference descriptions. */
162 static alloc_pool ipa_refdesc_pool
;
164 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
165 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
168 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node
*node
)
170 tree fs_opts
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node
->decl
);
171 struct cl_optimization
*os
;
175 os
= TREE_OPTIMIZATION (fs_opts
);
176 return !os
->x_optimize
|| !os
->x_flag_ipa_cp
;
179 /* Return index of the formal whose tree is PTREE in function which corresponds
183 ipa_get_param_decl_index_1 (vec
<ipa_param_descriptor
> descriptors
, tree ptree
)
187 count
= descriptors
.length ();
188 for (i
= 0; i
< count
; i
++)
189 if (descriptors
[i
].decl
== ptree
)
195 /* Return index of the formal whose tree is PTREE in function which corresponds
199 ipa_get_param_decl_index (struct ipa_node_params
*info
, tree ptree
)
201 return ipa_get_param_decl_index_1 (info
->descriptors
, ptree
);
204 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
208 ipa_populate_param_decls (struct cgraph_node
*node
,
209 vec
<ipa_param_descriptor
> &descriptors
)
217 gcc_assert (gimple_has_body_p (fndecl
));
218 fnargs
= DECL_ARGUMENTS (fndecl
);
220 for (parm
= fnargs
; parm
; parm
= DECL_CHAIN (parm
))
222 descriptors
[param_num
].decl
= parm
;
223 descriptors
[param_num
].move_cost
= estimate_move_cost (TREE_TYPE (parm
),
229 /* Return how many formal parameters FNDECL has. */
232 count_formal_params (tree fndecl
)
236 gcc_assert (gimple_has_body_p (fndecl
));
238 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
244 /* Return the declaration of Ith formal parameter of the function corresponding
245 to INFO. Note there is no setter function as this array is built just once
246 using ipa_initialize_node_params. */
249 ipa_dump_param (FILE *file
, struct ipa_node_params
*info
, int i
)
251 fprintf (file
, "param #%i", i
);
252 if (info
->descriptors
[i
].decl
)
255 print_generic_expr (file
, info
->descriptors
[i
].decl
, 0);
259 /* Initialize the ipa_node_params structure associated with NODE
260 to hold PARAM_COUNT parameters. */
263 ipa_alloc_node_params (struct cgraph_node
*node
, int param_count
)
265 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
267 if (!info
->descriptors
.exists () && param_count
)
268 info
->descriptors
.safe_grow_cleared (param_count
);
271 /* Initialize the ipa_node_params structure associated with NODE by counting
272 the function parameters, creating the descriptors and populating their
276 ipa_initialize_node_params (struct cgraph_node
*node
)
278 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
280 if (!info
->descriptors
.exists ())
282 ipa_alloc_node_params (node
, count_formal_params (node
->decl
));
283 ipa_populate_param_decls (node
, info
->descriptors
);
287 /* Print the jump functions associated with call graph edge CS to file F. */
290 ipa_print_node_jump_functions_for_edge (FILE *f
, struct cgraph_edge
*cs
)
294 count
= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
));
295 for (i
= 0; i
< count
; i
++)
297 struct ipa_jump_func
*jump_func
;
298 enum jump_func_type type
;
300 jump_func
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), i
);
301 type
= jump_func
->type
;
303 fprintf (f
, " param %d: ", i
);
304 if (type
== IPA_JF_UNKNOWN
)
305 fprintf (f
, "UNKNOWN\n");
306 else if (type
== IPA_JF_KNOWN_TYPE
)
308 fprintf (f
, "KNOWN TYPE: base ");
309 print_generic_expr (f
, jump_func
->value
.known_type
.base_type
, 0);
310 fprintf (f
, ", offset "HOST_WIDE_INT_PRINT_DEC
", component ",
311 jump_func
->value
.known_type
.offset
);
312 print_generic_expr (f
, jump_func
->value
.known_type
.component_type
, 0);
315 else if (type
== IPA_JF_CONST
)
317 tree val
= jump_func
->value
.constant
.value
;
318 fprintf (f
, "CONST: ");
319 print_generic_expr (f
, val
, 0);
320 if (TREE_CODE (val
) == ADDR_EXPR
321 && TREE_CODE (TREE_OPERAND (val
, 0)) == CONST_DECL
)
324 print_generic_expr (f
, DECL_INITIAL (TREE_OPERAND (val
, 0)),
329 else if (type
== IPA_JF_PASS_THROUGH
)
331 fprintf (f
, "PASS THROUGH: ");
332 fprintf (f
, "%d, op %s",
333 jump_func
->value
.pass_through
.formal_id
,
334 get_tree_code_name(jump_func
->value
.pass_through
.operation
));
335 if (jump_func
->value
.pass_through
.operation
!= NOP_EXPR
)
338 print_generic_expr (f
,
339 jump_func
->value
.pass_through
.operand
, 0);
341 if (jump_func
->value
.pass_through
.agg_preserved
)
342 fprintf (f
, ", agg_preserved");
343 if (jump_func
->value
.pass_through
.type_preserved
)
344 fprintf (f
, ", type_preserved");
347 else if (type
== IPA_JF_ANCESTOR
)
349 fprintf (f
, "ANCESTOR: ");
350 fprintf (f
, "%d, offset "HOST_WIDE_INT_PRINT_DEC
", ",
351 jump_func
->value
.ancestor
.formal_id
,
352 jump_func
->value
.ancestor
.offset
);
353 print_generic_expr (f
, jump_func
->value
.ancestor
.type
, 0);
354 if (jump_func
->value
.ancestor
.agg_preserved
)
355 fprintf (f
, ", agg_preserved");
356 if (jump_func
->value
.ancestor
.type_preserved
)
357 fprintf (f
, ", type_preserved");
361 if (jump_func
->agg
.items
)
363 struct ipa_agg_jf_item
*item
;
366 fprintf (f
, " Aggregate passed by %s:\n",
367 jump_func
->agg
.by_ref
? "reference" : "value");
368 FOR_EACH_VEC_SAFE_ELT (jump_func
->agg
.items
, j
, item
)
370 fprintf (f
, " offset: " HOST_WIDE_INT_PRINT_DEC
", ",
372 if (TYPE_P (item
->value
))
373 fprintf (f
, "clobber of " HOST_WIDE_INT_PRINT_DEC
" bits",
374 tree_to_uhwi (TYPE_SIZE (item
->value
)));
377 fprintf (f
, "cst: ");
378 print_generic_expr (f
, item
->value
, 0);
384 struct ipa_polymorphic_call_context
*ctx
385 = ipa_get_ith_polymorhic_call_context (IPA_EDGE_REF (cs
), i
);
386 if (ctx
&& !ctx
->useless_p ())
388 fprintf (f
, " Context: ");
389 ctx
->dump (dump_file
);
395 /* Print the jump functions of all arguments on all call graph edges going from
399 ipa_print_node_jump_functions (FILE *f
, struct cgraph_node
*node
)
401 struct cgraph_edge
*cs
;
403 fprintf (f
, " Jump functions of caller %s/%i:\n", node
->name (),
405 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
407 if (!ipa_edge_args_info_available_for_edge_p (cs
))
410 fprintf (f
, " callsite %s/%i -> %s/%i : \n",
411 xstrdup (node
->name ()), node
->order
,
412 xstrdup (cs
->callee
->name ()),
414 ipa_print_node_jump_functions_for_edge (f
, cs
);
417 for (cs
= node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
419 struct cgraph_indirect_call_info
*ii
;
420 if (!ipa_edge_args_info_available_for_edge_p (cs
))
423 ii
= cs
->indirect_info
;
424 if (ii
->agg_contents
)
425 fprintf (f
, " indirect %s callsite, calling param %i, "
426 "offset " HOST_WIDE_INT_PRINT_DEC
", %s",
427 ii
->member_ptr
? "member ptr" : "aggregate",
428 ii
->param_index
, ii
->offset
,
429 ii
->by_ref
? "by reference" : "by_value");
431 fprintf (f
, " indirect %s callsite, calling param %i, "
432 "offset " HOST_WIDE_INT_PRINT_DEC
,
433 ii
->polymorphic
? "polymorphic" : "simple", ii
->param_index
,
438 fprintf (f
, ", for stmt ");
439 print_gimple_stmt (f
, cs
->call_stmt
, 0, TDF_SLIM
);
444 ii
->context
.dump (f
);
445 ipa_print_node_jump_functions_for_edge (f
, cs
);
449 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
452 ipa_print_all_jump_functions (FILE *f
)
454 struct cgraph_node
*node
;
456 fprintf (f
, "\nJump functions:\n");
457 FOR_EACH_FUNCTION (node
)
459 ipa_print_node_jump_functions (f
, node
);
463 /* Set JFUNC to be a known type jump function. */
466 ipa_set_jf_known_type (struct ipa_jump_func
*jfunc
, HOST_WIDE_INT offset
,
467 tree base_type
, tree component_type
)
469 /* Recording and propagating main variants increases change that types
471 base_type
= TYPE_MAIN_VARIANT (base_type
);
472 component_type
= TYPE_MAIN_VARIANT (component_type
);
474 gcc_assert (contains_polymorphic_type_p (base_type
)
475 && contains_polymorphic_type_p (component_type
));
476 if (!flag_devirtualize
)
478 jfunc
->type
= IPA_JF_KNOWN_TYPE
;
479 jfunc
->value
.known_type
.offset
= offset
,
480 jfunc
->value
.known_type
.base_type
= base_type
;
481 jfunc
->value
.known_type
.component_type
= component_type
;
482 gcc_assert (component_type
);
485 /* Set JFUNC to be a copy of another jmp (to be used by jump function
486 combination code). The two functions will share their rdesc. */
489 ipa_set_jf_cst_copy (struct ipa_jump_func
*dst
,
490 struct ipa_jump_func
*src
)
493 gcc_checking_assert (src
->type
== IPA_JF_CONST
);
494 dst
->type
= IPA_JF_CONST
;
495 dst
->value
.constant
= src
->value
.constant
;
498 /* Set JFUNC to be a constant jmp function. */
501 ipa_set_jf_constant (struct ipa_jump_func
*jfunc
, tree constant
,
502 struct cgraph_edge
*cs
)
504 constant
= unshare_expr (constant
);
505 if (constant
&& EXPR_P (constant
))
506 SET_EXPR_LOCATION (constant
, UNKNOWN_LOCATION
);
507 jfunc
->type
= IPA_JF_CONST
;
508 jfunc
->value
.constant
.value
= unshare_expr_without_location (constant
);
510 if (TREE_CODE (constant
) == ADDR_EXPR
511 && TREE_CODE (TREE_OPERAND (constant
, 0)) == FUNCTION_DECL
)
513 struct ipa_cst_ref_desc
*rdesc
;
514 if (!ipa_refdesc_pool
)
515 ipa_refdesc_pool
= create_alloc_pool ("IPA-PROP ref descriptions",
516 sizeof (struct ipa_cst_ref_desc
), 32);
518 rdesc
= (struct ipa_cst_ref_desc
*) pool_alloc (ipa_refdesc_pool
);
520 rdesc
->next_duplicate
= NULL
;
522 jfunc
->value
.constant
.rdesc
= rdesc
;
525 jfunc
->value
.constant
.rdesc
= NULL
;
528 /* Set JFUNC to be a simple pass-through jump function. */
530 ipa_set_jf_simple_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
531 bool agg_preserved
, bool type_preserved
)
533 jfunc
->type
= IPA_JF_PASS_THROUGH
;
534 jfunc
->value
.pass_through
.operand
= NULL_TREE
;
535 jfunc
->value
.pass_through
.formal_id
= formal_id
;
536 jfunc
->value
.pass_through
.operation
= NOP_EXPR
;
537 jfunc
->value
.pass_through
.agg_preserved
= agg_preserved
;
538 jfunc
->value
.pass_through
.type_preserved
= type_preserved
;
541 /* Set JFUNC to be an arithmetic pass through jump function. */
544 ipa_set_jf_arith_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
545 tree operand
, enum tree_code operation
)
547 jfunc
->type
= IPA_JF_PASS_THROUGH
;
548 jfunc
->value
.pass_through
.operand
= unshare_expr_without_location (operand
);
549 jfunc
->value
.pass_through
.formal_id
= formal_id
;
550 jfunc
->value
.pass_through
.operation
= operation
;
551 jfunc
->value
.pass_through
.agg_preserved
= false;
552 jfunc
->value
.pass_through
.type_preserved
= false;
555 /* Set JFUNC to be an ancestor jump function. */
558 ipa_set_ancestor_jf (struct ipa_jump_func
*jfunc
, HOST_WIDE_INT offset
,
559 tree type
, int formal_id
, bool agg_preserved
,
562 if (!flag_devirtualize
)
563 type_preserved
= false;
567 type
= TYPE_MAIN_VARIANT (type
);
568 if (!type
|| !contains_polymorphic_type_p (type
))
569 type_preserved
= false;
570 jfunc
->type
= IPA_JF_ANCESTOR
;
571 jfunc
->value
.ancestor
.formal_id
= formal_id
;
572 jfunc
->value
.ancestor
.offset
= offset
;
573 jfunc
->value
.ancestor
.type
= type_preserved
? type
: NULL
;
574 jfunc
->value
.ancestor
.agg_preserved
= agg_preserved
;
575 jfunc
->value
.ancestor
.type_preserved
= type_preserved
;
578 /* Extract the acual BINFO being described by JFUNC which must be a known type
582 ipa_binfo_from_known_type_jfunc (struct ipa_jump_func
*jfunc
)
584 if (!RECORD_OR_UNION_TYPE_P (jfunc
->value
.known_type
.base_type
))
587 tree base_binfo
= TYPE_BINFO (jfunc
->value
.known_type
.base_type
);
591 /* FIXME: At LTO we can't propagate to non-polymorphic type, because
592 we have no ODR equivalency on those. This should be fixed by
593 propagating on types rather than binfos that would make type
594 matching here unnecesary. */
596 && (TREE_CODE (jfunc
->value
.known_type
.component_type
) != RECORD_TYPE
597 || !TYPE_BINFO (jfunc
->value
.known_type
.component_type
)
598 || !BINFO_VTABLE (TYPE_BINFO (jfunc
->value
.known_type
.component_type
))))
600 if (!jfunc
->value
.known_type
.offset
)
604 return get_binfo_at_offset (base_binfo
,
605 jfunc
->value
.known_type
.offset
,
606 jfunc
->value
.known_type
.component_type
);
609 /* Get IPA BB information about the given BB. FBI is the context of analyzis
610 of this function body. */
612 static struct ipa_bb_info
*
613 ipa_get_bb_info (struct func_body_info
*fbi
, basic_block bb
)
615 gcc_checking_assert (fbi
);
616 return &fbi
->bb_infos
[bb
->index
];
619 /* Structure to be passed in between detect_type_change and
620 check_stmt_for_type_change. */
622 struct prop_type_change_info
624 /* Offset into the object where there is the virtual method pointer we are
626 HOST_WIDE_INT offset
;
627 /* The declaration or SSA_NAME pointer of the base that we are checking for
630 /* If we actually can tell the type that the object has changed to, it is
631 stored in this field. Otherwise it remains NULL_TREE. */
632 tree known_current_type
;
633 /* Set to true if dynamic type change has been detected. */
634 bool type_maybe_changed
;
635 /* Set to true if multiple types have been encountered. known_current_type
636 must be disregarded in that case. */
637 bool multiple_types_encountered
;
640 /* Return true if STMT can modify a virtual method table pointer.
642 This function makes special assumptions about both constructors and
643 destructors which are all the functions that are allowed to alter the VMT
644 pointers. It assumes that destructors begin with assignment into all VMT
645 pointers and that constructors essentially look in the following way:
647 1) The very first thing they do is that they call constructors of ancestor
648 sub-objects that have them.
650 2) Then VMT pointers of this and all its ancestors is set to new values
651 corresponding to the type corresponding to the constructor.
653 3) Only afterwards, other stuff such as constructor of member sub-objects
654 and the code written by the user is run. Only this may include calling
655 virtual functions, directly or indirectly.
657 There is no way to call a constructor of an ancestor sub-object in any
660 This means that we do not have to care whether constructors get the correct
661 type information because they will always change it (in fact, if we define
662 the type to be given by the VMT pointer, it is undefined).
664 The most important fact to derive from the above is that if, for some
665 statement in the section 3, we try to detect whether the dynamic type has
666 changed, we can safely ignore all calls as we examine the function body
667 backwards until we reach statements in section 2 because these calls cannot
668 be ancestor constructors or destructors (if the input is not bogus) and so
669 do not change the dynamic type (this holds true only for automatically
670 allocated objects but at the moment we devirtualize only these). We then
671 must detect that statements in section 2 change the dynamic type and can try
672 to derive the new type. That is enough and we can stop, we will never see
673 the calls into constructors of sub-objects in this code. Therefore we can
674 safely ignore all call statements that we traverse.
678 stmt_may_be_vtbl_ptr_store (gimple stmt
)
680 if (is_gimple_call (stmt
))
682 if (gimple_clobber_p (stmt
))
684 else if (is_gimple_assign (stmt
))
686 tree lhs
= gimple_assign_lhs (stmt
);
688 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs
)))
690 if (flag_strict_aliasing
691 && !POINTER_TYPE_P (TREE_TYPE (lhs
)))
694 if (TREE_CODE (lhs
) == COMPONENT_REF
695 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs
, 1)))
697 /* In the future we might want to use get_base_ref_and_offset to find
698 if there is a field corresponding to the offset and if so, proceed
699 almost like if it was a component ref. */
705 /* If STMT can be proved to be an assignment to the virtual method table
706 pointer of ANALYZED_OBJ and the type associated with the new table
707 identified, return the type. Otherwise return NULL_TREE. */
710 extr_type_from_vtbl_ptr_store (gimple stmt
, struct prop_type_change_info
*tci
)
712 HOST_WIDE_INT offset
, size
, max_size
;
713 tree lhs
, rhs
, base
, binfo
;
715 if (!gimple_assign_single_p (stmt
))
718 lhs
= gimple_assign_lhs (stmt
);
719 rhs
= gimple_assign_rhs1 (stmt
);
720 if (TREE_CODE (lhs
) != COMPONENT_REF
721 || !DECL_VIRTUAL_P (TREE_OPERAND (lhs
, 1)))
724 base
= get_ref_base_and_extent (lhs
, &offset
, &size
, &max_size
);
725 if (offset
!= tci
->offset
726 || size
!= POINTER_SIZE
727 || max_size
!= POINTER_SIZE
)
729 if (TREE_CODE (base
) == MEM_REF
)
731 if (TREE_CODE (tci
->object
) != MEM_REF
732 || TREE_OPERAND (tci
->object
, 0) != TREE_OPERAND (base
, 0)
733 || !tree_int_cst_equal (TREE_OPERAND (tci
->object
, 1),
734 TREE_OPERAND (base
, 1)))
737 else if (tci
->object
!= base
)
740 binfo
= vtable_pointer_value_to_binfo (rhs
);
742 /* FIXME: vtable_pointer_value_to_binfo may return BINFO of a
743 base of outer type. In this case we would need to either
744 work on binfos or translate it back to outer type and offset.
745 KNOWN_TYPE jump functions are not ready for that, yet. */
746 if (!binfo
|| TYPE_BINFO (BINFO_TYPE (binfo
)) != binfo
)
749 return BINFO_TYPE (binfo
);
752 /* Callback of walk_aliased_vdefs and a helper function for
753 detect_type_change to check whether a particular statement may modify
754 the virtual table pointer, and if possible also determine the new type of
755 the (sub-)object. It stores its result into DATA, which points to a
756 prop_type_change_info structure. */
759 check_stmt_for_type_change (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef
, void *data
)
761 gimple stmt
= SSA_NAME_DEF_STMT (vdef
);
762 struct prop_type_change_info
*tci
= (struct prop_type_change_info
*) data
;
764 if (stmt_may_be_vtbl_ptr_store (stmt
))
768 type
= extr_type_from_vtbl_ptr_store (stmt
, tci
);
769 gcc_assert (!type
|| TYPE_MAIN_VARIANT (type
) == type
);
770 if (tci
->type_maybe_changed
771 && type
!= tci
->known_current_type
)
772 tci
->multiple_types_encountered
= true;
773 tci
->known_current_type
= type
;
774 tci
->type_maybe_changed
= true;
781 /* See if ARG is PARAM_DECl describing instance passed by pointer
782 or reference in FUNCTION. Return false if the dynamic type may change
783 in between beggining of the function until CALL is invoked.
785 Generally functions are not allowed to change type of such instances,
786 but they call destructors. We assume that methods can not destroy the THIS
787 pointer. Also as a special cases, constructor and destructors may change
788 type of the THIS pointer. */
791 param_type_may_change_p (tree function
, tree arg
, gimple call
)
793 /* Pure functions can not do any changes on the dynamic type;
794 that require writting to memory. */
795 if (flags_from_decl_or_type (function
) & (ECF_PURE
| ECF_CONST
))
797 /* We need to check if we are within inlined consturctor
798 or destructor (ideally we would have way to check that the
799 inline cdtor is actually working on ARG, but we don't have
800 easy tie on this, so punt on all non-pure cdtors.
801 We may also record the types of cdtors and once we know type
802 of the instance match them.
804 Also code unification optimizations may merge calls from
805 different blocks making return values unreliable. So
806 do nothing during late optimization. */
807 if (DECL_STRUCT_FUNCTION (function
)->after_inlining
)
809 if (TREE_CODE (arg
) == SSA_NAME
810 && SSA_NAME_IS_DEFAULT_DEF (arg
)
811 && TREE_CODE (SSA_NAME_VAR (arg
)) == PARM_DECL
)
813 /* Normal (non-THIS) argument. */
814 if ((SSA_NAME_VAR (arg
) != DECL_ARGUMENTS (function
)
815 || TREE_CODE (TREE_TYPE (function
)) != METHOD_TYPE
)
816 /* THIS pointer of an method - here we we want to watch constructors
817 and destructors as those definitely may change the dynamic
819 || (TREE_CODE (TREE_TYPE (function
)) == METHOD_TYPE
820 && !DECL_CXX_CONSTRUCTOR_P (function
)
821 && !DECL_CXX_DESTRUCTOR_P (function
)
822 && (SSA_NAME_VAR (arg
) == DECL_ARGUMENTS (function
))))
824 /* Walk the inline stack and watch out for ctors/dtors. */
825 for (tree block
= gimple_block (call
); block
&& TREE_CODE (block
) == BLOCK
;
826 block
= BLOCK_SUPERCONTEXT (block
))
827 if (BLOCK_ABSTRACT_ORIGIN (block
)
828 && TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block
)) == FUNCTION_DECL
)
830 tree fn
= BLOCK_ABSTRACT_ORIGIN (block
);
832 if (flags_from_decl_or_type (fn
) & (ECF_PURE
| ECF_CONST
))
834 if (TREE_CODE (TREE_TYPE (fn
)) == METHOD_TYPE
835 && (DECL_CXX_CONSTRUCTOR_P (fn
)
836 || DECL_CXX_DESTRUCTOR_P (fn
)))
845 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
846 callsite CALL) by looking for assignments to its virtual table pointer. If
847 it is, return true and fill in the jump function JFUNC with relevant type
848 information or set it to unknown. ARG is the object itself (not a pointer
849 to it, unless dereferenced). BASE is the base of the memory access as
850 returned by get_ref_base_and_extent, as is the offset.
852 This is helper function for detect_type_change and detect_type_change_ssa
853 that does the heavy work which is usually unnecesary. */
856 detect_type_change_from_memory_writes (tree arg
, tree base
, tree comp_type
,
857 gimple call
, struct ipa_jump_func
*jfunc
,
858 HOST_WIDE_INT offset
)
860 struct prop_type_change_info tci
;
862 bool entry_reached
= false;
864 gcc_checking_assert (DECL_P (arg
)
865 || TREE_CODE (arg
) == MEM_REF
866 || handled_component_p (arg
));
868 comp_type
= TYPE_MAIN_VARIANT (comp_type
);
870 /* Const calls cannot call virtual methods through VMT and so type changes do
872 if (!flag_devirtualize
|| !gimple_vuse (call
)
873 /* Be sure expected_type is polymorphic. */
875 || TREE_CODE (comp_type
) != RECORD_TYPE
876 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type
))
877 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type
))))
880 ao_ref_init (&ao
, arg
);
883 ao
.size
= POINTER_SIZE
;
884 ao
.max_size
= ao
.size
;
887 tci
.object
= get_base_address (arg
);
888 tci
.known_current_type
= NULL_TREE
;
889 tci
.type_maybe_changed
= false;
890 tci
.multiple_types_encountered
= false;
892 walk_aliased_vdefs (&ao
, gimple_vuse (call
), check_stmt_for_type_change
,
893 &tci
, NULL
, &entry_reached
);
894 if (!tci
.type_maybe_changed
)
897 if (!tci
.known_current_type
898 || tci
.multiple_types_encountered
900 /* When the walk reached function entry, it means that type
901 is set along some paths but not along others. */
903 jfunc
->type
= IPA_JF_UNKNOWN
;
905 ipa_set_jf_known_type (jfunc
, 0, tci
.known_current_type
, comp_type
);
910 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
911 If it is, return true and fill in the jump function JFUNC with relevant type
912 information or set it to unknown. ARG is the object itself (not a pointer
913 to it, unless dereferenced). BASE is the base of the memory access as
914 returned by get_ref_base_and_extent, as is the offset. */
917 detect_type_change (tree arg
, tree base
, tree comp_type
, gimple call
,
918 struct ipa_jump_func
*jfunc
, HOST_WIDE_INT offset
)
920 if (!flag_devirtualize
)
923 if (TREE_CODE (base
) == MEM_REF
924 && !param_type_may_change_p (current_function_decl
,
925 TREE_OPERAND (base
, 0),
928 return detect_type_change_from_memory_writes (arg
, base
, comp_type
,
929 call
, jfunc
, offset
);
932 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
933 SSA name (its dereference will become the base and the offset is assumed to
937 detect_type_change_ssa (tree arg
, tree comp_type
,
938 gimple call
, struct ipa_jump_func
*jfunc
)
940 gcc_checking_assert (TREE_CODE (arg
) == SSA_NAME
);
941 if (!flag_devirtualize
942 || !POINTER_TYPE_P (TREE_TYPE (arg
)))
945 if (!param_type_may_change_p (current_function_decl
, arg
, call
))
948 arg
= build2 (MEM_REF
, ptr_type_node
, arg
,
949 build_int_cst (ptr_type_node
, 0));
951 return detect_type_change_from_memory_writes (arg
, arg
, comp_type
,
955 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
956 boolean variable pointed to by DATA. */
959 mark_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
962 bool *b
= (bool *) data
;
967 /* Return true if we have already walked so many statements in AA that we
968 should really just start giving up. */
971 aa_overwalked (struct func_body_info
*fbi
)
973 gcc_checking_assert (fbi
);
974 return fbi
->aa_walked
> (unsigned) PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS
);
977 /* Find the nearest valid aa status for parameter specified by INDEX that
980 static struct param_aa_status
*
981 find_dominating_aa_status (struct func_body_info
*fbi
, basic_block bb
,
986 bb
= get_immediate_dominator (CDI_DOMINATORS
, bb
);
989 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
990 if (!bi
->param_aa_statuses
.is_empty ()
991 && bi
->param_aa_statuses
[index
].valid
)
992 return &bi
->param_aa_statuses
[index
];
996 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
997 structures and/or intialize the result with a dominating description as
1000 static struct param_aa_status
*
1001 parm_bb_aa_status_for_bb (struct func_body_info
*fbi
, basic_block bb
,
1004 gcc_checking_assert (fbi
);
1005 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
1006 if (bi
->param_aa_statuses
.is_empty ())
1007 bi
->param_aa_statuses
.safe_grow_cleared (fbi
->param_count
);
1008 struct param_aa_status
*paa
= &bi
->param_aa_statuses
[index
];
1011 gcc_checking_assert (!paa
->parm_modified
1012 && !paa
->ref_modified
1013 && !paa
->pt_modified
);
1014 struct param_aa_status
*dom_paa
;
1015 dom_paa
= find_dominating_aa_status (fbi
, bb
, index
);
1025 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
1026 a value known not to be modified in this function before reaching the
1027 statement STMT. FBI holds information about the function we have so far
1028 gathered but do not survive the summary building stage. */
1031 parm_preserved_before_stmt_p (struct func_body_info
*fbi
, int index
,
1032 gimple stmt
, tree parm_load
)
1034 struct param_aa_status
*paa
;
1035 bool modified
= false;
1038 /* FIXME: FBI can be NULL if we are being called from outside
1039 ipa_node_analysis or ipcp_transform_function, which currently happens
1040 during inlining analysis. It would be great to extend fbi's lifetime and
1041 always have it. Currently, we are just not afraid of too much walking in
1045 if (aa_overwalked (fbi
))
1047 paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (stmt
), index
);
1048 if (paa
->parm_modified
)
1054 gcc_checking_assert (gimple_vuse (stmt
) != NULL_TREE
);
1055 ao_ref_init (&refd
, parm_load
);
1056 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), mark_modified
,
1059 fbi
->aa_walked
+= walked
;
1060 if (paa
&& modified
)
1061 paa
->parm_modified
= true;
1065 /* If STMT is an assignment that loads a value from an parameter declaration,
1066 return the index of the parameter in ipa_node_params which has not been
1067 modified. Otherwise return -1. */
1070 load_from_unmodified_param (struct func_body_info
*fbi
,
1071 vec
<ipa_param_descriptor
> descriptors
,
1077 if (!gimple_assign_single_p (stmt
))
1080 op1
= gimple_assign_rhs1 (stmt
);
1081 if (TREE_CODE (op1
) != PARM_DECL
)
1084 index
= ipa_get_param_decl_index_1 (descriptors
, op1
);
1086 || !parm_preserved_before_stmt_p (fbi
, index
, stmt
, op1
))
1092 /* Return true if memory reference REF (which must be a load through parameter
1093 with INDEX) loads data that are known to be unmodified in this function
1094 before reaching statement STMT. */
1097 parm_ref_data_preserved_p (struct func_body_info
*fbi
,
1098 int index
, gimple stmt
, tree ref
)
1100 struct param_aa_status
*paa
;
1101 bool modified
= false;
1104 /* FIXME: FBI can be NULL if we are being called from outside
1105 ipa_node_analysis or ipcp_transform_function, which currently happens
1106 during inlining analysis. It would be great to extend fbi's lifetime and
1107 always have it. Currently, we are just not afraid of too much walking in
1111 if (aa_overwalked (fbi
))
1113 paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (stmt
), index
);
1114 if (paa
->ref_modified
)
1120 gcc_checking_assert (gimple_vuse (stmt
));
1121 ao_ref_init (&refd
, ref
);
1122 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), mark_modified
,
1125 fbi
->aa_walked
+= walked
;
1126 if (paa
&& modified
)
1127 paa
->ref_modified
= true;
1131 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
1132 is known to be unmodified in this function before reaching call statement
1133 CALL into which it is passed. FBI describes the function body. */
1136 parm_ref_data_pass_through_p (struct func_body_info
*fbi
, int index
,
1137 gimple call
, tree parm
)
1139 bool modified
= false;
1142 /* It's unnecessary to calculate anything about memory contnets for a const
1143 function because it is not goin to use it. But do not cache the result
1144 either. Also, no such calculations for non-pointers. */
1145 if (!gimple_vuse (call
)
1146 || !POINTER_TYPE_P (TREE_TYPE (parm
))
1147 || aa_overwalked (fbi
))
1150 struct param_aa_status
*paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (call
),
1152 if (paa
->pt_modified
)
1155 ao_ref_init_from_ptr_and_size (&refd
, parm
, NULL_TREE
);
1156 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (call
), mark_modified
,
1158 fbi
->aa_walked
+= walked
;
1160 paa
->pt_modified
= true;
1164 /* Return true if we can prove that OP is a memory reference loading unmodified
1165 data from an aggregate passed as a parameter and if the aggregate is passed
1166 by reference, that the alias type of the load corresponds to the type of the
1167 formal parameter (so that we can rely on this type for TBAA in callers).
1168 INFO and PARMS_AINFO describe parameters of the current function (but the
1169 latter can be NULL), STMT is the load statement. If function returns true,
1170 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1171 within the aggregate and whether it is a load from a value passed by
1172 reference respectively. */
1175 ipa_load_from_parm_agg_1 (struct func_body_info
*fbi
,
1176 vec
<ipa_param_descriptor
> descriptors
,
1177 gimple stmt
, tree op
, int *index_p
,
1178 HOST_WIDE_INT
*offset_p
, HOST_WIDE_INT
*size_p
,
1182 HOST_WIDE_INT size
, max_size
;
1183 tree base
= get_ref_base_and_extent (op
, offset_p
, &size
, &max_size
);
1185 if (max_size
== -1 || max_size
!= size
|| *offset_p
< 0)
1190 int index
= ipa_get_param_decl_index_1 (descriptors
, base
);
1192 && parm_preserved_before_stmt_p (fbi
, index
, stmt
, op
))
1203 if (TREE_CODE (base
) != MEM_REF
1204 || TREE_CODE (TREE_OPERAND (base
, 0)) != SSA_NAME
1205 || !integer_zerop (TREE_OPERAND (base
, 1)))
1208 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base
, 0)))
1210 tree parm
= SSA_NAME_VAR (TREE_OPERAND (base
, 0));
1211 index
= ipa_get_param_decl_index_1 (descriptors
, parm
);
1215 /* This branch catches situations where a pointer parameter is not a
1216 gimple register, for example:
1218 void hip7(S*) (struct S * p)
1220 void (*<T2e4>) (struct S *) D.1867;
1225 D.1867_2 = p.1_1->f;
1230 gimple def
= SSA_NAME_DEF_STMT (TREE_OPERAND (base
, 0));
1231 index
= load_from_unmodified_param (fbi
, descriptors
, def
);
1235 && parm_ref_data_preserved_p (fbi
, index
, stmt
, op
))
1246 /* Just like the previous function, just without the param_analysis_info
1247 pointer, for users outside of this file. */
1250 ipa_load_from_parm_agg (struct ipa_node_params
*info
, gimple stmt
,
1251 tree op
, int *index_p
, HOST_WIDE_INT
*offset_p
,
1254 return ipa_load_from_parm_agg_1 (NULL
, info
->descriptors
, stmt
, op
, index_p
,
1255 offset_p
, NULL
, by_ref_p
);
1258 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1259 of an assignment statement STMT, try to determine whether we are actually
1260 handling any of the following cases and construct an appropriate jump
1261 function into JFUNC if so:
1263 1) The passed value is loaded from a formal parameter which is not a gimple
1264 register (most probably because it is addressable, the value has to be
1265 scalar) and we can guarantee the value has not changed. This case can
1266 therefore be described by a simple pass-through jump function. For example:
1275 2) The passed value can be described by a simple arithmetic pass-through
1282 D.2064_4 = a.1(D) + 4;
1285 This case can also occur in combination of the previous one, e.g.:
1293 D.2064_4 = a.0_3 + 4;
1296 3) The passed value is an address of an object within another one (which
1297 also passed by reference). Such situations are described by an ancestor
1298 jump function and describe situations such as:
1300 B::foo() (struct B * const this)
1304 D.1845_2 = &this_1(D)->D.1748;
1307 INFO is the structure describing individual parameters access different
1308 stages of IPA optimizations. PARMS_AINFO contains the information that is
1309 only needed for intraprocedural analysis. */
1312 compute_complex_assign_jump_func (struct func_body_info
*fbi
,
1313 struct ipa_node_params
*info
,
1314 struct ipa_jump_func
*jfunc
,
1315 gimple call
, gimple stmt
, tree name
,
1318 HOST_WIDE_INT offset
, size
, max_size
;
1319 tree op1
, tc_ssa
, base
, ssa
;
1322 op1
= gimple_assign_rhs1 (stmt
);
1324 if (TREE_CODE (op1
) == SSA_NAME
)
1326 if (SSA_NAME_IS_DEFAULT_DEF (op1
))
1327 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (op1
));
1329 index
= load_from_unmodified_param (fbi
, info
->descriptors
,
1330 SSA_NAME_DEF_STMT (op1
));
1335 index
= load_from_unmodified_param (fbi
, info
->descriptors
, stmt
);
1336 tc_ssa
= gimple_assign_lhs (stmt
);
1341 tree op2
= gimple_assign_rhs2 (stmt
);
1345 if (!is_gimple_ip_invariant (op2
)
1346 || (TREE_CODE_CLASS (gimple_expr_code (stmt
)) != tcc_comparison
1347 && !useless_type_conversion_p (TREE_TYPE (name
),
1351 ipa_set_jf_arith_pass_through (jfunc
, index
, op2
,
1352 gimple_assign_rhs_code (stmt
));
1354 else if (gimple_assign_single_p (stmt
))
1356 bool agg_p
= parm_ref_data_pass_through_p (fbi
, index
, call
, tc_ssa
);
1357 bool type_p
= false;
1359 if (param_type
&& POINTER_TYPE_P (param_type
))
1360 type_p
= !detect_type_change_ssa (tc_ssa
, TREE_TYPE (param_type
),
1362 if (type_p
|| jfunc
->type
== IPA_JF_UNKNOWN
)
1363 ipa_set_jf_simple_pass_through (jfunc
, index
, agg_p
, type_p
);
1368 if (TREE_CODE (op1
) != ADDR_EXPR
)
1370 op1
= TREE_OPERAND (op1
, 0);
1371 if (TREE_CODE (TREE_TYPE (op1
)) != RECORD_TYPE
)
1373 base
= get_ref_base_and_extent (op1
, &offset
, &size
, &max_size
);
1374 if (TREE_CODE (base
) != MEM_REF
1375 /* If this is a varying address, punt. */
1377 || max_size
!= size
)
1379 offset
+= mem_ref_offset (base
).to_short_addr () * BITS_PER_UNIT
;
1380 ssa
= TREE_OPERAND (base
, 0);
1381 if (TREE_CODE (ssa
) != SSA_NAME
1382 || !SSA_NAME_IS_DEFAULT_DEF (ssa
)
1386 /* Dynamic types are changed in constructors and destructors. */
1387 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (ssa
));
1388 if (index
>= 0 && param_type
&& POINTER_TYPE_P (param_type
))
1390 bool type_p
= (contains_polymorphic_type_p (TREE_TYPE (param_type
))
1391 && !detect_type_change (op1
, base
, TREE_TYPE (param_type
),
1392 call
, jfunc
, offset
));
1393 if (type_p
|| jfunc
->type
== IPA_JF_UNKNOWN
)
1394 ipa_set_ancestor_jf (jfunc
, offset
,
1395 type_p
? TREE_TYPE (param_type
) : NULL
, index
,
1396 parm_ref_data_pass_through_p (fbi
, index
,
1397 call
, ssa
), type_p
);
1401 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1404 iftmp.1_3 = &obj_2(D)->D.1762;
1406 The base of the MEM_REF must be a default definition SSA NAME of a
1407 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1408 whole MEM_REF expression is returned and the offset calculated from any
1409 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1410 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1413 get_ancestor_addr_info (gimple assign
, tree
*obj_p
, HOST_WIDE_INT
*offset
)
1415 HOST_WIDE_INT size
, max_size
;
1416 tree expr
, parm
, obj
;
1418 if (!gimple_assign_single_p (assign
))
1420 expr
= gimple_assign_rhs1 (assign
);
1422 if (TREE_CODE (expr
) != ADDR_EXPR
)
1424 expr
= TREE_OPERAND (expr
, 0);
1426 expr
= get_ref_base_and_extent (expr
, offset
, &size
, &max_size
);
1428 if (TREE_CODE (expr
) != MEM_REF
1429 /* If this is a varying address, punt. */
1434 parm
= TREE_OPERAND (expr
, 0);
1435 if (TREE_CODE (parm
) != SSA_NAME
1436 || !SSA_NAME_IS_DEFAULT_DEF (parm
)
1437 || TREE_CODE (SSA_NAME_VAR (parm
)) != PARM_DECL
)
1440 *offset
+= mem_ref_offset (expr
).to_short_addr () * BITS_PER_UNIT
;
1446 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1447 statement PHI, try to find out whether NAME is in fact a
1448 multiple-inheritance typecast from a descendant into an ancestor of a formal
1449 parameter and thus can be described by an ancestor jump function and if so,
1450 write the appropriate function into JFUNC.
1452 Essentially we want to match the following pattern:
1460 iftmp.1_3 = &obj_2(D)->D.1762;
1463 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1464 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1468 compute_complex_ancestor_jump_func (struct func_body_info
*fbi
,
1469 struct ipa_node_params
*info
,
1470 struct ipa_jump_func
*jfunc
,
1471 gimple call
, gimple phi
, tree param_type
)
1473 HOST_WIDE_INT offset
;
1474 gimple assign
, cond
;
1475 basic_block phi_bb
, assign_bb
, cond_bb
;
1476 tree tmp
, parm
, expr
, obj
;
1479 if (gimple_phi_num_args (phi
) != 2)
1482 if (integer_zerop (PHI_ARG_DEF (phi
, 1)))
1483 tmp
= PHI_ARG_DEF (phi
, 0);
1484 else if (integer_zerop (PHI_ARG_DEF (phi
, 0)))
1485 tmp
= PHI_ARG_DEF (phi
, 1);
1488 if (TREE_CODE (tmp
) != SSA_NAME
1489 || SSA_NAME_IS_DEFAULT_DEF (tmp
)
1490 || !POINTER_TYPE_P (TREE_TYPE (tmp
))
1491 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp
))) != RECORD_TYPE
)
1494 assign
= SSA_NAME_DEF_STMT (tmp
);
1495 assign_bb
= gimple_bb (assign
);
1496 if (!single_pred_p (assign_bb
))
1498 expr
= get_ancestor_addr_info (assign
, &obj
, &offset
);
1501 parm
= TREE_OPERAND (expr
, 0);
1502 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (parm
));
1506 cond_bb
= single_pred (assign_bb
);
1507 cond
= last_stmt (cond_bb
);
1509 || gimple_code (cond
) != GIMPLE_COND
1510 || gimple_cond_code (cond
) != NE_EXPR
1511 || gimple_cond_lhs (cond
) != parm
1512 || !integer_zerop (gimple_cond_rhs (cond
)))
1515 phi_bb
= gimple_bb (phi
);
1516 for (i
= 0; i
< 2; i
++)
1518 basic_block pred
= EDGE_PRED (phi_bb
, i
)->src
;
1519 if (pred
!= assign_bb
&& pred
!= cond_bb
)
1523 bool type_p
= false;
1524 if (param_type
&& POINTER_TYPE_P (param_type
)
1525 && contains_polymorphic_type_p (TREE_TYPE (param_type
)))
1526 type_p
= !detect_type_change (obj
, expr
, TREE_TYPE (param_type
),
1527 call
, jfunc
, offset
);
1528 if (type_p
|| jfunc
->type
== IPA_JF_UNKNOWN
)
1529 ipa_set_ancestor_jf (jfunc
, offset
, type_p
? TREE_TYPE (param_type
) : NULL
,
1531 parm_ref_data_pass_through_p (fbi
, index
, call
, parm
),
1535 /* Given OP which is passed as an actual argument to a called function,
1536 determine if it is possible to construct a KNOWN_TYPE jump function for it
1537 and if so, create one and store it to JFUNC.
1538 EXPECTED_TYPE represents a type the argument should be in */
1541 compute_known_type_jump_func (tree op
, struct ipa_jump_func
*jfunc
,
1542 gimple call
, tree expected_type
)
1544 HOST_WIDE_INT offset
, size
, max_size
;
1547 if (!flag_devirtualize
1548 || TREE_CODE (op
) != ADDR_EXPR
1549 || !contains_polymorphic_type_p (TREE_TYPE (TREE_TYPE (op
)))
1550 /* Be sure expected_type is polymorphic. */
1552 || !contains_polymorphic_type_p (expected_type
))
1555 op
= TREE_OPERAND (op
, 0);
1556 base
= get_ref_base_and_extent (op
, &offset
, &size
, &max_size
);
1560 || !contains_polymorphic_type_p (TREE_TYPE (base
)))
1563 if (decl_maybe_in_construction_p (base
, TREE_TYPE (base
),
1564 call
, current_function_decl
)
1565 /* Even if the var seems to be in construction by inline call stack,
1566 we may work out the actual type by walking memory writes. */
1567 && (is_global_var (base
)
1568 || detect_type_change (op
, base
, expected_type
, call
, jfunc
, offset
)))
1571 ipa_set_jf_known_type (jfunc
, offset
, TREE_TYPE (base
),
1575 /* Inspect the given TYPE and return true iff it has the same structure (the
1576 same number of fields of the same types) as a C++ member pointer. If
1577 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1578 corresponding fields there. */
1581 type_like_member_ptr_p (tree type
, tree
*method_ptr
, tree
*delta
)
1585 if (TREE_CODE (type
) != RECORD_TYPE
)
1588 fld
= TYPE_FIELDS (type
);
1589 if (!fld
|| !POINTER_TYPE_P (TREE_TYPE (fld
))
1590 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld
))) != METHOD_TYPE
1591 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
1597 fld
= DECL_CHAIN (fld
);
1598 if (!fld
|| INTEGRAL_TYPE_P (fld
)
1599 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
1604 if (DECL_CHAIN (fld
))
1610 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1611 return the rhs of its defining statement. Otherwise return RHS as it
1615 get_ssa_def_if_simple_copy (tree rhs
)
1617 while (TREE_CODE (rhs
) == SSA_NAME
&& !SSA_NAME_IS_DEFAULT_DEF (rhs
))
1619 gimple def_stmt
= SSA_NAME_DEF_STMT (rhs
);
1621 if (gimple_assign_single_p (def_stmt
))
1622 rhs
= gimple_assign_rhs1 (def_stmt
);
1629 /* Simple linked list, describing known contents of an aggregate beforere
1632 struct ipa_known_agg_contents_list
1634 /* Offset and size of the described part of the aggregate. */
1635 HOST_WIDE_INT offset
, size
;
1636 /* Known constant value or NULL if the contents is known to be unknown. */
1638 /* Pointer to the next structure in the list. */
1639 struct ipa_known_agg_contents_list
*next
;
1642 /* Find the proper place in linked list of ipa_known_agg_contents_list
1643 structures where to put a new one with the given LHS_OFFSET and LHS_SIZE,
1644 unless there is a partial overlap, in which case return NULL, or such
1645 element is already there, in which case set *ALREADY_THERE to true. */
1647 static struct ipa_known_agg_contents_list
**
1648 get_place_in_agg_contents_list (struct ipa_known_agg_contents_list
**list
,
1649 HOST_WIDE_INT lhs_offset
,
1650 HOST_WIDE_INT lhs_size
,
1651 bool *already_there
)
1653 struct ipa_known_agg_contents_list
**p
= list
;
1654 while (*p
&& (*p
)->offset
< lhs_offset
)
1656 if ((*p
)->offset
+ (*p
)->size
> lhs_offset
)
1661 if (*p
&& (*p
)->offset
< lhs_offset
+ lhs_size
)
1663 if ((*p
)->offset
== lhs_offset
&& (*p
)->size
== lhs_size
)
1664 /* We already know this value is subsequently overwritten with
1666 *already_there
= true;
1668 /* Otherwise this is a partial overlap which we cannot
1675 /* Build aggregate jump function from LIST, assuming there are exactly
1676 CONST_COUNT constant entries there and that th offset of the passed argument
1677 is ARG_OFFSET and store it into JFUNC. */
1680 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list
*list
,
1681 int const_count
, HOST_WIDE_INT arg_offset
,
1682 struct ipa_jump_func
*jfunc
)
1684 vec_alloc (jfunc
->agg
.items
, const_count
);
1689 struct ipa_agg_jf_item item
;
1690 item
.offset
= list
->offset
- arg_offset
;
1691 gcc_assert ((item
.offset
% BITS_PER_UNIT
) == 0);
1692 item
.value
= unshare_expr_without_location (list
->constant
);
1693 jfunc
->agg
.items
->quick_push (item
);
1699 /* Traverse statements from CALL backwards, scanning whether an aggregate given
1700 in ARG is filled in with constant values. ARG can either be an aggregate
1701 expression or a pointer to an aggregate. ARG_TYPE is the type of the
1702 aggregate. JFUNC is the jump function into which the constants are
1703 subsequently stored. */
1706 determine_locally_known_aggregate_parts (gimple call
, tree arg
, tree arg_type
,
1707 struct ipa_jump_func
*jfunc
)
1709 struct ipa_known_agg_contents_list
*list
= NULL
;
1710 int item_count
= 0, const_count
= 0;
1711 HOST_WIDE_INT arg_offset
, arg_size
;
1712 gimple_stmt_iterator gsi
;
1714 bool check_ref
, by_ref
;
1717 /* The function operates in three stages. First, we prepare check_ref, r,
1718 arg_base and arg_offset based on what is actually passed as an actual
1721 if (POINTER_TYPE_P (arg_type
))
1724 if (TREE_CODE (arg
) == SSA_NAME
)
1727 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type
))))
1732 type_size
= TYPE_SIZE (TREE_TYPE (arg_type
));
1733 arg_size
= tree_to_uhwi (type_size
);
1734 ao_ref_init_from_ptr_and_size (&r
, arg_base
, NULL_TREE
);
1736 else if (TREE_CODE (arg
) == ADDR_EXPR
)
1738 HOST_WIDE_INT arg_max_size
;
1740 arg
= TREE_OPERAND (arg
, 0);
1741 arg_base
= get_ref_base_and_extent (arg
, &arg_offset
, &arg_size
,
1743 if (arg_max_size
== -1
1744 || arg_max_size
!= arg_size
1747 if (DECL_P (arg_base
))
1750 ao_ref_init (&r
, arg_base
);
1760 HOST_WIDE_INT arg_max_size
;
1762 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg
)));
1766 arg_base
= get_ref_base_and_extent (arg
, &arg_offset
, &arg_size
,
1768 if (arg_max_size
== -1
1769 || arg_max_size
!= arg_size
1773 ao_ref_init (&r
, arg
);
1776 /* Second stage walks back the BB, looks at individual statements and as long
1777 as it is confident of how the statements affect contents of the
1778 aggregates, it builds a sorted linked list of ipa_agg_jf_list structures
1780 gsi
= gsi_for_stmt (call
);
1782 for (; !gsi_end_p (gsi
); gsi_prev (&gsi
))
1784 struct ipa_known_agg_contents_list
*n
, **p
;
1785 gimple stmt
= gsi_stmt (gsi
);
1786 HOST_WIDE_INT lhs_offset
, lhs_size
, lhs_max_size
;
1787 tree lhs
, rhs
, lhs_base
;
1789 if (!stmt_may_clobber_ref_p_1 (stmt
, &r
))
1791 if (!gimple_assign_single_p (stmt
))
1794 lhs
= gimple_assign_lhs (stmt
);
1795 rhs
= gimple_assign_rhs1 (stmt
);
1796 if (!is_gimple_reg_type (TREE_TYPE (rhs
))
1797 || TREE_CODE (lhs
) == BIT_FIELD_REF
1798 || contains_bitfld_component_ref_p (lhs
))
1801 lhs_base
= get_ref_base_and_extent (lhs
, &lhs_offset
, &lhs_size
,
1803 if (lhs_max_size
== -1
1804 || lhs_max_size
!= lhs_size
)
1809 if (TREE_CODE (lhs_base
) != MEM_REF
1810 || TREE_OPERAND (lhs_base
, 0) != arg_base
1811 || !integer_zerop (TREE_OPERAND (lhs_base
, 1)))
1814 else if (lhs_base
!= arg_base
)
1816 if (DECL_P (lhs_base
))
1822 bool already_there
= false;
1823 p
= get_place_in_agg_contents_list (&list
, lhs_offset
, lhs_size
,
1830 rhs
= get_ssa_def_if_simple_copy (rhs
);
1831 n
= XALLOCA (struct ipa_known_agg_contents_list
);
1833 n
->offset
= lhs_offset
;
1834 if (is_gimple_ip_invariant (rhs
))
1840 n
->constant
= NULL_TREE
;
1845 if (const_count
== PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS
)
1846 || item_count
== 2 * PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS
))
1850 /* Third stage just goes over the list and creates an appropriate vector of
1851 ipa_agg_jf_item structures out of it, of sourse only if there are
1852 any known constants to begin with. */
1856 jfunc
->agg
.by_ref
= by_ref
;
1857 build_agg_jump_func_from_list (list
, const_count
, arg_offset
, jfunc
);
1862 ipa_get_callee_param_type (struct cgraph_edge
*e
, int i
)
1865 tree type
= (e
->callee
1866 ? TREE_TYPE (e
->callee
->decl
)
1867 : gimple_call_fntype (e
->call_stmt
));
1868 tree t
= TYPE_ARG_TYPES (type
);
1870 for (n
= 0; n
< i
; n
++)
1877 return TREE_VALUE (t
);
1880 t
= DECL_ARGUMENTS (e
->callee
->decl
);
1881 for (n
= 0; n
< i
; n
++)
1888 return TREE_TYPE (t
);
1892 /* Compute jump function for all arguments of callsite CS and insert the
1893 information in the jump_functions array in the ipa_edge_args corresponding
1894 to this callsite. */
1897 ipa_compute_jump_functions_for_edge (struct func_body_info
*fbi
,
1898 struct cgraph_edge
*cs
)
1900 struct ipa_node_params
*info
= IPA_NODE_REF (cs
->caller
);
1901 struct ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
1902 gimple call
= cs
->call_stmt
;
1903 int n
, arg_num
= gimple_call_num_args (call
);
1904 bool useful_context
= false;
1906 if (arg_num
== 0 || args
->jump_functions
)
1908 vec_safe_grow_cleared (args
->jump_functions
, arg_num
);
1909 if (flag_devirtualize
)
1910 vec_safe_grow_cleared (args
->polymorphic_call_contexts
, arg_num
);
1912 if (gimple_call_internal_p (call
))
1914 if (ipa_func_spec_opts_forbid_analysis_p (cs
->caller
))
1917 for (n
= 0; n
< arg_num
; n
++)
1919 struct ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (args
, n
);
1920 tree arg
= gimple_call_arg (call
, n
);
1921 tree param_type
= ipa_get_callee_param_type (cs
, n
);
1922 if (flag_devirtualize
&& POINTER_TYPE_P (TREE_TYPE (arg
)))
1925 struct ipa_polymorphic_call_context
context (cs
->caller
->decl
,
1928 context
.get_dynamic_type (instance
, arg
, NULL
, cs
->call_stmt
);
1929 *ipa_get_ith_polymorhic_call_context (args
, n
) = context
;
1930 if (!context
.useless_p ())
1931 useful_context
= true;
1934 if (is_gimple_ip_invariant (arg
))
1935 ipa_set_jf_constant (jfunc
, arg
, cs
);
1936 else if (!is_gimple_reg_type (TREE_TYPE (arg
))
1937 && TREE_CODE (arg
) == PARM_DECL
)
1939 int index
= ipa_get_param_decl_index (info
, arg
);
1941 gcc_assert (index
>=0);
1942 /* Aggregate passed by value, check for pass-through, otherwise we
1943 will attempt to fill in aggregate contents later in this
1945 if (parm_preserved_before_stmt_p (fbi
, index
, call
, arg
))
1947 ipa_set_jf_simple_pass_through (jfunc
, index
, false, false);
1951 else if (TREE_CODE (arg
) == SSA_NAME
)
1953 if (SSA_NAME_IS_DEFAULT_DEF (arg
))
1955 int index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (arg
));
1959 agg_p
= parm_ref_data_pass_through_p (fbi
, index
, call
, arg
);
1960 if (param_type
&& POINTER_TYPE_P (param_type
))
1961 type_p
= !detect_type_change_ssa (arg
, TREE_TYPE (param_type
),
1965 if (type_p
|| jfunc
->type
== IPA_JF_UNKNOWN
)
1966 ipa_set_jf_simple_pass_through (jfunc
, index
, agg_p
,
1972 gimple stmt
= SSA_NAME_DEF_STMT (arg
);
1973 if (is_gimple_assign (stmt
))
1974 compute_complex_assign_jump_func (fbi
, info
, jfunc
,
1975 call
, stmt
, arg
, param_type
);
1976 else if (gimple_code (stmt
) == GIMPLE_PHI
)
1977 compute_complex_ancestor_jump_func (fbi
, info
, jfunc
,
1978 call
, stmt
, param_type
);
1982 compute_known_type_jump_func (arg
, jfunc
, call
,
1984 && POINTER_TYPE_P (param_type
)
1985 ? TREE_TYPE (param_type
)
1988 /* If ARG is pointer, we can not use its type to determine the type of aggregate
1989 passed (because type conversions are ignored in gimple). Usually we can
1990 safely get type from function declaration, but in case of K&R prototypes or
1991 variadic functions we can try our luck with type of the pointer passed.
1992 TODO: Since we look for actual initialization of the memory object, we may better
1993 work out the type based on the memory stores we find. */
1995 param_type
= TREE_TYPE (arg
);
1997 if ((jfunc
->type
!= IPA_JF_PASS_THROUGH
1998 || !ipa_get_jf_pass_through_agg_preserved (jfunc
))
1999 && (jfunc
->type
!= IPA_JF_ANCESTOR
2000 || !ipa_get_jf_ancestor_agg_preserved (jfunc
))
2001 && (AGGREGATE_TYPE_P (TREE_TYPE (arg
))
2002 || POINTER_TYPE_P (param_type
)))
2003 determine_locally_known_aggregate_parts (call
, arg
, param_type
, jfunc
);
2005 if (!useful_context
)
2006 vec_free (args
->polymorphic_call_contexts
);
2009 /* Compute jump functions for all edges - both direct and indirect - outgoing
2013 ipa_compute_jump_functions_for_bb (struct func_body_info
*fbi
, basic_block bb
)
2015 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
2017 struct cgraph_edge
*cs
;
2019 FOR_EACH_VEC_ELT_REVERSE (bi
->cg_edges
, i
, cs
)
2021 struct cgraph_node
*callee
= cs
->callee
;
2025 callee
->ultimate_alias_target ();
2026 /* We do not need to bother analyzing calls to unknown functions
2027 unless they may become known during lto/whopr. */
2028 if (!callee
->definition
&& !flag_lto
)
2031 ipa_compute_jump_functions_for_edge (fbi
, cs
);
2035 /* If STMT looks like a statement loading a value from a member pointer formal
2036 parameter, return that parameter and store the offset of the field to
2037 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
2038 might be clobbered). If USE_DELTA, then we look for a use of the delta
2039 field rather than the pfn. */
2042 ipa_get_stmt_member_ptr_load_param (gimple stmt
, bool use_delta
,
2043 HOST_WIDE_INT
*offset_p
)
2045 tree rhs
, rec
, ref_field
, ref_offset
, fld
, ptr_field
, delta_field
;
2047 if (!gimple_assign_single_p (stmt
))
2050 rhs
= gimple_assign_rhs1 (stmt
);
2051 if (TREE_CODE (rhs
) == COMPONENT_REF
)
2053 ref_field
= TREE_OPERAND (rhs
, 1);
2054 rhs
= TREE_OPERAND (rhs
, 0);
2057 ref_field
= NULL_TREE
;
2058 if (TREE_CODE (rhs
) != MEM_REF
)
2060 rec
= TREE_OPERAND (rhs
, 0);
2061 if (TREE_CODE (rec
) != ADDR_EXPR
)
2063 rec
= TREE_OPERAND (rec
, 0);
2064 if (TREE_CODE (rec
) != PARM_DECL
2065 || !type_like_member_ptr_p (TREE_TYPE (rec
), &ptr_field
, &delta_field
))
2067 ref_offset
= TREE_OPERAND (rhs
, 1);
2074 *offset_p
= int_bit_position (fld
);
2078 if (integer_nonzerop (ref_offset
))
2080 return ref_field
== fld
? rec
: NULL_TREE
;
2083 return tree_int_cst_equal (byte_position (fld
), ref_offset
) ? rec
2087 /* Returns true iff T is an SSA_NAME defined by a statement. */
2090 ipa_is_ssa_with_stmt_def (tree t
)
2092 if (TREE_CODE (t
) == SSA_NAME
2093 && !SSA_NAME_IS_DEFAULT_DEF (t
))
2099 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2100 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2101 indirect call graph edge. */
2103 static struct cgraph_edge
*
2104 ipa_note_param_call (struct cgraph_node
*node
, int param_index
, gimple stmt
)
2106 struct cgraph_edge
*cs
;
2108 cs
= node
->get_edge (stmt
);
2109 cs
->indirect_info
->param_index
= param_index
;
2110 cs
->indirect_info
->agg_contents
= 0;
2111 cs
->indirect_info
->member_ptr
= 0;
2115 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2116 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2117 intermediate information about each formal parameter. Currently it checks
2118 whether the call calls a pointer that is a formal parameter and if so, the
2119 parameter is marked with the called flag and an indirect call graph edge
2120 describing the call is created. This is very simple for ordinary pointers
2121 represented in SSA but not-so-nice when it comes to member pointers. The
2122 ugly part of this function does nothing more than trying to match the
2123 pattern of such a call. An example of such a pattern is the gimple dump
2124 below, the call is on the last line:
2127 f$__delta_5 = f.__delta;
2128 f$__pfn_24 = f.__pfn;
2132 f$__delta_5 = MEM[(struct *)&f];
2133 f$__pfn_24 = MEM[(struct *)&f + 4B];
2135 and a few lines below:
2138 D.2496_3 = (int) f$__pfn_24;
2139 D.2497_4 = D.2496_3 & 1;
2146 D.2500_7 = (unsigned int) f$__delta_5;
2147 D.2501_8 = &S + D.2500_7;
2148 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2149 D.2503_10 = *D.2502_9;
2150 D.2504_12 = f$__pfn_24 + -1;
2151 D.2505_13 = (unsigned int) D.2504_12;
2152 D.2506_14 = D.2503_10 + D.2505_13;
2153 D.2507_15 = *D.2506_14;
2154 iftmp.11_16 = (String:: *) D.2507_15;
2157 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2158 D.2500_19 = (unsigned int) f$__delta_5;
2159 D.2508_20 = &S + D.2500_19;
2160 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2162 Such patterns are results of simple calls to a member pointer:
2164 int doprinting (int (MyString::* f)(int) const)
2166 MyString S ("somestring");
2171 Moreover, the function also looks for called pointers loaded from aggregates
2172 passed by value or reference. */
2175 ipa_analyze_indirect_call_uses (struct func_body_info
*fbi
, gimple call
,
2178 struct ipa_node_params
*info
= fbi
->info
;
2179 HOST_WIDE_INT offset
;
2182 if (SSA_NAME_IS_DEFAULT_DEF (target
))
2184 tree var
= SSA_NAME_VAR (target
);
2185 int index
= ipa_get_param_decl_index (info
, var
);
2187 ipa_note_param_call (fbi
->node
, index
, call
);
2192 gimple def
= SSA_NAME_DEF_STMT (target
);
2193 if (gimple_assign_single_p (def
)
2194 && ipa_load_from_parm_agg_1 (fbi
, info
->descriptors
, def
,
2195 gimple_assign_rhs1 (def
), &index
, &offset
,
2198 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
, call
);
2199 cs
->indirect_info
->offset
= offset
;
2200 cs
->indirect_info
->agg_contents
= 1;
2201 cs
->indirect_info
->by_ref
= by_ref
;
2205 /* Now we need to try to match the complex pattern of calling a member
2207 if (gimple_code (def
) != GIMPLE_PHI
2208 || gimple_phi_num_args (def
) != 2
2209 || !POINTER_TYPE_P (TREE_TYPE (target
))
2210 || TREE_CODE (TREE_TYPE (TREE_TYPE (target
))) != METHOD_TYPE
)
2213 /* First, we need to check whether one of these is a load from a member
2214 pointer that is a parameter to this function. */
2215 tree n1
= PHI_ARG_DEF (def
, 0);
2216 tree n2
= PHI_ARG_DEF (def
, 1);
2217 if (!ipa_is_ssa_with_stmt_def (n1
) || !ipa_is_ssa_with_stmt_def (n2
))
2219 gimple d1
= SSA_NAME_DEF_STMT (n1
);
2220 gimple d2
= SSA_NAME_DEF_STMT (n2
);
2223 basic_block bb
, virt_bb
;
2224 basic_block join
= gimple_bb (def
);
2225 if ((rec
= ipa_get_stmt_member_ptr_load_param (d1
, false, &offset
)))
2227 if (ipa_get_stmt_member_ptr_load_param (d2
, false, NULL
))
2230 bb
= EDGE_PRED (join
, 0)->src
;
2231 virt_bb
= gimple_bb (d2
);
2233 else if ((rec
= ipa_get_stmt_member_ptr_load_param (d2
, false, &offset
)))
2235 bb
= EDGE_PRED (join
, 1)->src
;
2236 virt_bb
= gimple_bb (d1
);
2241 /* Second, we need to check that the basic blocks are laid out in the way
2242 corresponding to the pattern. */
2244 if (!single_pred_p (virt_bb
) || !single_succ_p (virt_bb
)
2245 || single_pred (virt_bb
) != bb
2246 || single_succ (virt_bb
) != join
)
2249 /* Third, let's see that the branching is done depending on the least
2250 significant bit of the pfn. */
2252 gimple branch
= last_stmt (bb
);
2253 if (!branch
|| gimple_code (branch
) != GIMPLE_COND
)
2256 if ((gimple_cond_code (branch
) != NE_EXPR
2257 && gimple_cond_code (branch
) != EQ_EXPR
)
2258 || !integer_zerop (gimple_cond_rhs (branch
)))
2261 tree cond
= gimple_cond_lhs (branch
);
2262 if (!ipa_is_ssa_with_stmt_def (cond
))
2265 def
= SSA_NAME_DEF_STMT (cond
);
2266 if (!is_gimple_assign (def
)
2267 || gimple_assign_rhs_code (def
) != BIT_AND_EXPR
2268 || !integer_onep (gimple_assign_rhs2 (def
)))
2271 cond
= gimple_assign_rhs1 (def
);
2272 if (!ipa_is_ssa_with_stmt_def (cond
))
2275 def
= SSA_NAME_DEF_STMT (cond
);
2277 if (is_gimple_assign (def
)
2278 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def
)))
2280 cond
= gimple_assign_rhs1 (def
);
2281 if (!ipa_is_ssa_with_stmt_def (cond
))
2283 def
= SSA_NAME_DEF_STMT (cond
);
2287 rec2
= ipa_get_stmt_member_ptr_load_param (def
,
2288 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2289 == ptrmemfunc_vbit_in_delta
),
2294 index
= ipa_get_param_decl_index (info
, rec
);
2296 && parm_preserved_before_stmt_p (fbi
, index
, call
, rec
))
2298 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
, call
);
2299 cs
->indirect_info
->offset
= offset
;
2300 cs
->indirect_info
->agg_contents
= 1;
2301 cs
->indirect_info
->member_ptr
= 1;
2307 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2308 object referenced in the expression is a formal parameter of the caller
2309 FBI->node (described by FBI->info), create a call note for the
2313 ipa_analyze_virtual_call_uses (struct func_body_info
*fbi
,
2314 gimple call
, tree target
)
2316 tree obj
= OBJ_TYPE_REF_OBJECT (target
);
2318 HOST_WIDE_INT anc_offset
;
2320 if (!flag_devirtualize
)
2323 if (TREE_CODE (obj
) != SSA_NAME
)
2326 struct ipa_node_params
*info
= fbi
->info
;
2327 if (SSA_NAME_IS_DEFAULT_DEF (obj
))
2329 struct ipa_jump_func jfunc
;
2330 if (TREE_CODE (SSA_NAME_VAR (obj
)) != PARM_DECL
)
2334 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (obj
));
2335 gcc_assert (index
>= 0);
2336 if (detect_type_change_ssa (obj
, obj_type_ref_class (target
),
2342 struct ipa_jump_func jfunc
;
2343 gimple stmt
= SSA_NAME_DEF_STMT (obj
);
2346 expr
= get_ancestor_addr_info (stmt
, &obj
, &anc_offset
);
2349 index
= ipa_get_param_decl_index (info
,
2350 SSA_NAME_VAR (TREE_OPERAND (expr
, 0)));
2351 gcc_assert (index
>= 0);
2352 if (detect_type_change (obj
, expr
, obj_type_ref_class (target
),
2353 call
, &jfunc
, anc_offset
))
2357 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
, call
);
2358 struct cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
2359 ii
->offset
= anc_offset
;
2360 ii
->otr_token
= tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target
));
2361 ii
->otr_type
= obj_type_ref_class (target
);
2362 ii
->polymorphic
= 1;
2365 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2366 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2367 containing intermediate information about each formal parameter. */
2370 ipa_analyze_call_uses (struct func_body_info
*fbi
, gimple call
)
2372 tree target
= gimple_call_fn (call
);
2375 || (TREE_CODE (target
) != SSA_NAME
2376 && !virtual_method_call_p (target
)))
2379 struct cgraph_edge
*cs
= fbi
->node
->get_edge (call
);
2380 /* If we previously turned the call into a direct call, there is
2381 no need to analyze. */
2382 if (cs
&& !cs
->indirect_unknown_callee
)
2385 if (cs
->indirect_info
->polymorphic
)
2388 tree target
= gimple_call_fn (call
);
2389 ipa_polymorphic_call_context
context (current_function_decl
,
2390 target
, call
, &instance
);
2392 gcc_checking_assert (cs
->indirect_info
->otr_type
2393 == obj_type_ref_class (target
));
2394 gcc_checking_assert (cs
->indirect_info
->otr_token
2395 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target
)));
2397 cs
->indirect_info
->vptr_changed
2398 = !context
.get_dynamic_type (instance
,
2399 OBJ_TYPE_REF_OBJECT (target
),
2400 obj_type_ref_class (target
), call
);
2401 cs
->indirect_info
->context
= context
;
2404 if (TREE_CODE (target
) == SSA_NAME
)
2405 ipa_analyze_indirect_call_uses (fbi
, call
, target
);
2406 else if (virtual_method_call_p (target
))
2407 ipa_analyze_virtual_call_uses (fbi
, call
, target
);
2411 /* Analyze the call statement STMT with respect to formal parameters (described
2412 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2413 formal parameters are called. */
2416 ipa_analyze_stmt_uses (struct func_body_info
*fbi
, gimple stmt
)
2418 if (is_gimple_call (stmt
))
2419 ipa_analyze_call_uses (fbi
, stmt
);
2422 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2423 If OP is a parameter declaration, mark it as used in the info structure
2427 visit_ref_for_mod_analysis (gimple
, tree op
, tree
, void *data
)
2429 struct ipa_node_params
*info
= (struct ipa_node_params
*) data
;
2431 op
= get_base_address (op
);
2433 && TREE_CODE (op
) == PARM_DECL
)
2435 int index
= ipa_get_param_decl_index (info
, op
);
2436 gcc_assert (index
>= 0);
2437 ipa_set_param_used (info
, index
, true);
2443 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2444 the findings in various structures of the associated ipa_node_params
2445 structure, such as parameter flags, notes etc. FBI holds various data about
2446 the function being analyzed. */
2449 ipa_analyze_params_uses_in_bb (struct func_body_info
*fbi
, basic_block bb
)
2451 gimple_stmt_iterator gsi
;
2452 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2454 gimple stmt
= gsi_stmt (gsi
);
2456 if (is_gimple_debug (stmt
))
2459 ipa_analyze_stmt_uses (fbi
, stmt
);
2460 walk_stmt_load_store_addr_ops (stmt
, fbi
->info
,
2461 visit_ref_for_mod_analysis
,
2462 visit_ref_for_mod_analysis
,
2463 visit_ref_for_mod_analysis
);
2465 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2466 walk_stmt_load_store_addr_ops (gsi_stmt (gsi
), fbi
->info
,
2467 visit_ref_for_mod_analysis
,
2468 visit_ref_for_mod_analysis
,
2469 visit_ref_for_mod_analysis
);
2472 /* Calculate controlled uses of parameters of NODE. */
2475 ipa_analyze_controlled_uses (struct cgraph_node
*node
)
2477 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
2479 for (int i
= 0; i
< ipa_get_param_count (info
); i
++)
2481 tree parm
= ipa_get_param (info
, i
);
2482 int controlled_uses
= 0;
2484 /* For SSA regs see if parameter is used. For non-SSA we compute
2485 the flag during modification analysis. */
2486 if (is_gimple_reg (parm
))
2488 tree ddef
= ssa_default_def (DECL_STRUCT_FUNCTION (node
->decl
),
2490 if (ddef
&& !has_zero_uses (ddef
))
2492 imm_use_iterator imm_iter
;
2493 use_operand_p use_p
;
2495 ipa_set_param_used (info
, i
, true);
2496 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, ddef
)
2497 if (!is_gimple_call (USE_STMT (use_p
)))
2499 if (!is_gimple_debug (USE_STMT (use_p
)))
2501 controlled_uses
= IPA_UNDESCRIBED_USE
;
2509 controlled_uses
= 0;
2512 controlled_uses
= IPA_UNDESCRIBED_USE
;
2513 ipa_set_controlled_uses (info
, i
, controlled_uses
);
2517 /* Free stuff in BI. */
2520 free_ipa_bb_info (struct ipa_bb_info
*bi
)
2522 bi
->cg_edges
.release ();
2523 bi
->param_aa_statuses
.release ();
2526 /* Dominator walker driving the analysis. */
2528 class analysis_dom_walker
: public dom_walker
2531 analysis_dom_walker (struct func_body_info
*fbi
)
2532 : dom_walker (CDI_DOMINATORS
), m_fbi (fbi
) {}
2534 virtual void before_dom_children (basic_block
);
2537 struct func_body_info
*m_fbi
;
2541 analysis_dom_walker::before_dom_children (basic_block bb
)
2543 ipa_analyze_params_uses_in_bb (m_fbi
, bb
);
2544 ipa_compute_jump_functions_for_bb (m_fbi
, bb
);
2547 /* Initialize the array describing properties of of formal parameters
2548 of NODE, analyze their uses and compute jump functions associated
2549 with actual arguments of calls from within NODE. */
2552 ipa_analyze_node (struct cgraph_node
*node
)
2554 struct func_body_info fbi
;
2555 struct ipa_node_params
*info
;
2557 ipa_check_create_node_params ();
2558 ipa_check_create_edge_args ();
2559 info
= IPA_NODE_REF (node
);
2561 if (info
->analysis_done
)
2563 info
->analysis_done
= 1;
2565 if (ipa_func_spec_opts_forbid_analysis_p (node
))
2567 for (int i
= 0; i
< ipa_get_param_count (info
); i
++)
2569 ipa_set_param_used (info
, i
, true);
2570 ipa_set_controlled_uses (info
, i
, IPA_UNDESCRIBED_USE
);
2575 struct function
*func
= DECL_STRUCT_FUNCTION (node
->decl
);
2577 calculate_dominance_info (CDI_DOMINATORS
);
2578 ipa_initialize_node_params (node
);
2579 ipa_analyze_controlled_uses (node
);
2582 fbi
.info
= IPA_NODE_REF (node
);
2583 fbi
.bb_infos
= vNULL
;
2584 fbi
.bb_infos
.safe_grow_cleared (last_basic_block_for_fn (cfun
));
2585 fbi
.param_count
= ipa_get_param_count (info
);
2588 for (struct cgraph_edge
*cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
2590 ipa_bb_info
*bi
= ipa_get_bb_info (&fbi
, gimple_bb (cs
->call_stmt
));
2591 bi
->cg_edges
.safe_push (cs
);
2594 for (struct cgraph_edge
*cs
= node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
2596 ipa_bb_info
*bi
= ipa_get_bb_info (&fbi
, gimple_bb (cs
->call_stmt
));
2597 bi
->cg_edges
.safe_push (cs
);
2600 analysis_dom_walker (&fbi
).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
2603 struct ipa_bb_info
*bi
;
2604 FOR_EACH_VEC_ELT (fbi
.bb_infos
, i
, bi
)
2605 free_ipa_bb_info (bi
);
2606 fbi
.bb_infos
.release ();
2607 free_dominance_info (CDI_DOMINATORS
);
2611 /* Update the jump function DST when the call graph edge corresponding to SRC is
2612 is being inlined, knowing that DST is of type ancestor and src of known
2616 combine_known_type_and_ancestor_jfs (struct ipa_jump_func
*src
,
2617 struct ipa_jump_func
*dst
)
2619 HOST_WIDE_INT combined_offset
;
2622 if (!ipa_get_jf_ancestor_type_preserved (dst
))
2624 dst
->type
= IPA_JF_UNKNOWN
;
2628 combined_offset
= ipa_get_jf_known_type_offset (src
)
2629 + ipa_get_jf_ancestor_offset (dst
);
2630 combined_type
= ipa_get_jf_ancestor_type (dst
);
2633 ipa_set_jf_known_type (dst
, combined_offset
,
2634 ipa_get_jf_known_type_base_type (src
),
2637 dst
->type
= IPA_JF_UNKNOWN
;
2640 /* Update the jump functions associated with call graph edge E when the call
2641 graph edge CS is being inlined, assuming that E->caller is already (possibly
2642 indirectly) inlined into CS->callee and that E has not been inlined. */
2645 update_jump_functions_after_inlining (struct cgraph_edge
*cs
,
2646 struct cgraph_edge
*e
)
2648 struct ipa_edge_args
*top
= IPA_EDGE_REF (cs
);
2649 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
2650 int count
= ipa_get_cs_argument_count (args
);
2653 for (i
= 0; i
< count
; i
++)
2655 struct ipa_jump_func
*dst
= ipa_get_ith_jump_func (args
, i
);
2656 struct ipa_polymorphic_call_context
*dst_ctx
2657 = ipa_get_ith_polymorhic_call_context (args
, i
);
2659 if (dst
->type
== IPA_JF_ANCESTOR
)
2661 struct ipa_jump_func
*src
;
2662 int dst_fid
= dst
->value
.ancestor
.formal_id
;
2663 struct ipa_polymorphic_call_context
*src_ctx
2664 = ipa_get_ith_polymorhic_call_context (top
, dst_fid
);
2666 /* Variable number of arguments can cause havoc if we try to access
2667 one that does not exist in the inlined edge. So make sure we
2669 if (dst_fid
>= ipa_get_cs_argument_count (top
))
2671 dst
->type
= IPA_JF_UNKNOWN
;
2675 src
= ipa_get_ith_jump_func (top
, dst_fid
);
2677 if (src_ctx
&& !src_ctx
->useless_p ())
2679 struct ipa_polymorphic_call_context ctx
= *src_ctx
;
2681 /* TODO: Make type preserved safe WRT contexts. */
2682 if (!ipa_get_jf_ancestor_type_preserved (dst
))
2683 ctx
.possible_dynamic_type_change (e
->in_polymorphic_cdtor
);
2684 ctx
.offset_by (dst
->value
.ancestor
.offset
);
2685 if (!ctx
.useless_p ())
2687 vec_safe_grow_cleared (args
->polymorphic_call_contexts
,
2689 dst_ctx
= ipa_get_ith_polymorhic_call_context (args
, i
);
2691 dst_ctx
->combine_with (ctx
);
2695 && (dst
->value
.ancestor
.agg_preserved
|| !src
->agg
.by_ref
))
2697 struct ipa_agg_jf_item
*item
;
2700 /* Currently we do not produce clobber aggregate jump functions,
2701 replace with merging when we do. */
2702 gcc_assert (!dst
->agg
.items
);
2704 dst
->agg
.items
= vec_safe_copy (src
->agg
.items
);
2705 dst
->agg
.by_ref
= src
->agg
.by_ref
;
2706 FOR_EACH_VEC_SAFE_ELT (dst
->agg
.items
, j
, item
)
2707 item
->offset
-= dst
->value
.ancestor
.offset
;
2710 if (src
->type
== IPA_JF_KNOWN_TYPE
)
2711 combine_known_type_and_ancestor_jfs (src
, dst
);
2712 else if (src
->type
== IPA_JF_PASS_THROUGH
2713 && src
->value
.pass_through
.operation
== NOP_EXPR
)
2715 dst
->value
.ancestor
.formal_id
= src
->value
.pass_through
.formal_id
;
2716 dst
->value
.ancestor
.agg_preserved
&=
2717 src
->value
.pass_through
.agg_preserved
;
2718 dst
->value
.ancestor
.type_preserved
&=
2719 src
->value
.pass_through
.type_preserved
;
2721 else if (src
->type
== IPA_JF_ANCESTOR
)
2723 dst
->value
.ancestor
.formal_id
= src
->value
.ancestor
.formal_id
;
2724 dst
->value
.ancestor
.offset
+= src
->value
.ancestor
.offset
;
2725 dst
->value
.ancestor
.agg_preserved
&=
2726 src
->value
.ancestor
.agg_preserved
;
2727 dst
->value
.ancestor
.type_preserved
&=
2728 src
->value
.ancestor
.type_preserved
;
2731 dst
->type
= IPA_JF_UNKNOWN
;
2733 else if (dst
->type
== IPA_JF_PASS_THROUGH
)
2735 struct ipa_jump_func
*src
;
2736 /* We must check range due to calls with variable number of arguments
2737 and we cannot combine jump functions with operations. */
2738 if (dst
->value
.pass_through
.operation
== NOP_EXPR
2739 && (dst
->value
.pass_through
.formal_id
2740 < ipa_get_cs_argument_count (top
)))
2742 int dst_fid
= dst
->value
.pass_through
.formal_id
;
2743 src
= ipa_get_ith_jump_func (top
, dst_fid
);
2744 bool dst_agg_p
= ipa_get_jf_pass_through_agg_preserved (dst
);
2745 struct ipa_polymorphic_call_context
*src_ctx
2746 = ipa_get_ith_polymorhic_call_context (top
, dst_fid
);
2748 if (src_ctx
&& !src_ctx
->useless_p ())
2750 struct ipa_polymorphic_call_context ctx
= *src_ctx
;
2752 /* TODO: Make type preserved safe WRT contexts. */
2753 if (!ipa_get_jf_pass_through_type_preserved (dst
))
2754 ctx
.possible_dynamic_type_change (e
->in_polymorphic_cdtor
);
2755 if (!ctx
.useless_p ())
2759 vec_safe_grow_cleared (args
->polymorphic_call_contexts
,
2761 dst_ctx
= ipa_get_ith_polymorhic_call_context (args
, i
);
2763 dst_ctx
->combine_with (ctx
);
2768 case IPA_JF_UNKNOWN
:
2769 dst
->type
= IPA_JF_UNKNOWN
;
2771 case IPA_JF_KNOWN_TYPE
:
2772 if (ipa_get_jf_pass_through_type_preserved (dst
))
2773 ipa_set_jf_known_type (dst
,
2774 ipa_get_jf_known_type_offset (src
),
2775 ipa_get_jf_known_type_base_type (src
),
2776 ipa_get_jf_known_type_component_type (src
));
2778 dst
->type
= IPA_JF_UNKNOWN
;
2781 ipa_set_jf_cst_copy (dst
, src
);
2784 case IPA_JF_PASS_THROUGH
:
2786 int formal_id
= ipa_get_jf_pass_through_formal_id (src
);
2787 enum tree_code operation
;
2788 operation
= ipa_get_jf_pass_through_operation (src
);
2790 if (operation
== NOP_EXPR
)
2794 && ipa_get_jf_pass_through_agg_preserved (src
);
2795 type_p
= ipa_get_jf_pass_through_type_preserved (src
)
2796 && ipa_get_jf_pass_through_type_preserved (dst
);
2797 ipa_set_jf_simple_pass_through (dst
, formal_id
,
2802 tree operand
= ipa_get_jf_pass_through_operand (src
);
2803 ipa_set_jf_arith_pass_through (dst
, formal_id
, operand
,
2808 case IPA_JF_ANCESTOR
:
2812 && ipa_get_jf_ancestor_agg_preserved (src
);
2813 type_p
= ipa_get_jf_ancestor_type_preserved (src
)
2814 && ipa_get_jf_pass_through_type_preserved (dst
);
2815 ipa_set_ancestor_jf (dst
,
2816 ipa_get_jf_ancestor_offset (src
),
2817 ipa_get_jf_ancestor_type (src
),
2818 ipa_get_jf_ancestor_formal_id (src
),
2827 && (dst_agg_p
|| !src
->agg
.by_ref
))
2829 /* Currently we do not produce clobber aggregate jump
2830 functions, replace with merging when we do. */
2831 gcc_assert (!dst
->agg
.items
);
2833 dst
->agg
.by_ref
= src
->agg
.by_ref
;
2834 dst
->agg
.items
= vec_safe_copy (src
->agg
.items
);
2838 dst
->type
= IPA_JF_UNKNOWN
;
2843 /* If TARGET is an addr_expr of a function declaration, make it the
2844 (SPECULATIVE)destination of an indirect edge IE and return the edge.
2845 Otherwise, return NULL. */
2847 struct cgraph_edge
*
2848 ipa_make_edge_direct_to_target (struct cgraph_edge
*ie
, tree target
,
2851 struct cgraph_node
*callee
;
2852 struct inline_edge_summary
*es
= inline_edge_summary (ie
);
2853 bool unreachable
= false;
2855 if (TREE_CODE (target
) == ADDR_EXPR
)
2856 target
= TREE_OPERAND (target
, 0);
2857 if (TREE_CODE (target
) != FUNCTION_DECL
)
2859 target
= canonicalize_constructor_val (target
, NULL
);
2860 if (!target
|| TREE_CODE (target
) != FUNCTION_DECL
)
2862 if (ie
->indirect_info
->member_ptr
)
2863 /* Member pointer call that goes through a VMT lookup. */
2866 if (dump_enabled_p ())
2868 location_t loc
= gimple_location_safe (ie
->call_stmt
);
2869 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, loc
,
2870 "discovered direct call to non-function in %s/%i, "
2871 "making it __builtin_unreachable\n",
2872 ie
->caller
->name (), ie
->caller
->order
);
2875 target
= builtin_decl_implicit (BUILT_IN_UNREACHABLE
);
2876 callee
= cgraph_node::get_create (target
);
2880 callee
= cgraph_node::get (target
);
2883 callee
= cgraph_node::get (target
);
2885 /* Because may-edges are not explicitely represented and vtable may be external,
2886 we may create the first reference to the object in the unit. */
2887 if (!callee
|| callee
->global
.inlined_to
)
2890 /* We are better to ensure we can refer to it.
2891 In the case of static functions we are out of luck, since we already
2892 removed its body. In the case of public functions we may or may
2893 not introduce the reference. */
2894 if (!canonicalize_constructor_val (target
, NULL
)
2895 || !TREE_PUBLIC (target
))
2898 fprintf (dump_file
, "ipa-prop: Discovered call to a known target "
2899 "(%s/%i -> %s/%i) but can not refer to it. Giving up.\n",
2900 xstrdup (ie
->caller
->name ()),
2902 xstrdup (ie
->callee
->name ()),
2906 callee
= cgraph_node::get_create (target
);
2909 /* If the edge is already speculated. */
2910 if (speculative
&& ie
->speculative
)
2912 struct cgraph_edge
*e2
;
2913 struct ipa_ref
*ref
;
2914 ie
->speculative_call_info (e2
, ie
, ref
);
2915 if (e2
->callee
->ultimate_alias_target ()
2916 != callee
->ultimate_alias_target ())
2919 fprintf (dump_file
, "ipa-prop: Discovered call to a speculative target "
2920 "(%s/%i -> %s/%i) but the call is already speculated to %s/%i. Giving up.\n",
2921 xstrdup (ie
->caller
->name ()),
2923 xstrdup (callee
->name ()),
2925 xstrdup (e2
->callee
->name ()),
2931 fprintf (dump_file
, "ipa-prop: Discovered call to a speculative target "
2932 "(%s/%i -> %s/%i) this agree with previous speculation.\n",
2933 xstrdup (ie
->caller
->name ()),
2935 xstrdup (callee
->name ()),
2941 if (!dbg_cnt (devirt
))
2944 ipa_check_create_node_params ();
2946 /* We can not make edges to inline clones. It is bug that someone removed
2947 the cgraph node too early. */
2948 gcc_assert (!callee
->global
.inlined_to
);
2950 if (dump_file
&& !unreachable
)
2952 fprintf (dump_file
, "ipa-prop: Discovered %s call to a %s target "
2953 "(%s/%i -> %s/%i), for stmt ",
2954 ie
->indirect_info
->polymorphic
? "a virtual" : "an indirect",
2955 speculative
? "speculative" : "known",
2956 xstrdup (ie
->caller
->name ()),
2958 xstrdup (callee
->name ()),
2961 print_gimple_stmt (dump_file
, ie
->call_stmt
, 2, TDF_SLIM
);
2963 fprintf (dump_file
, "with uid %i\n", ie
->lto_stmt_uid
);
2965 if (dump_enabled_p ())
2967 location_t loc
= gimple_location_safe (ie
->call_stmt
);
2969 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, loc
,
2970 "converting indirect call in %s to direct call to %s\n",
2971 ie
->caller
->name (), callee
->name ());
2974 ie
= ie
->make_direct (callee
);
2977 if (!callee
->can_be_discarded_p ())
2980 alias
= dyn_cast
<cgraph_node
*> (callee
->noninterposable_alias ());
2984 ie
= ie
->make_speculative
2985 (callee
, ie
->count
* 8 / 10, ie
->frequency
* 8 / 10);
2987 es
= inline_edge_summary (ie
);
2988 es
->call_stmt_size
-= (eni_size_weights
.indirect_call_cost
2989 - eni_size_weights
.call_cost
);
2990 es
->call_stmt_time
-= (eni_time_weights
.indirect_call_cost
2991 - eni_time_weights
.call_cost
);
2996 /* Retrieve value from aggregate jump function AGG for the given OFFSET or
2997 return NULL if there is not any. BY_REF specifies whether the value has to
2998 be passed by reference or by value. */
3001 ipa_find_agg_cst_for_param (struct ipa_agg_jump_function
*agg
,
3002 HOST_WIDE_INT offset
, bool by_ref
)
3004 struct ipa_agg_jf_item
*item
;
3007 if (by_ref
!= agg
->by_ref
)
3010 FOR_EACH_VEC_SAFE_ELT (agg
->items
, i
, item
)
3011 if (item
->offset
== offset
)
3013 /* Currently we do not have clobber values, return NULL for them once
3015 gcc_checking_assert (is_gimple_ip_invariant (item
->value
));
3021 /* Remove a reference to SYMBOL from the list of references of a node given by
3022 reference description RDESC. Return true if the reference has been
3023 successfully found and removed. */
3026 remove_described_reference (symtab_node
*symbol
, struct ipa_cst_ref_desc
*rdesc
)
3028 struct ipa_ref
*to_del
;
3029 struct cgraph_edge
*origin
;
3034 to_del
= origin
->caller
->find_reference (symbol
, origin
->call_stmt
,
3035 origin
->lto_stmt_uid
);
3039 to_del
->remove_reference ();
3041 fprintf (dump_file
, "ipa-prop: Removed a reference from %s/%i to %s.\n",
3042 xstrdup (origin
->caller
->name ()),
3043 origin
->caller
->order
, xstrdup (symbol
->name ()));
3047 /* If JFUNC has a reference description with refcount different from
3048 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
3049 NULL. JFUNC must be a constant jump function. */
3051 static struct ipa_cst_ref_desc
*
3052 jfunc_rdesc_usable (struct ipa_jump_func
*jfunc
)
3054 struct ipa_cst_ref_desc
*rdesc
= ipa_get_jf_constant_rdesc (jfunc
);
3055 if (rdesc
&& rdesc
->refcount
!= IPA_UNDESCRIBED_USE
)
3061 /* If the value of constant jump function JFUNC is an address of a function
3062 declaration, return the associated call graph node. Otherwise return
3065 static cgraph_node
*
3066 cgraph_node_for_jfunc (struct ipa_jump_func
*jfunc
)
3068 gcc_checking_assert (jfunc
->type
== IPA_JF_CONST
);
3069 tree cst
= ipa_get_jf_constant (jfunc
);
3070 if (TREE_CODE (cst
) != ADDR_EXPR
3071 || TREE_CODE (TREE_OPERAND (cst
, 0)) != FUNCTION_DECL
)
3074 return cgraph_node::get (TREE_OPERAND (cst
, 0));
3078 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
3079 refcount and if it hits zero, remove reference to SYMBOL from the caller of
3080 the edge specified in the rdesc. Return false if either the symbol or the
3081 reference could not be found, otherwise return true. */
3084 try_decrement_rdesc_refcount (struct ipa_jump_func
*jfunc
)
3086 struct ipa_cst_ref_desc
*rdesc
;
3087 if (jfunc
->type
== IPA_JF_CONST
3088 && (rdesc
= jfunc_rdesc_usable (jfunc
))
3089 && --rdesc
->refcount
== 0)
3091 symtab_node
*symbol
= cgraph_node_for_jfunc (jfunc
);
3095 return remove_described_reference (symbol
, rdesc
);
3100 /* Try to find a destination for indirect edge IE that corresponds to a simple
3101 call or a call of a member function pointer and where the destination is a
3102 pointer formal parameter described by jump function JFUNC. If it can be
3103 determined, return the newly direct edge, otherwise return NULL.
3104 NEW_ROOT_INFO is the node info that JFUNC lattices are relative to. */
3106 static struct cgraph_edge
*
3107 try_make_edge_direct_simple_call (struct cgraph_edge
*ie
,
3108 struct ipa_jump_func
*jfunc
,
3109 struct ipa_node_params
*new_root_info
)
3111 struct cgraph_edge
*cs
;
3113 bool agg_contents
= ie
->indirect_info
->agg_contents
;
3115 if (ie
->indirect_info
->agg_contents
)
3116 target
= ipa_find_agg_cst_for_param (&jfunc
->agg
,
3117 ie
->indirect_info
->offset
,
3118 ie
->indirect_info
->by_ref
);
3120 target
= ipa_value_from_jfunc (new_root_info
, jfunc
);
3123 cs
= ipa_make_edge_direct_to_target (ie
, target
);
3125 if (cs
&& !agg_contents
)
3128 gcc_checking_assert (cs
->callee
3130 || jfunc
->type
!= IPA_JF_CONST
3131 || !cgraph_node_for_jfunc (jfunc
)
3132 || cs
->callee
== cgraph_node_for_jfunc (jfunc
)));
3133 ok
= try_decrement_rdesc_refcount (jfunc
);
3134 gcc_checking_assert (ok
);
3140 /* Return the target to be used in cases of impossible devirtualization. IE
3141 and target (the latter can be NULL) are dumped when dumping is enabled. */
3144 ipa_impossible_devirt_target (struct cgraph_edge
*ie
, tree target
)
3150 "Type inconsistent devirtualization: %s/%i->%s\n",
3151 ie
->caller
->name (), ie
->caller
->order
,
3152 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target
)));
3155 "No devirtualization target in %s/%i\n",
3156 ie
->caller
->name (), ie
->caller
->order
);
3158 tree new_target
= builtin_decl_implicit (BUILT_IN_UNREACHABLE
);
3159 cgraph_node::get_create (new_target
);
3163 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3164 call based on a formal parameter which is described by jump function JFUNC
3165 and if it can be determined, make it direct and return the direct edge.
3166 Otherwise, return NULL. CTX describes the polymorphic context that the
3167 parameter the call is based on brings along with it. */
3169 static struct cgraph_edge
*
3170 try_make_edge_direct_virtual_call (struct cgraph_edge
*ie
,
3171 struct ipa_jump_func
*jfunc
,
3172 struct ipa_polymorphic_call_context ctx
)
3175 bool speculative
= false;
3177 if (!flag_devirtualize
)
3180 gcc_assert (!ie
->indirect_info
->by_ref
);
3182 /* Try to do lookup via known virtual table pointer value. */
3183 if (!ie
->indirect_info
->vptr_changed
|| flag_devirtualize_speculatively
)
3186 unsigned HOST_WIDE_INT offset
;
3187 tree t
= ipa_find_agg_cst_for_param (&jfunc
->agg
,
3188 ie
->indirect_info
->offset
,
3190 if (t
&& vtable_pointer_value_to_vtable (t
, &vtable
, &offset
))
3192 t
= gimple_get_virt_method_for_vtable (ie
->indirect_info
->otr_token
,
3196 if ((TREE_CODE (TREE_TYPE (t
)) == FUNCTION_TYPE
3197 && DECL_FUNCTION_CODE (t
) == BUILT_IN_UNREACHABLE
)
3198 || !possible_polymorphic_call_target_p
3199 (ie
, cgraph_node::get (t
)))
3201 /* Do not speculate builtin_unreachable, it is stpid! */
3202 if (!ie
->indirect_info
->vptr_changed
)
3203 target
= ipa_impossible_devirt_target (ie
, target
);
3208 speculative
= ie
->indirect_info
->vptr_changed
;
3214 ipa_polymorphic_call_context
ie_context (ie
);
3215 vec
<cgraph_node
*>targets
;
3218 ctx
.offset_by (ie
->indirect_info
->offset
);
3219 if (ie
->indirect_info
->vptr_changed
)
3220 ctx
.possible_dynamic_type_change (ie
->in_polymorphic_cdtor
,
3221 ie
->indirect_info
->otr_type
);
3222 ctx
.combine_with (ie_context
, ie
->indirect_info
->otr_type
);
3223 targets
= possible_polymorphic_call_targets
3224 (ie
->indirect_info
->otr_type
,
3225 ie
->indirect_info
->otr_token
,
3227 if (final
&& targets
.length () <= 1)
3229 if (targets
.length () == 1)
3230 target
= targets
[0]->decl
;
3232 target
= ipa_impossible_devirt_target (ie
, NULL_TREE
);
3234 else if (!target
&& flag_devirtualize_speculatively
3235 && !ie
->speculative
&& ie
->maybe_hot_p ())
3238 n
= try_speculative_devirtualization (ie
->indirect_info
->otr_type
,
3239 ie
->indirect_info
->otr_token
,
3240 ie
->indirect_info
->context
);
3250 if (!possible_polymorphic_call_target_p
3251 (ie
, cgraph_node::get_create (target
)))
3255 target
= ipa_impossible_devirt_target (ie
, target
);
3257 return ipa_make_edge_direct_to_target (ie
, target
, speculative
);
3263 /* Update the param called notes associated with NODE when CS is being inlined,
3264 assuming NODE is (potentially indirectly) inlined into CS->callee.
3265 Moreover, if the callee is discovered to be constant, create a new cgraph
3266 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
3267 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
3270 update_indirect_edges_after_inlining (struct cgraph_edge
*cs
,
3271 struct cgraph_node
*node
,
3272 vec
<cgraph_edge
*> *new_edges
)
3274 struct ipa_edge_args
*top
;
3275 struct cgraph_edge
*ie
, *next_ie
, *new_direct_edge
;
3276 struct ipa_node_params
*new_root_info
;
3279 ipa_check_create_edge_args ();
3280 top
= IPA_EDGE_REF (cs
);
3281 new_root_info
= IPA_NODE_REF (cs
->caller
->global
.inlined_to
3282 ? cs
->caller
->global
.inlined_to
3285 for (ie
= node
->indirect_calls
; ie
; ie
= next_ie
)
3287 struct cgraph_indirect_call_info
*ici
= ie
->indirect_info
;
3288 struct ipa_jump_func
*jfunc
;
3291 next_ie
= ie
->next_callee
;
3293 if (ici
->param_index
== -1)
3296 /* We must check range due to calls with variable number of arguments: */
3297 if (ici
->param_index
>= ipa_get_cs_argument_count (top
))
3299 ici
->param_index
= -1;
3303 param_index
= ici
->param_index
;
3304 jfunc
= ipa_get_ith_jump_func (top
, param_index
);
3306 if (!flag_indirect_inlining
)
3307 new_direct_edge
= NULL
;
3308 else if (ici
->polymorphic
)
3310 ipa_polymorphic_call_context ctx
;
3311 ctx
= ipa_context_from_jfunc (new_root_info
, cs
, param_index
, jfunc
);
3312 new_direct_edge
= try_make_edge_direct_virtual_call (ie
, jfunc
, ctx
);
3315 new_direct_edge
= try_make_edge_direct_simple_call (ie
, jfunc
,
3317 /* If speculation was removed, then we need to do nothing. */
3318 if (new_direct_edge
&& new_direct_edge
!= ie
)
3320 new_direct_edge
->indirect_inlining_edge
= 1;
3321 top
= IPA_EDGE_REF (cs
);
3324 else if (new_direct_edge
)
3326 new_direct_edge
->indirect_inlining_edge
= 1;
3327 if (new_direct_edge
->call_stmt
)
3328 new_direct_edge
->call_stmt_cannot_inline_p
3329 = !gimple_check_call_matching_types (
3330 new_direct_edge
->call_stmt
,
3331 new_direct_edge
->callee
->decl
, false);
3334 new_edges
->safe_push (new_direct_edge
);
3337 top
= IPA_EDGE_REF (cs
);
3339 else if (jfunc
->type
== IPA_JF_PASS_THROUGH
3340 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
3342 if ((ici
->agg_contents
3343 && !ipa_get_jf_pass_through_agg_preserved (jfunc
))
3344 || (ici
->polymorphic
3345 && !ipa_get_jf_pass_through_type_preserved (jfunc
)))
3346 ici
->param_index
= -1;
3348 ici
->param_index
= ipa_get_jf_pass_through_formal_id (jfunc
);
3350 else if (jfunc
->type
== IPA_JF_ANCESTOR
)
3352 if ((ici
->agg_contents
3353 && !ipa_get_jf_ancestor_agg_preserved (jfunc
))
3354 || (ici
->polymorphic
3355 && !ipa_get_jf_ancestor_type_preserved (jfunc
)))
3356 ici
->param_index
= -1;
3359 ici
->param_index
= ipa_get_jf_ancestor_formal_id (jfunc
);
3360 ici
->offset
+= ipa_get_jf_ancestor_offset (jfunc
);
3364 /* Either we can find a destination for this edge now or never. */
3365 ici
->param_index
= -1;
3371 /* Recursively traverse subtree of NODE (including node) made of inlined
3372 cgraph_edges when CS has been inlined and invoke
3373 update_indirect_edges_after_inlining on all nodes and
3374 update_jump_functions_after_inlining on all non-inlined edges that lead out
3375 of this subtree. Newly discovered indirect edges will be added to
3376 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
3380 propagate_info_to_inlined_callees (struct cgraph_edge
*cs
,
3381 struct cgraph_node
*node
,
3382 vec
<cgraph_edge
*> *new_edges
)
3384 struct cgraph_edge
*e
;
3387 res
= update_indirect_edges_after_inlining (cs
, node
, new_edges
);
3389 for (e
= node
->callees
; e
; e
= e
->next_callee
)
3390 if (!e
->inline_failed
)
3391 res
|= propagate_info_to_inlined_callees (cs
, e
->callee
, new_edges
);
3393 update_jump_functions_after_inlining (cs
, e
);
3394 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
3395 update_jump_functions_after_inlining (cs
, e
);
3400 /* Combine two controlled uses counts as done during inlining. */
3403 combine_controlled_uses_counters (int c
, int d
)
3405 if (c
== IPA_UNDESCRIBED_USE
|| d
== IPA_UNDESCRIBED_USE
)
3406 return IPA_UNDESCRIBED_USE
;
3411 /* Propagate number of controlled users from CS->caleee to the new root of the
3412 tree of inlined nodes. */
3415 propagate_controlled_uses (struct cgraph_edge
*cs
)
3417 struct ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
3418 struct cgraph_node
*new_root
= cs
->caller
->global
.inlined_to
3419 ? cs
->caller
->global
.inlined_to
: cs
->caller
;
3420 struct ipa_node_params
*new_root_info
= IPA_NODE_REF (new_root
);
3421 struct ipa_node_params
*old_root_info
= IPA_NODE_REF (cs
->callee
);
3424 count
= MIN (ipa_get_cs_argument_count (args
),
3425 ipa_get_param_count (old_root_info
));
3426 for (i
= 0; i
< count
; i
++)
3428 struct ipa_jump_func
*jf
= ipa_get_ith_jump_func (args
, i
);
3429 struct ipa_cst_ref_desc
*rdesc
;
3431 if (jf
->type
== IPA_JF_PASS_THROUGH
)
3434 src_idx
= ipa_get_jf_pass_through_formal_id (jf
);
3435 c
= ipa_get_controlled_uses (new_root_info
, src_idx
);
3436 d
= ipa_get_controlled_uses (old_root_info
, i
);
3438 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf
)
3439 == NOP_EXPR
|| c
== IPA_UNDESCRIBED_USE
);
3440 c
= combine_controlled_uses_counters (c
, d
);
3441 ipa_set_controlled_uses (new_root_info
, src_idx
, c
);
3442 if (c
== 0 && new_root_info
->ipcp_orig_node
)
3444 struct cgraph_node
*n
;
3445 struct ipa_ref
*ref
;
3446 tree t
= new_root_info
->known_csts
[src_idx
];
3448 if (t
&& TREE_CODE (t
) == ADDR_EXPR
3449 && TREE_CODE (TREE_OPERAND (t
, 0)) == FUNCTION_DECL
3450 && (n
= cgraph_node::get (TREE_OPERAND (t
, 0)))
3451 && (ref
= new_root
->find_reference (n
, NULL
, 0)))
3454 fprintf (dump_file
, "ipa-prop: Removing cloning-created "
3455 "reference from %s/%i to %s/%i.\n",
3456 xstrdup (new_root
->name ()),
3458 xstrdup (n
->name ()), n
->order
);
3459 ref
->remove_reference ();
3463 else if (jf
->type
== IPA_JF_CONST
3464 && (rdesc
= jfunc_rdesc_usable (jf
)))
3466 int d
= ipa_get_controlled_uses (old_root_info
, i
);
3467 int c
= rdesc
->refcount
;
3468 rdesc
->refcount
= combine_controlled_uses_counters (c
, d
);
3469 if (rdesc
->refcount
== 0)
3471 tree cst
= ipa_get_jf_constant (jf
);
3472 struct cgraph_node
*n
;
3473 gcc_checking_assert (TREE_CODE (cst
) == ADDR_EXPR
3474 && TREE_CODE (TREE_OPERAND (cst
, 0))
3476 n
= cgraph_node::get (TREE_OPERAND (cst
, 0));
3479 struct cgraph_node
*clone
;
3481 ok
= remove_described_reference (n
, rdesc
);
3482 gcc_checking_assert (ok
);
3485 while (clone
->global
.inlined_to
3486 && clone
!= rdesc
->cs
->caller
3487 && IPA_NODE_REF (clone
)->ipcp_orig_node
)
3489 struct ipa_ref
*ref
;
3490 ref
= clone
->find_reference (n
, NULL
, 0);
3494 fprintf (dump_file
, "ipa-prop: Removing "
3495 "cloning-created reference "
3496 "from %s/%i to %s/%i.\n",
3497 xstrdup (clone
->name ()),
3499 xstrdup (n
->name ()),
3501 ref
->remove_reference ();
3503 clone
= clone
->callers
->caller
;
3510 for (i
= ipa_get_param_count (old_root_info
);
3511 i
< ipa_get_cs_argument_count (args
);
3514 struct ipa_jump_func
*jf
= ipa_get_ith_jump_func (args
, i
);
3516 if (jf
->type
== IPA_JF_CONST
)
3518 struct ipa_cst_ref_desc
*rdesc
= jfunc_rdesc_usable (jf
);
3520 rdesc
->refcount
= IPA_UNDESCRIBED_USE
;
3522 else if (jf
->type
== IPA_JF_PASS_THROUGH
)
3523 ipa_set_controlled_uses (new_root_info
,
3524 jf
->value
.pass_through
.formal_id
,
3525 IPA_UNDESCRIBED_USE
);
3529 /* Update jump functions and call note functions on inlining the call site CS.
3530 CS is expected to lead to a node already cloned by
3531 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
3532 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
3536 ipa_propagate_indirect_call_infos (struct cgraph_edge
*cs
,
3537 vec
<cgraph_edge
*> *new_edges
)
3540 /* Do nothing if the preparation phase has not been carried out yet
3541 (i.e. during early inlining). */
3542 if (!ipa_node_params_vector
.exists ())
3544 gcc_assert (ipa_edge_args_vector
);
3546 propagate_controlled_uses (cs
);
3547 changed
= propagate_info_to_inlined_callees (cs
, cs
->callee
, new_edges
);
3552 /* Frees all dynamically allocated structures that the argument info points
3556 ipa_free_edge_args_substructures (struct ipa_edge_args
*args
)
3558 vec_free (args
->jump_functions
);
3559 memset (args
, 0, sizeof (*args
));
3562 /* Free all ipa_edge structures. */
3565 ipa_free_all_edge_args (void)
3568 struct ipa_edge_args
*args
;
3570 if (!ipa_edge_args_vector
)
3573 FOR_EACH_VEC_ELT (*ipa_edge_args_vector
, i
, args
)
3574 ipa_free_edge_args_substructures (args
);
3576 vec_free (ipa_edge_args_vector
);
3579 /* Frees all dynamically allocated structures that the param info points
3583 ipa_free_node_params_substructures (struct ipa_node_params
*info
)
3585 info
->descriptors
.release ();
3586 free (info
->lattices
);
3587 /* Lattice values and their sources are deallocated with their alocation
3589 info
->known_csts
.release ();
3590 info
->known_contexts
.release ();
3591 memset (info
, 0, sizeof (*info
));
3594 /* Free all ipa_node_params structures. */
3597 ipa_free_all_node_params (void)
3600 struct ipa_node_params
*info
;
3602 FOR_EACH_VEC_ELT (ipa_node_params_vector
, i
, info
)
3603 ipa_free_node_params_substructures (info
);
3605 ipa_node_params_vector
.release ();
3608 /* Set the aggregate replacements of NODE to be AGGVALS. */
3611 ipa_set_node_agg_value_chain (struct cgraph_node
*node
,
3612 struct ipa_agg_replacement_value
*aggvals
)
3614 if (vec_safe_length (ipa_node_agg_replacements
)
3615 <= (unsigned) symtab
->cgraph_max_uid
)
3616 vec_safe_grow_cleared (ipa_node_agg_replacements
,
3617 symtab
->cgraph_max_uid
+ 1);
3619 (*ipa_node_agg_replacements
)[node
->uid
] = aggvals
;
3622 /* Hook that is called by cgraph.c when an edge is removed. */
3625 ipa_edge_removal_hook (struct cgraph_edge
*cs
, void *data ATTRIBUTE_UNUSED
)
3627 struct ipa_edge_args
*args
;
3629 /* During IPA-CP updating we can be called on not-yet analyzed clones. */
3630 if (vec_safe_length (ipa_edge_args_vector
) <= (unsigned)cs
->uid
)
3633 args
= IPA_EDGE_REF (cs
);
3634 if (args
->jump_functions
)
3636 struct ipa_jump_func
*jf
;
3638 FOR_EACH_VEC_ELT (*args
->jump_functions
, i
, jf
)
3640 struct ipa_cst_ref_desc
*rdesc
;
3641 try_decrement_rdesc_refcount (jf
);
3642 if (jf
->type
== IPA_JF_CONST
3643 && (rdesc
= ipa_get_jf_constant_rdesc (jf
))
3649 ipa_free_edge_args_substructures (IPA_EDGE_REF (cs
));
3652 /* Hook that is called by cgraph.c when a node is removed. */
3655 ipa_node_removal_hook (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
3657 /* During IPA-CP updating we can be called on not-yet analyze clones. */
3658 if (ipa_node_params_vector
.length () > (unsigned)node
->uid
)
3659 ipa_free_node_params_substructures (IPA_NODE_REF (node
));
3660 if (vec_safe_length (ipa_node_agg_replacements
) > (unsigned)node
->uid
)
3661 (*ipa_node_agg_replacements
)[(unsigned)node
->uid
] = NULL
;
3664 /* Hook that is called by cgraph.c when an edge is duplicated. */
3667 ipa_edge_duplication_hook (struct cgraph_edge
*src
, struct cgraph_edge
*dst
,
3668 __attribute__((unused
)) void *data
)
3670 struct ipa_edge_args
*old_args
, *new_args
;
3673 ipa_check_create_edge_args ();
3675 old_args
= IPA_EDGE_REF (src
);
3676 new_args
= IPA_EDGE_REF (dst
);
3678 new_args
->jump_functions
= vec_safe_copy (old_args
->jump_functions
);
3679 if (old_args
->polymorphic_call_contexts
)
3680 new_args
->polymorphic_call_contexts
3681 = vec_safe_copy (old_args
->polymorphic_call_contexts
);
3683 for (i
= 0; i
< vec_safe_length (old_args
->jump_functions
); i
++)
3685 struct ipa_jump_func
*src_jf
= ipa_get_ith_jump_func (old_args
, i
);
3686 struct ipa_jump_func
*dst_jf
= ipa_get_ith_jump_func (new_args
, i
);
3688 dst_jf
->agg
.items
= vec_safe_copy (dst_jf
->agg
.items
);
3690 if (src_jf
->type
== IPA_JF_CONST
)
3692 struct ipa_cst_ref_desc
*src_rdesc
= jfunc_rdesc_usable (src_jf
);
3695 dst_jf
->value
.constant
.rdesc
= NULL
;
3696 else if (src
->caller
== dst
->caller
)
3698 struct ipa_ref
*ref
;
3699 symtab_node
*n
= cgraph_node_for_jfunc (src_jf
);
3700 gcc_checking_assert (n
);
3701 ref
= src
->caller
->find_reference (n
, src
->call_stmt
,
3703 gcc_checking_assert (ref
);
3704 dst
->caller
->clone_reference (ref
, ref
->stmt
);
3706 gcc_checking_assert (ipa_refdesc_pool
);
3707 struct ipa_cst_ref_desc
*dst_rdesc
3708 = (struct ipa_cst_ref_desc
*) pool_alloc (ipa_refdesc_pool
);
3709 dst_rdesc
->cs
= dst
;
3710 dst_rdesc
->refcount
= src_rdesc
->refcount
;
3711 dst_rdesc
->next_duplicate
= NULL
;
3712 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
3714 else if (src_rdesc
->cs
== src
)
3716 struct ipa_cst_ref_desc
*dst_rdesc
;
3717 gcc_checking_assert (ipa_refdesc_pool
);
3719 = (struct ipa_cst_ref_desc
*) pool_alloc (ipa_refdesc_pool
);
3720 dst_rdesc
->cs
= dst
;
3721 dst_rdesc
->refcount
= src_rdesc
->refcount
;
3722 dst_rdesc
->next_duplicate
= src_rdesc
->next_duplicate
;
3723 src_rdesc
->next_duplicate
= dst_rdesc
;
3724 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
3728 struct ipa_cst_ref_desc
*dst_rdesc
;
3729 /* This can happen during inlining, when a JFUNC can refer to a
3730 reference taken in a function up in the tree of inline clones.
3731 We need to find the duplicate that refers to our tree of
3734 gcc_assert (dst
->caller
->global
.inlined_to
);
3735 for (dst_rdesc
= src_rdesc
->next_duplicate
;
3737 dst_rdesc
= dst_rdesc
->next_duplicate
)
3739 struct cgraph_node
*top
;
3740 top
= dst_rdesc
->cs
->caller
->global
.inlined_to
3741 ? dst_rdesc
->cs
->caller
->global
.inlined_to
3742 : dst_rdesc
->cs
->caller
;
3743 if (dst
->caller
->global
.inlined_to
== top
)
3746 gcc_assert (dst_rdesc
);
3747 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
3750 else if (dst_jf
->type
== IPA_JF_PASS_THROUGH
3751 && src
->caller
== dst
->caller
)
3753 struct cgraph_node
*inline_root
= dst
->caller
->global
.inlined_to
3754 ? dst
->caller
->global
.inlined_to
: dst
->caller
;
3755 struct ipa_node_params
*root_info
= IPA_NODE_REF (inline_root
);
3756 int idx
= ipa_get_jf_pass_through_formal_id (dst_jf
);
3758 int c
= ipa_get_controlled_uses (root_info
, idx
);
3759 if (c
!= IPA_UNDESCRIBED_USE
)
3762 ipa_set_controlled_uses (root_info
, idx
, c
);
3768 /* Hook that is called by cgraph.c when a node is duplicated. */
3771 ipa_node_duplication_hook (struct cgraph_node
*src
, struct cgraph_node
*dst
,
3772 ATTRIBUTE_UNUSED
void *data
)
3774 struct ipa_node_params
*old_info
, *new_info
;
3775 struct ipa_agg_replacement_value
*old_av
, *new_av
;
3777 ipa_check_create_node_params ();
3778 old_info
= IPA_NODE_REF (src
);
3779 new_info
= IPA_NODE_REF (dst
);
3781 new_info
->descriptors
= old_info
->descriptors
.copy ();
3782 new_info
->lattices
= NULL
;
3783 new_info
->ipcp_orig_node
= old_info
->ipcp_orig_node
;
3785 new_info
->analysis_done
= old_info
->analysis_done
;
3786 new_info
->node_enqueued
= old_info
->node_enqueued
;
3788 old_av
= ipa_get_agg_replacements_for_node (src
);
3795 struct ipa_agg_replacement_value
*v
;
3797 v
= ggc_alloc
<ipa_agg_replacement_value
> ();
3798 memcpy (v
, old_av
, sizeof (*v
));
3801 old_av
= old_av
->next
;
3803 ipa_set_node_agg_value_chain (dst
, new_av
);
3807 /* Analyze newly added function into callgraph. */
3810 ipa_add_new_function (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
3812 if (node
->has_gimple_body_p ())
3813 ipa_analyze_node (node
);
3816 /* Register our cgraph hooks if they are not already there. */
3819 ipa_register_cgraph_hooks (void)
3821 if (!edge_removal_hook_holder
)
3822 edge_removal_hook_holder
=
3823 symtab
->add_edge_removal_hook (&ipa_edge_removal_hook
, NULL
);
3824 if (!node_removal_hook_holder
)
3825 node_removal_hook_holder
=
3826 symtab
->add_cgraph_removal_hook (&ipa_node_removal_hook
, NULL
);
3827 if (!edge_duplication_hook_holder
)
3828 edge_duplication_hook_holder
=
3829 symtab
->add_edge_duplication_hook (&ipa_edge_duplication_hook
, NULL
);
3830 if (!node_duplication_hook_holder
)
3831 node_duplication_hook_holder
=
3832 symtab
->add_cgraph_duplication_hook (&ipa_node_duplication_hook
, NULL
);
3833 function_insertion_hook_holder
=
3834 symtab
->add_cgraph_insertion_hook (&ipa_add_new_function
, NULL
);
3837 /* Unregister our cgraph hooks if they are not already there. */
3840 ipa_unregister_cgraph_hooks (void)
3842 symtab
->remove_edge_removal_hook (edge_removal_hook_holder
);
3843 edge_removal_hook_holder
= NULL
;
3844 symtab
->remove_cgraph_removal_hook (node_removal_hook_holder
);
3845 node_removal_hook_holder
= NULL
;
3846 symtab
->remove_edge_duplication_hook (edge_duplication_hook_holder
);
3847 edge_duplication_hook_holder
= NULL
;
3848 symtab
->remove_cgraph_duplication_hook (node_duplication_hook_holder
);
3849 node_duplication_hook_holder
= NULL
;
3850 symtab
->remove_cgraph_insertion_hook (function_insertion_hook_holder
);
3851 function_insertion_hook_holder
= NULL
;
3854 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
3855 longer needed after ipa-cp. */
3858 ipa_free_all_structures_after_ipa_cp (void)
3862 ipa_free_all_edge_args ();
3863 ipa_free_all_node_params ();
3864 free_alloc_pool (ipcp_sources_pool
);
3865 free_alloc_pool (ipcp_cst_values_pool
);
3866 free_alloc_pool (ipcp_poly_ctx_values_pool
);
3867 free_alloc_pool (ipcp_agg_lattice_pool
);
3868 ipa_unregister_cgraph_hooks ();
3869 if (ipa_refdesc_pool
)
3870 free_alloc_pool (ipa_refdesc_pool
);
3874 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
3875 longer needed after indirect inlining. */
3878 ipa_free_all_structures_after_iinln (void)
3880 ipa_free_all_edge_args ();
3881 ipa_free_all_node_params ();
3882 ipa_unregister_cgraph_hooks ();
3883 if (ipcp_sources_pool
)
3884 free_alloc_pool (ipcp_sources_pool
);
3885 if (ipcp_cst_values_pool
)
3886 free_alloc_pool (ipcp_cst_values_pool
);
3887 if (ipcp_poly_ctx_values_pool
)
3888 free_alloc_pool (ipcp_poly_ctx_values_pool
);
3889 if (ipcp_agg_lattice_pool
)
3890 free_alloc_pool (ipcp_agg_lattice_pool
);
3891 if (ipa_refdesc_pool
)
3892 free_alloc_pool (ipa_refdesc_pool
);
3895 /* Print ipa_tree_map data structures of all functions in the
3899 ipa_print_node_params (FILE *f
, struct cgraph_node
*node
)
3902 struct ipa_node_params
*info
;
3904 if (!node
->definition
)
3906 info
= IPA_NODE_REF (node
);
3907 fprintf (f
, " function %s/%i parameter descriptors:\n",
3908 node
->name (), node
->order
);
3909 count
= ipa_get_param_count (info
);
3910 for (i
= 0; i
< count
; i
++)
3915 ipa_dump_param (f
, info
, i
);
3916 if (ipa_is_param_used (info
, i
))
3917 fprintf (f
, " used");
3918 c
= ipa_get_controlled_uses (info
, i
);
3919 if (c
== IPA_UNDESCRIBED_USE
)
3920 fprintf (f
, " undescribed_use");
3922 fprintf (f
, " controlled_uses=%i", c
);
3927 /* Print ipa_tree_map data structures of all functions in the
3931 ipa_print_all_params (FILE * f
)
3933 struct cgraph_node
*node
;
3935 fprintf (f
, "\nFunction parameters:\n");
3936 FOR_EACH_FUNCTION (node
)
3937 ipa_print_node_params (f
, node
);
3940 /* Return a heap allocated vector containing formal parameters of FNDECL. */
3943 ipa_get_vector_of_formal_parms (tree fndecl
)
3949 gcc_assert (!flag_wpa
);
3950 count
= count_formal_params (fndecl
);
3951 args
.create (count
);
3952 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
3953 args
.quick_push (parm
);
3958 /* Return a heap allocated vector containing types of formal parameters of
3959 function type FNTYPE. */
3962 ipa_get_vector_of_formal_parm_types (tree fntype
)
3968 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
3971 types
.create (count
);
3972 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
3973 types
.quick_push (TREE_VALUE (t
));
3978 /* Modify the function declaration FNDECL and its type according to the plan in
3979 ADJUSTMENTS. It also sets base fields of individual adjustments structures
3980 to reflect the actual parameters being modified which are determined by the
3981 base_index field. */
3984 ipa_modify_formal_parameters (tree fndecl
, ipa_parm_adjustment_vec adjustments
)
3986 vec
<tree
> oparms
= ipa_get_vector_of_formal_parms (fndecl
);
3987 tree orig_type
= TREE_TYPE (fndecl
);
3988 tree old_arg_types
= TYPE_ARG_TYPES (orig_type
);
3990 /* The following test is an ugly hack, some functions simply don't have any
3991 arguments in their type. This is probably a bug but well... */
3992 bool care_for_types
= (old_arg_types
!= NULL_TREE
);
3993 bool last_parm_void
;
3997 last_parm_void
= (TREE_VALUE (tree_last (old_arg_types
))
3999 otypes
= ipa_get_vector_of_formal_parm_types (orig_type
);
4001 gcc_assert (oparms
.length () + 1 == otypes
.length ());
4003 gcc_assert (oparms
.length () == otypes
.length ());
4007 last_parm_void
= false;
4011 int len
= adjustments
.length ();
4012 tree
*link
= &DECL_ARGUMENTS (fndecl
);
4013 tree new_arg_types
= NULL
;
4014 for (int i
= 0; i
< len
; i
++)
4016 struct ipa_parm_adjustment
*adj
;
4019 adj
= &adjustments
[i
];
4021 if (adj
->op
== IPA_PARM_OP_NEW
)
4024 parm
= oparms
[adj
->base_index
];
4027 if (adj
->op
== IPA_PARM_OP_COPY
)
4030 new_arg_types
= tree_cons (NULL_TREE
, otypes
[adj
->base_index
],
4033 link
= &DECL_CHAIN (parm
);
4035 else if (adj
->op
!= IPA_PARM_OP_REMOVE
)
4041 ptype
= build_pointer_type (adj
->type
);
4045 if (is_gimple_reg_type (ptype
))
4047 unsigned malign
= GET_MODE_ALIGNMENT (TYPE_MODE (ptype
));
4048 if (TYPE_ALIGN (ptype
) < malign
)
4049 ptype
= build_aligned_type (ptype
, malign
);
4054 new_arg_types
= tree_cons (NULL_TREE
, ptype
, new_arg_types
);
4056 new_parm
= build_decl (UNKNOWN_LOCATION
, PARM_DECL
, NULL_TREE
,
4058 const char *prefix
= adj
->arg_prefix
? adj
->arg_prefix
: "SYNTH";
4059 DECL_NAME (new_parm
) = create_tmp_var_name (prefix
);
4060 DECL_ARTIFICIAL (new_parm
) = 1;
4061 DECL_ARG_TYPE (new_parm
) = ptype
;
4062 DECL_CONTEXT (new_parm
) = fndecl
;
4063 TREE_USED (new_parm
) = 1;
4064 DECL_IGNORED_P (new_parm
) = 1;
4065 layout_decl (new_parm
, 0);
4067 if (adj
->op
== IPA_PARM_OP_NEW
)
4071 adj
->new_decl
= new_parm
;
4074 link
= &DECL_CHAIN (new_parm
);
4080 tree new_reversed
= NULL
;
4083 new_reversed
= nreverse (new_arg_types
);
4087 TREE_CHAIN (new_arg_types
) = void_list_node
;
4089 new_reversed
= void_list_node
;
4093 /* Use copy_node to preserve as much as possible from original type
4094 (debug info, attribute lists etc.)
4095 Exception is METHOD_TYPEs must have THIS argument.
4096 When we are asked to remove it, we need to build new FUNCTION_TYPE
4098 tree new_type
= NULL
;
4099 if (TREE_CODE (orig_type
) != METHOD_TYPE
4100 || (adjustments
[0].op
== IPA_PARM_OP_COPY
4101 && adjustments
[0].base_index
== 0))
4103 new_type
= build_distinct_type_copy (orig_type
);
4104 TYPE_ARG_TYPES (new_type
) = new_reversed
;
4109 = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type
),
4111 TYPE_CONTEXT (new_type
) = TYPE_CONTEXT (orig_type
);
4112 DECL_VINDEX (fndecl
) = NULL_TREE
;
4115 /* When signature changes, we need to clear builtin info. */
4116 if (DECL_BUILT_IN (fndecl
))
4118 DECL_BUILT_IN_CLASS (fndecl
) = NOT_BUILT_IN
;
4119 DECL_FUNCTION_CODE (fndecl
) = (enum built_in_function
) 0;
4122 TREE_TYPE (fndecl
) = new_type
;
4123 DECL_VIRTUAL_P (fndecl
) = 0;
4124 DECL_LANG_SPECIFIC (fndecl
) = NULL
;
4129 /* Modify actual arguments of a function call CS as indicated in ADJUSTMENTS.
4130 If this is a directly recursive call, CS must be NULL. Otherwise it must
4131 contain the corresponding call graph edge. */
4134 ipa_modify_call_arguments (struct cgraph_edge
*cs
, gimple stmt
,
4135 ipa_parm_adjustment_vec adjustments
)
4137 struct cgraph_node
*current_node
= cgraph_node::get (current_function_decl
);
4139 vec
<tree
, va_gc
> **debug_args
= NULL
;
4141 gimple_stmt_iterator gsi
, prev_gsi
;
4145 len
= adjustments
.length ();
4147 callee_decl
= !cs
? gimple_call_fndecl (stmt
) : cs
->callee
->decl
;
4148 current_node
->remove_stmt_references (stmt
);
4150 gsi
= gsi_for_stmt (stmt
);
4152 gsi_prev (&prev_gsi
);
4153 for (i
= 0; i
< len
; i
++)
4155 struct ipa_parm_adjustment
*adj
;
4157 adj
= &adjustments
[i
];
4159 if (adj
->op
== IPA_PARM_OP_COPY
)
4161 tree arg
= gimple_call_arg (stmt
, adj
->base_index
);
4163 vargs
.quick_push (arg
);
4165 else if (adj
->op
!= IPA_PARM_OP_REMOVE
)
4167 tree expr
, base
, off
;
4169 unsigned int deref_align
= 0;
4170 bool deref_base
= false;
4172 /* We create a new parameter out of the value of the old one, we can
4173 do the following kind of transformations:
4175 - A scalar passed by reference is converted to a scalar passed by
4176 value. (adj->by_ref is false and the type of the original
4177 actual argument is a pointer to a scalar).
4179 - A part of an aggregate is passed instead of the whole aggregate.
4180 The part can be passed either by value or by reference, this is
4181 determined by value of adj->by_ref. Moreover, the code below
4182 handles both situations when the original aggregate is passed by
4183 value (its type is not a pointer) and when it is passed by
4184 reference (it is a pointer to an aggregate).
4186 When the new argument is passed by reference (adj->by_ref is true)
4187 it must be a part of an aggregate and therefore we form it by
4188 simply taking the address of a reference inside the original
4191 gcc_checking_assert (adj
->offset
% BITS_PER_UNIT
== 0);
4192 base
= gimple_call_arg (stmt
, adj
->base_index
);
4193 loc
= DECL_P (base
) ? DECL_SOURCE_LOCATION (base
)
4194 : EXPR_LOCATION (base
);
4196 if (TREE_CODE (base
) != ADDR_EXPR
4197 && POINTER_TYPE_P (TREE_TYPE (base
)))
4198 off
= build_int_cst (adj
->alias_ptr_type
,
4199 adj
->offset
/ BITS_PER_UNIT
);
4202 HOST_WIDE_INT base_offset
;
4206 if (TREE_CODE (base
) == ADDR_EXPR
)
4208 base
= TREE_OPERAND (base
, 0);
4214 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
4215 /* Aggregate arguments can have non-invariant addresses. */
4218 base
= build_fold_addr_expr (prev_base
);
4219 off
= build_int_cst (adj
->alias_ptr_type
,
4220 adj
->offset
/ BITS_PER_UNIT
);
4222 else if (TREE_CODE (base
) == MEM_REF
)
4227 deref_align
= TYPE_ALIGN (TREE_TYPE (base
));
4229 off
= build_int_cst (adj
->alias_ptr_type
,
4231 + adj
->offset
/ BITS_PER_UNIT
);
4232 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1),
4234 base
= TREE_OPERAND (base
, 0);
4238 off
= build_int_cst (adj
->alias_ptr_type
,
4240 + adj
->offset
/ BITS_PER_UNIT
);
4241 base
= build_fold_addr_expr (base
);
4247 tree type
= adj
->type
;
4249 unsigned HOST_WIDE_INT misalign
;
4253 align
= deref_align
;
4258 get_pointer_alignment_1 (base
, &align
, &misalign
);
4259 if (TYPE_ALIGN (type
) > align
)
4260 align
= TYPE_ALIGN (type
);
4262 misalign
+= (offset_int::from (off
, SIGNED
).to_short_addr ()
4264 misalign
= misalign
& (align
- 1);
4266 align
= (misalign
& -misalign
);
4267 if (align
< TYPE_ALIGN (type
))
4268 type
= build_aligned_type (type
, align
);
4269 base
= force_gimple_operand_gsi (&gsi
, base
,
4270 true, NULL
, true, GSI_SAME_STMT
);
4271 expr
= fold_build2_loc (loc
, MEM_REF
, type
, base
, off
);
4272 /* If expr is not a valid gimple call argument emit
4273 a load into a temporary. */
4274 if (is_gimple_reg_type (TREE_TYPE (expr
)))
4276 gimple tem
= gimple_build_assign (NULL_TREE
, expr
);
4277 if (gimple_in_ssa_p (cfun
))
4279 gimple_set_vuse (tem
, gimple_vuse (stmt
));
4280 expr
= make_ssa_name (TREE_TYPE (expr
), tem
);
4283 expr
= create_tmp_reg (TREE_TYPE (expr
), NULL
);
4284 gimple_assign_set_lhs (tem
, expr
);
4285 gsi_insert_before (&gsi
, tem
, GSI_SAME_STMT
);
4290 expr
= fold_build2_loc (loc
, MEM_REF
, adj
->type
, base
, off
);
4291 expr
= build_fold_addr_expr (expr
);
4292 expr
= force_gimple_operand_gsi (&gsi
, expr
,
4293 true, NULL
, true, GSI_SAME_STMT
);
4295 vargs
.quick_push (expr
);
4297 if (adj
->op
!= IPA_PARM_OP_COPY
&& MAY_HAVE_DEBUG_STMTS
)
4300 tree ddecl
= NULL_TREE
, origin
= DECL_ORIGIN (adj
->base
), arg
;
4303 arg
= gimple_call_arg (stmt
, adj
->base_index
);
4304 if (!useless_type_conversion_p (TREE_TYPE (origin
), TREE_TYPE (arg
)))
4306 if (!fold_convertible_p (TREE_TYPE (origin
), arg
))
4308 arg
= fold_convert_loc (gimple_location (stmt
),
4309 TREE_TYPE (origin
), arg
);
4311 if (debug_args
== NULL
)
4312 debug_args
= decl_debug_args_insert (callee_decl
);
4313 for (ix
= 0; vec_safe_iterate (*debug_args
, ix
, &ddecl
); ix
+= 2)
4314 if (ddecl
== origin
)
4316 ddecl
= (**debug_args
)[ix
+ 1];
4321 ddecl
= make_node (DEBUG_EXPR_DECL
);
4322 DECL_ARTIFICIAL (ddecl
) = 1;
4323 TREE_TYPE (ddecl
) = TREE_TYPE (origin
);
4324 DECL_MODE (ddecl
) = DECL_MODE (origin
);
4326 vec_safe_push (*debug_args
, origin
);
4327 vec_safe_push (*debug_args
, ddecl
);
4329 def_temp
= gimple_build_debug_bind (ddecl
, unshare_expr (arg
), stmt
);
4330 gsi_insert_before (&gsi
, def_temp
, GSI_SAME_STMT
);
4334 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4336 fprintf (dump_file
, "replacing stmt:");
4337 print_gimple_stmt (dump_file
, gsi_stmt (gsi
), 0, 0);
4340 new_stmt
= gimple_build_call_vec (callee_decl
, vargs
);
4342 if (gimple_call_lhs (stmt
))
4343 gimple_call_set_lhs (new_stmt
, gimple_call_lhs (stmt
));
4345 gimple_set_block (new_stmt
, gimple_block (stmt
));
4346 if (gimple_has_location (stmt
))
4347 gimple_set_location (new_stmt
, gimple_location (stmt
));
4348 gimple_call_set_chain (new_stmt
, gimple_call_chain (stmt
));
4349 gimple_call_copy_flags (new_stmt
, stmt
);
4350 if (gimple_in_ssa_p (cfun
))
4352 gimple_set_vuse (new_stmt
, gimple_vuse (stmt
));
4353 if (gimple_vdef (stmt
))
4355 gimple_set_vdef (new_stmt
, gimple_vdef (stmt
));
4356 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt
)) = new_stmt
;
4360 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4362 fprintf (dump_file
, "with stmt:");
4363 print_gimple_stmt (dump_file
, new_stmt
, 0, 0);
4364 fprintf (dump_file
, "\n");
4366 gsi_replace (&gsi
, new_stmt
, true);
4368 cs
->set_call_stmt (new_stmt
);
4371 current_node
->record_stmt_references (gsi_stmt (gsi
));
4374 while (gsi_stmt (gsi
) != gsi_stmt (prev_gsi
));
4377 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
4378 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
4379 specifies whether the function should care about type incompatibility the
4380 current and new expressions. If it is false, the function will leave
4381 incompatibility issues to the caller. Return true iff the expression
4385 ipa_modify_expr (tree
*expr
, bool convert
,
4386 ipa_parm_adjustment_vec adjustments
)
4388 struct ipa_parm_adjustment
*cand
4389 = ipa_get_adjustment_candidate (&expr
, &convert
, adjustments
, false);
4395 src
= build_simple_mem_ref (cand
->new_decl
);
4397 src
= cand
->new_decl
;
4399 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4401 fprintf (dump_file
, "About to replace expr ");
4402 print_generic_expr (dump_file
, *expr
, 0);
4403 fprintf (dump_file
, " with ");
4404 print_generic_expr (dump_file
, src
, 0);
4405 fprintf (dump_file
, "\n");
4408 if (convert
&& !useless_type_conversion_p (TREE_TYPE (*expr
), cand
->type
))
4410 tree vce
= build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (*expr
), src
);
4418 /* If T is an SSA_NAME, return NULL if it is not a default def or
4419 return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
4420 the base variable is always returned, regardless if it is a default
4421 def. Return T if it is not an SSA_NAME. */
4424 get_ssa_base_param (tree t
, bool ignore_default_def
)
4426 if (TREE_CODE (t
) == SSA_NAME
)
4428 if (ignore_default_def
|| SSA_NAME_IS_DEFAULT_DEF (t
))
4429 return SSA_NAME_VAR (t
);
4436 /* Given an expression, return an adjustment entry specifying the
4437 transformation to be done on EXPR. If no suitable adjustment entry
4438 was found, returns NULL.
4440 If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
4441 default def, otherwise bail on them.
4443 If CONVERT is non-NULL, this function will set *CONVERT if the
4444 expression provided is a component reference. ADJUSTMENTS is the
4445 adjustments vector. */
4447 ipa_parm_adjustment
*
4448 ipa_get_adjustment_candidate (tree
**expr
, bool *convert
,
4449 ipa_parm_adjustment_vec adjustments
,
4450 bool ignore_default_def
)
4452 if (TREE_CODE (**expr
) == BIT_FIELD_REF
4453 || TREE_CODE (**expr
) == IMAGPART_EXPR
4454 || TREE_CODE (**expr
) == REALPART_EXPR
)
4456 *expr
= &TREE_OPERAND (**expr
, 0);
4461 HOST_WIDE_INT offset
, size
, max_size
;
4462 tree base
= get_ref_base_and_extent (**expr
, &offset
, &size
, &max_size
);
4463 if (!base
|| size
== -1 || max_size
== -1)
4466 if (TREE_CODE (base
) == MEM_REF
)
4468 offset
+= mem_ref_offset (base
).to_short_addr () * BITS_PER_UNIT
;
4469 base
= TREE_OPERAND (base
, 0);
4472 base
= get_ssa_base_param (base
, ignore_default_def
);
4473 if (!base
|| TREE_CODE (base
) != PARM_DECL
)
4476 struct ipa_parm_adjustment
*cand
= NULL
;
4477 unsigned int len
= adjustments
.length ();
4478 for (unsigned i
= 0; i
< len
; i
++)
4480 struct ipa_parm_adjustment
*adj
= &adjustments
[i
];
4482 if (adj
->base
== base
4483 && (adj
->offset
== offset
|| adj
->op
== IPA_PARM_OP_REMOVE
))
4490 if (!cand
|| cand
->op
== IPA_PARM_OP_COPY
|| cand
->op
== IPA_PARM_OP_REMOVE
)
4495 /* Return true iff BASE_INDEX is in ADJUSTMENTS more than once. */
4498 index_in_adjustments_multiple_times_p (int base_index
,
4499 ipa_parm_adjustment_vec adjustments
)
4501 int i
, len
= adjustments
.length ();
4504 for (i
= 0; i
< len
; i
++)
4506 struct ipa_parm_adjustment
*adj
;
4507 adj
= &adjustments
[i
];
4509 if (adj
->base_index
== base_index
)
4521 /* Return adjustments that should have the same effect on function parameters
4522 and call arguments as if they were first changed according to adjustments in
4523 INNER and then by adjustments in OUTER. */
4525 ipa_parm_adjustment_vec
4526 ipa_combine_adjustments (ipa_parm_adjustment_vec inner
,
4527 ipa_parm_adjustment_vec outer
)
4529 int i
, outlen
= outer
.length ();
4530 int inlen
= inner
.length ();
4532 ipa_parm_adjustment_vec adjustments
, tmp
;
4535 for (i
= 0; i
< inlen
; i
++)
4537 struct ipa_parm_adjustment
*n
;
4540 if (n
->op
== IPA_PARM_OP_REMOVE
)
4544 /* FIXME: Handling of new arguments are not implemented yet. */
4545 gcc_assert (n
->op
!= IPA_PARM_OP_NEW
);
4546 tmp
.quick_push (*n
);
4550 adjustments
.create (outlen
+ removals
);
4551 for (i
= 0; i
< outlen
; i
++)
4553 struct ipa_parm_adjustment r
;
4554 struct ipa_parm_adjustment
*out
= &outer
[i
];
4555 struct ipa_parm_adjustment
*in
= &tmp
[out
->base_index
];
4557 memset (&r
, 0, sizeof (r
));
4558 gcc_assert (in
->op
!= IPA_PARM_OP_REMOVE
);
4559 if (out
->op
== IPA_PARM_OP_REMOVE
)
4561 if (!index_in_adjustments_multiple_times_p (in
->base_index
, tmp
))
4563 r
.op
= IPA_PARM_OP_REMOVE
;
4564 adjustments
.quick_push (r
);
4570 /* FIXME: Handling of new arguments are not implemented yet. */
4571 gcc_assert (out
->op
!= IPA_PARM_OP_NEW
);
4574 r
.base_index
= in
->base_index
;
4577 /* FIXME: Create nonlocal value too. */
4579 if (in
->op
== IPA_PARM_OP_COPY
&& out
->op
== IPA_PARM_OP_COPY
)
4580 r
.op
= IPA_PARM_OP_COPY
;
4581 else if (in
->op
== IPA_PARM_OP_COPY
)
4582 r
.offset
= out
->offset
;
4583 else if (out
->op
== IPA_PARM_OP_COPY
)
4584 r
.offset
= in
->offset
;
4586 r
.offset
= in
->offset
+ out
->offset
;
4587 adjustments
.quick_push (r
);
4590 for (i
= 0; i
< inlen
; i
++)
4592 struct ipa_parm_adjustment
*n
= &inner
[i
];
4594 if (n
->op
== IPA_PARM_OP_REMOVE
)
4595 adjustments
.quick_push (*n
);
4602 /* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
4603 friendly way, assuming they are meant to be applied to FNDECL. */
4606 ipa_dump_param_adjustments (FILE *file
, ipa_parm_adjustment_vec adjustments
,
4609 int i
, len
= adjustments
.length ();
4611 vec
<tree
> parms
= ipa_get_vector_of_formal_parms (fndecl
);
4613 fprintf (file
, "IPA param adjustments: ");
4614 for (i
= 0; i
< len
; i
++)
4616 struct ipa_parm_adjustment
*adj
;
4617 adj
= &adjustments
[i
];
4620 fprintf (file
, " ");
4624 fprintf (file
, "%i. base_index: %i - ", i
, adj
->base_index
);
4625 print_generic_expr (file
, parms
[adj
->base_index
], 0);
4628 fprintf (file
, ", base: ");
4629 print_generic_expr (file
, adj
->base
, 0);
4633 fprintf (file
, ", new_decl: ");
4634 print_generic_expr (file
, adj
->new_decl
, 0);
4636 if (adj
->new_ssa_base
)
4638 fprintf (file
, ", new_ssa_base: ");
4639 print_generic_expr (file
, adj
->new_ssa_base
, 0);
4642 if (adj
->op
== IPA_PARM_OP_COPY
)
4643 fprintf (file
, ", copy_param");
4644 else if (adj
->op
== IPA_PARM_OP_REMOVE
)
4645 fprintf (file
, ", remove_param");
4647 fprintf (file
, ", offset %li", (long) adj
->offset
);
4649 fprintf (file
, ", by_ref");
4650 print_node_brief (file
, ", type: ", adj
->type
, 0);
4651 fprintf (file
, "\n");
4656 /* Dump the AV linked list. */
4659 ipa_dump_agg_replacement_values (FILE *f
, struct ipa_agg_replacement_value
*av
)
4662 fprintf (f
, " Aggregate replacements:");
4663 for (; av
; av
= av
->next
)
4665 fprintf (f
, "%s %i[" HOST_WIDE_INT_PRINT_DEC
"]=", comma
? "," : "",
4666 av
->index
, av
->offset
);
4667 print_generic_expr (f
, av
->value
, 0);
4673 /* Stream out jump function JUMP_FUNC to OB. */
4676 ipa_write_jump_function (struct output_block
*ob
,
4677 struct ipa_jump_func
*jump_func
)
4679 struct ipa_agg_jf_item
*item
;
4680 struct bitpack_d bp
;
4683 streamer_write_uhwi (ob
, jump_func
->type
);
4684 switch (jump_func
->type
)
4686 case IPA_JF_UNKNOWN
:
4688 case IPA_JF_KNOWN_TYPE
:
4689 streamer_write_uhwi (ob
, jump_func
->value
.known_type
.offset
);
4690 stream_write_tree (ob
, jump_func
->value
.known_type
.base_type
, true);
4691 stream_write_tree (ob
, jump_func
->value
.known_type
.component_type
, true);
4695 EXPR_LOCATION (jump_func
->value
.constant
.value
) == UNKNOWN_LOCATION
);
4696 stream_write_tree (ob
, jump_func
->value
.constant
.value
, true);
4698 case IPA_JF_PASS_THROUGH
:
4699 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.operation
);
4700 if (jump_func
->value
.pass_through
.operation
== NOP_EXPR
)
4702 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4703 bp
= bitpack_create (ob
->main_stream
);
4704 bp_pack_value (&bp
, jump_func
->value
.pass_through
.agg_preserved
, 1);
4705 bp_pack_value (&bp
, jump_func
->value
.pass_through
.type_preserved
, 1);
4706 streamer_write_bitpack (&bp
);
4710 stream_write_tree (ob
, jump_func
->value
.pass_through
.operand
, true);
4711 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4714 case IPA_JF_ANCESTOR
:
4715 streamer_write_uhwi (ob
, jump_func
->value
.ancestor
.offset
);
4716 stream_write_tree (ob
, jump_func
->value
.ancestor
.type
, true);
4717 streamer_write_uhwi (ob
, jump_func
->value
.ancestor
.formal_id
);
4718 bp
= bitpack_create (ob
->main_stream
);
4719 bp_pack_value (&bp
, jump_func
->value
.ancestor
.agg_preserved
, 1);
4720 bp_pack_value (&bp
, jump_func
->value
.ancestor
.type_preserved
, 1);
4721 streamer_write_bitpack (&bp
);
4725 count
= vec_safe_length (jump_func
->agg
.items
);
4726 streamer_write_uhwi (ob
, count
);
4729 bp
= bitpack_create (ob
->main_stream
);
4730 bp_pack_value (&bp
, jump_func
->agg
.by_ref
, 1);
4731 streamer_write_bitpack (&bp
);
4734 FOR_EACH_VEC_SAFE_ELT (jump_func
->agg
.items
, i
, item
)
4736 streamer_write_uhwi (ob
, item
->offset
);
4737 stream_write_tree (ob
, item
->value
, true);
4741 /* Read in jump function JUMP_FUNC from IB. */
4744 ipa_read_jump_function (struct lto_input_block
*ib
,
4745 struct ipa_jump_func
*jump_func
,
4746 struct cgraph_edge
*cs
,
4747 struct data_in
*data_in
)
4749 enum jump_func_type jftype
;
4750 enum tree_code operation
;
4753 jftype
= (enum jump_func_type
) streamer_read_uhwi (ib
);
4756 case IPA_JF_UNKNOWN
:
4757 jump_func
->type
= IPA_JF_UNKNOWN
;
4759 case IPA_JF_KNOWN_TYPE
:
4761 HOST_WIDE_INT offset
= streamer_read_uhwi (ib
);
4762 tree base_type
= stream_read_tree (ib
, data_in
);
4763 tree component_type
= stream_read_tree (ib
, data_in
);
4765 ipa_set_jf_known_type (jump_func
, offset
, base_type
, component_type
);
4769 ipa_set_jf_constant (jump_func
, stream_read_tree (ib
, data_in
), cs
);
4771 case IPA_JF_PASS_THROUGH
:
4772 operation
= (enum tree_code
) streamer_read_uhwi (ib
);
4773 if (operation
== NOP_EXPR
)
4775 int formal_id
= streamer_read_uhwi (ib
);
4776 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4777 bool agg_preserved
= bp_unpack_value (&bp
, 1);
4778 bool type_preserved
= bp_unpack_value (&bp
, 1);
4779 ipa_set_jf_simple_pass_through (jump_func
, formal_id
, agg_preserved
,
4784 tree operand
= stream_read_tree (ib
, data_in
);
4785 int formal_id
= streamer_read_uhwi (ib
);
4786 ipa_set_jf_arith_pass_through (jump_func
, formal_id
, operand
,
4790 case IPA_JF_ANCESTOR
:
4792 HOST_WIDE_INT offset
= streamer_read_uhwi (ib
);
4793 tree type
= stream_read_tree (ib
, data_in
);
4794 int formal_id
= streamer_read_uhwi (ib
);
4795 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4796 bool agg_preserved
= bp_unpack_value (&bp
, 1);
4797 bool type_preserved
= bp_unpack_value (&bp
, 1);
4799 ipa_set_ancestor_jf (jump_func
, offset
, type
, formal_id
, agg_preserved
,
4805 count
= streamer_read_uhwi (ib
);
4806 vec_alloc (jump_func
->agg
.items
, count
);
4809 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4810 jump_func
->agg
.by_ref
= bp_unpack_value (&bp
, 1);
4812 for (i
= 0; i
< count
; i
++)
4814 struct ipa_agg_jf_item item
;
4815 item
.offset
= streamer_read_uhwi (ib
);
4816 item
.value
= stream_read_tree (ib
, data_in
);
4817 jump_func
->agg
.items
->quick_push (item
);
4821 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
4822 relevant to indirect inlining to OB. */
4825 ipa_write_indirect_edge_info (struct output_block
*ob
,
4826 struct cgraph_edge
*cs
)
4828 struct cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
4829 struct bitpack_d bp
;
4831 streamer_write_hwi (ob
, ii
->param_index
);
4832 bp
= bitpack_create (ob
->main_stream
);
4833 bp_pack_value (&bp
, ii
->polymorphic
, 1);
4834 bp_pack_value (&bp
, ii
->agg_contents
, 1);
4835 bp_pack_value (&bp
, ii
->member_ptr
, 1);
4836 bp_pack_value (&bp
, ii
->by_ref
, 1);
4837 bp_pack_value (&bp
, ii
->vptr_changed
, 1);
4838 streamer_write_bitpack (&bp
);
4839 if (ii
->agg_contents
|| ii
->polymorphic
)
4840 streamer_write_hwi (ob
, ii
->offset
);
4842 gcc_assert (ii
->offset
== 0);
4844 if (ii
->polymorphic
)
4846 streamer_write_hwi (ob
, ii
->otr_token
);
4847 stream_write_tree (ob
, ii
->otr_type
, true);
4848 ii
->context
.stream_out (ob
);
4852 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
4853 relevant to indirect inlining from IB. */
4856 ipa_read_indirect_edge_info (struct lto_input_block
*ib
,
4857 struct data_in
*data_in
,
4858 struct cgraph_edge
*cs
)
4860 struct cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
4861 struct bitpack_d bp
;
4863 ii
->param_index
= (int) streamer_read_hwi (ib
);
4864 bp
= streamer_read_bitpack (ib
);
4865 ii
->polymorphic
= bp_unpack_value (&bp
, 1);
4866 ii
->agg_contents
= bp_unpack_value (&bp
, 1);
4867 ii
->member_ptr
= bp_unpack_value (&bp
, 1);
4868 ii
->by_ref
= bp_unpack_value (&bp
, 1);
4869 ii
->vptr_changed
= bp_unpack_value (&bp
, 1);
4870 if (ii
->agg_contents
|| ii
->polymorphic
)
4871 ii
->offset
= (HOST_WIDE_INT
) streamer_read_hwi (ib
);
4874 if (ii
->polymorphic
)
4876 ii
->otr_token
= (HOST_WIDE_INT
) streamer_read_hwi (ib
);
4877 ii
->otr_type
= stream_read_tree (ib
, data_in
);
4878 ii
->context
.stream_in (ib
, data_in
);
4882 /* Stream out NODE info to OB. */
4885 ipa_write_node_info (struct output_block
*ob
, struct cgraph_node
*node
)
4888 lto_symtab_encoder_t encoder
;
4889 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
4891 struct cgraph_edge
*e
;
4892 struct bitpack_d bp
;
4894 encoder
= ob
->decl_state
->symtab_node_encoder
;
4895 node_ref
= lto_symtab_encoder_encode (encoder
, node
);
4896 streamer_write_uhwi (ob
, node_ref
);
4898 streamer_write_uhwi (ob
, ipa_get_param_count (info
));
4899 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
4900 streamer_write_uhwi (ob
, ipa_get_param_move_cost (info
, j
));
4901 bp
= bitpack_create (ob
->main_stream
);
4902 gcc_assert (info
->analysis_done
4903 || ipa_get_param_count (info
) == 0);
4904 gcc_assert (!info
->node_enqueued
);
4905 gcc_assert (!info
->ipcp_orig_node
);
4906 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
4907 bp_pack_value (&bp
, ipa_is_param_used (info
, j
), 1);
4908 streamer_write_bitpack (&bp
);
4909 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
4910 streamer_write_hwi (ob
, ipa_get_controlled_uses (info
, j
));
4911 for (e
= node
->callees
; e
; e
= e
->next_callee
)
4913 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4915 streamer_write_uhwi (ob
,
4916 ipa_get_cs_argument_count (args
) * 2
4917 + (args
->polymorphic_call_contexts
!= NULL
));
4918 for (j
= 0; j
< ipa_get_cs_argument_count (args
); j
++)
4920 ipa_write_jump_function (ob
, ipa_get_ith_jump_func (args
, j
));
4921 if (args
->polymorphic_call_contexts
!= NULL
)
4922 ipa_get_ith_polymorhic_call_context (args
, j
)->stream_out (ob
);
4925 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
4927 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4929 streamer_write_uhwi (ob
,
4930 ipa_get_cs_argument_count (args
) * 2
4931 + (args
->polymorphic_call_contexts
!= NULL
));
4932 for (j
= 0; j
< ipa_get_cs_argument_count (args
); j
++)
4934 ipa_write_jump_function (ob
, ipa_get_ith_jump_func (args
, j
));
4935 if (args
->polymorphic_call_contexts
!= NULL
)
4936 ipa_get_ith_polymorhic_call_context (args
, j
)->stream_out (ob
);
4938 ipa_write_indirect_edge_info (ob
, e
);
4942 /* Stream in NODE info from IB. */
4945 ipa_read_node_info (struct lto_input_block
*ib
, struct cgraph_node
*node
,
4946 struct data_in
*data_in
)
4948 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
4950 struct cgraph_edge
*e
;
4951 struct bitpack_d bp
;
4953 ipa_alloc_node_params (node
, streamer_read_uhwi (ib
));
4955 for (k
= 0; k
< ipa_get_param_count (info
); k
++)
4956 info
->descriptors
[k
].move_cost
= streamer_read_uhwi (ib
);
4958 bp
= streamer_read_bitpack (ib
);
4959 if (ipa_get_param_count (info
) != 0)
4960 info
->analysis_done
= true;
4961 info
->node_enqueued
= false;
4962 for (k
= 0; k
< ipa_get_param_count (info
); k
++)
4963 ipa_set_param_used (info
, k
, bp_unpack_value (&bp
, 1));
4964 for (k
= 0; k
< ipa_get_param_count (info
); k
++)
4965 ipa_set_controlled_uses (info
, k
, streamer_read_hwi (ib
));
4966 for (e
= node
->callees
; e
; e
= e
->next_callee
)
4968 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4969 int count
= streamer_read_uhwi (ib
);
4970 bool contexts_computed
= count
& 1;
4975 vec_safe_grow_cleared (args
->jump_functions
, count
);
4976 if (contexts_computed
)
4977 vec_safe_grow_cleared (args
->polymorphic_call_contexts
, count
);
4979 for (k
= 0; k
< ipa_get_cs_argument_count (args
); k
++)
4981 ipa_read_jump_function (ib
, ipa_get_ith_jump_func (args
, k
), e
,
4983 if (contexts_computed
)
4984 ipa_get_ith_polymorhic_call_context (args
, k
)->stream_in (ib
, data_in
);
4987 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
4989 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4990 int count
= streamer_read_uhwi (ib
);
4991 bool contexts_computed
= count
& 1;
4996 vec_safe_grow_cleared (args
->jump_functions
, count
);
4997 if (contexts_computed
)
4998 vec_safe_grow_cleared (args
->polymorphic_call_contexts
, count
);
4999 for (k
= 0; k
< ipa_get_cs_argument_count (args
); k
++)
5001 ipa_read_jump_function (ib
, ipa_get_ith_jump_func (args
, k
), e
,
5003 if (contexts_computed
)
5004 ipa_get_ith_polymorhic_call_context (args
, k
)->stream_in (ib
, data_in
);
5007 ipa_read_indirect_edge_info (ib
, data_in
, e
);
5011 /* Write jump functions for nodes in SET. */
5014 ipa_prop_write_jump_functions (void)
5016 struct cgraph_node
*node
;
5017 struct output_block
*ob
;
5018 unsigned int count
= 0;
5019 lto_symtab_encoder_iterator lsei
;
5020 lto_symtab_encoder_t encoder
;
5023 if (!ipa_node_params_vector
.exists ())
5026 ob
= create_output_block (LTO_section_jump_functions
);
5027 encoder
= ob
->decl_state
->symtab_node_encoder
;
5029 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5030 lsei_next_function_in_partition (&lsei
))
5032 node
= lsei_cgraph_node (lsei
);
5033 if (node
->has_gimple_body_p ()
5034 && IPA_NODE_REF (node
) != NULL
)
5038 streamer_write_uhwi (ob
, count
);
5040 /* Process all of the functions. */
5041 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5042 lsei_next_function_in_partition (&lsei
))
5044 node
= lsei_cgraph_node (lsei
);
5045 if (node
->has_gimple_body_p ()
5046 && IPA_NODE_REF (node
) != NULL
)
5047 ipa_write_node_info (ob
, node
);
5049 streamer_write_char_stream (ob
->main_stream
, 0);
5050 produce_asm (ob
, NULL
);
5051 destroy_output_block (ob
);
5054 /* Read section in file FILE_DATA of length LEN with data DATA. */
5057 ipa_prop_read_section (struct lto_file_decl_data
*file_data
, const char *data
,
5060 const struct lto_function_header
*header
=
5061 (const struct lto_function_header
*) data
;
5062 const int cfg_offset
= sizeof (struct lto_function_header
);
5063 const int main_offset
= cfg_offset
+ header
->cfg_size
;
5064 const int string_offset
= main_offset
+ header
->main_size
;
5065 struct data_in
*data_in
;
5069 lto_input_block
ib_main ((const char *) data
+ main_offset
,
5073 lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
5074 header
->string_size
, vNULL
);
5075 count
= streamer_read_uhwi (&ib_main
);
5077 for (i
= 0; i
< count
; i
++)
5080 struct cgraph_node
*node
;
5081 lto_symtab_encoder_t encoder
;
5083 index
= streamer_read_uhwi (&ib_main
);
5084 encoder
= file_data
->symtab_node_encoder
;
5085 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref (encoder
,
5087 gcc_assert (node
->definition
);
5088 ipa_read_node_info (&ib_main
, node
, data_in
);
5090 lto_free_section_data (file_data
, LTO_section_jump_functions
, NULL
, data
,
5092 lto_data_in_delete (data_in
);
5095 /* Read ipcp jump functions. */
5098 ipa_prop_read_jump_functions (void)
5100 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
5101 struct lto_file_decl_data
*file_data
;
5104 ipa_check_create_node_params ();
5105 ipa_check_create_edge_args ();
5106 ipa_register_cgraph_hooks ();
5108 while ((file_data
= file_data_vec
[j
++]))
5111 const char *data
= lto_get_section_data (file_data
, LTO_section_jump_functions
, NULL
, &len
);
5114 ipa_prop_read_section (file_data
, data
, len
);
5118 /* After merging units, we can get mismatch in argument counts.
5119 Also decl merging might've rendered parameter lists obsolete.
5120 Also compute called_with_variable_arg info. */
5123 ipa_update_after_lto_read (void)
5125 ipa_check_create_node_params ();
5126 ipa_check_create_edge_args ();
5130 write_agg_replacement_chain (struct output_block
*ob
, struct cgraph_node
*node
)
5133 unsigned int count
= 0;
5134 lto_symtab_encoder_t encoder
;
5135 struct ipa_agg_replacement_value
*aggvals
, *av
;
5137 aggvals
= ipa_get_agg_replacements_for_node (node
);
5138 encoder
= ob
->decl_state
->symtab_node_encoder
;
5139 node_ref
= lto_symtab_encoder_encode (encoder
, node
);
5140 streamer_write_uhwi (ob
, node_ref
);
5142 for (av
= aggvals
; av
; av
= av
->next
)
5144 streamer_write_uhwi (ob
, count
);
5146 for (av
= aggvals
; av
; av
= av
->next
)
5148 struct bitpack_d bp
;
5150 streamer_write_uhwi (ob
, av
->offset
);
5151 streamer_write_uhwi (ob
, av
->index
);
5152 stream_write_tree (ob
, av
->value
, true);
5154 bp
= bitpack_create (ob
->main_stream
);
5155 bp_pack_value (&bp
, av
->by_ref
, 1);
5156 streamer_write_bitpack (&bp
);
5160 /* Stream in the aggregate value replacement chain for NODE from IB. */
5163 read_agg_replacement_chain (struct lto_input_block
*ib
,
5164 struct cgraph_node
*node
,
5165 struct data_in
*data_in
)
5167 struct ipa_agg_replacement_value
*aggvals
= NULL
;
5168 unsigned int count
, i
;
5170 count
= streamer_read_uhwi (ib
);
5171 for (i
= 0; i
<count
; i
++)
5173 struct ipa_agg_replacement_value
*av
;
5174 struct bitpack_d bp
;
5176 av
= ggc_alloc
<ipa_agg_replacement_value
> ();
5177 av
->offset
= streamer_read_uhwi (ib
);
5178 av
->index
= streamer_read_uhwi (ib
);
5179 av
->value
= stream_read_tree (ib
, data_in
);
5180 bp
= streamer_read_bitpack (ib
);
5181 av
->by_ref
= bp_unpack_value (&bp
, 1);
5185 ipa_set_node_agg_value_chain (node
, aggvals
);
5188 /* Write all aggregate replacement for nodes in set. */
5191 ipa_prop_write_all_agg_replacement (void)
5193 struct cgraph_node
*node
;
5194 struct output_block
*ob
;
5195 unsigned int count
= 0;
5196 lto_symtab_encoder_iterator lsei
;
5197 lto_symtab_encoder_t encoder
;
5199 if (!ipa_node_agg_replacements
)
5202 ob
= create_output_block (LTO_section_ipcp_transform
);
5203 encoder
= ob
->decl_state
->symtab_node_encoder
;
5205 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5206 lsei_next_function_in_partition (&lsei
))
5208 node
= lsei_cgraph_node (lsei
);
5209 if (node
->has_gimple_body_p ()
5210 && ipa_get_agg_replacements_for_node (node
) != NULL
)
5214 streamer_write_uhwi (ob
, count
);
5216 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5217 lsei_next_function_in_partition (&lsei
))
5219 node
= lsei_cgraph_node (lsei
);
5220 if (node
->has_gimple_body_p ()
5221 && ipa_get_agg_replacements_for_node (node
) != NULL
)
5222 write_agg_replacement_chain (ob
, node
);
5224 streamer_write_char_stream (ob
->main_stream
, 0);
5225 produce_asm (ob
, NULL
);
5226 destroy_output_block (ob
);
5229 /* Read replacements section in file FILE_DATA of length LEN with data
5233 read_replacements_section (struct lto_file_decl_data
*file_data
,
5237 const struct lto_function_header
*header
=
5238 (const struct lto_function_header
*) data
;
5239 const int cfg_offset
= sizeof (struct lto_function_header
);
5240 const int main_offset
= cfg_offset
+ header
->cfg_size
;
5241 const int string_offset
= main_offset
+ header
->main_size
;
5242 struct data_in
*data_in
;
5246 lto_input_block
ib_main ((const char *) data
+ main_offset
,
5249 data_in
= lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
5250 header
->string_size
, vNULL
);
5251 count
= streamer_read_uhwi (&ib_main
);
5253 for (i
= 0; i
< count
; i
++)
5256 struct cgraph_node
*node
;
5257 lto_symtab_encoder_t encoder
;
5259 index
= streamer_read_uhwi (&ib_main
);
5260 encoder
= file_data
->symtab_node_encoder
;
5261 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref (encoder
,
5263 gcc_assert (node
->definition
);
5264 read_agg_replacement_chain (&ib_main
, node
, data_in
);
5266 lto_free_section_data (file_data
, LTO_section_jump_functions
, NULL
, data
,
5268 lto_data_in_delete (data_in
);
5271 /* Read IPA-CP aggregate replacements. */
5274 ipa_prop_read_all_agg_replacement (void)
5276 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
5277 struct lto_file_decl_data
*file_data
;
5280 while ((file_data
= file_data_vec
[j
++]))
5283 const char *data
= lto_get_section_data (file_data
,
5284 LTO_section_ipcp_transform
,
5287 read_replacements_section (file_data
, data
, len
);
5291 /* Adjust the aggregate replacements in AGGVAL to reflect parameters skipped in
5295 adjust_agg_replacement_values (struct cgraph_node
*node
,
5296 struct ipa_agg_replacement_value
*aggval
)
5298 struct ipa_agg_replacement_value
*v
;
5299 int i
, c
= 0, d
= 0, *adj
;
5301 if (!node
->clone
.combined_args_to_skip
)
5304 for (v
= aggval
; v
; v
= v
->next
)
5306 gcc_assert (v
->index
>= 0);
5312 adj
= XALLOCAVEC (int, c
);
5313 for (i
= 0; i
< c
; i
++)
5314 if (bitmap_bit_p (node
->clone
.combined_args_to_skip
, i
))
5322 for (v
= aggval
; v
; v
= v
->next
)
5323 v
->index
= adj
[v
->index
];
5326 /* Dominator walker driving the ipcp modification phase. */
5328 class ipcp_modif_dom_walker
: public dom_walker
5331 ipcp_modif_dom_walker (struct func_body_info
*fbi
,
5332 vec
<ipa_param_descriptor
> descs
,
5333 struct ipa_agg_replacement_value
*av
,
5335 : dom_walker (CDI_DOMINATORS
), m_fbi (fbi
), m_descriptors (descs
),
5336 m_aggval (av
), m_something_changed (sc
), m_cfg_changed (cc
) {}
5338 virtual void before_dom_children (basic_block
);
5341 struct func_body_info
*m_fbi
;
5342 vec
<ipa_param_descriptor
> m_descriptors
;
5343 struct ipa_agg_replacement_value
*m_aggval
;
5344 bool *m_something_changed
, *m_cfg_changed
;
5348 ipcp_modif_dom_walker::before_dom_children (basic_block bb
)
5350 gimple_stmt_iterator gsi
;
5351 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
5353 struct ipa_agg_replacement_value
*v
;
5354 gimple stmt
= gsi_stmt (gsi
);
5356 HOST_WIDE_INT offset
, size
;
5360 if (!gimple_assign_load_p (stmt
))
5362 rhs
= gimple_assign_rhs1 (stmt
);
5363 if (!is_gimple_reg_type (TREE_TYPE (rhs
)))
5368 while (handled_component_p (t
))
5370 /* V_C_E can do things like convert an array of integers to one
5371 bigger integer and similar things we do not handle below. */
5372 if (TREE_CODE (rhs
) == VIEW_CONVERT_EXPR
)
5377 t
= TREE_OPERAND (t
, 0);
5382 if (!ipa_load_from_parm_agg_1 (m_fbi
, m_descriptors
, stmt
, rhs
, &index
,
5383 &offset
, &size
, &by_ref
))
5385 for (v
= m_aggval
; v
; v
= v
->next
)
5386 if (v
->index
== index
5387 && v
->offset
== offset
)
5390 || v
->by_ref
!= by_ref
5391 || tree_to_shwi (TYPE_SIZE (TREE_TYPE (v
->value
))) != size
)
5394 gcc_checking_assert (is_gimple_ip_invariant (v
->value
));
5395 if (!useless_type_conversion_p (TREE_TYPE (rhs
), TREE_TYPE (v
->value
)))
5397 if (fold_convertible_p (TREE_TYPE (rhs
), v
->value
))
5398 val
= fold_build1 (NOP_EXPR
, TREE_TYPE (rhs
), v
->value
);
5399 else if (TYPE_SIZE (TREE_TYPE (rhs
))
5400 == TYPE_SIZE (TREE_TYPE (v
->value
)))
5401 val
= fold_build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (rhs
), v
->value
);
5406 fprintf (dump_file
, " const ");
5407 print_generic_expr (dump_file
, v
->value
, 0);
5408 fprintf (dump_file
, " can't be converted to type of ");
5409 print_generic_expr (dump_file
, rhs
, 0);
5410 fprintf (dump_file
, "\n");
5418 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5420 fprintf (dump_file
, "Modifying stmt:\n ");
5421 print_gimple_stmt (dump_file
, stmt
, 0, 0);
5423 gimple_assign_set_rhs_from_tree (&gsi
, val
);
5426 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5428 fprintf (dump_file
, "into:\n ");
5429 print_gimple_stmt (dump_file
, stmt
, 0, 0);
5430 fprintf (dump_file
, "\n");
5433 *m_something_changed
= true;
5434 if (maybe_clean_eh_stmt (stmt
)
5435 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
5436 *m_cfg_changed
= true;
5441 /* IPCP transformation phase doing propagation of aggregate values. */
5444 ipcp_transform_function (struct cgraph_node
*node
)
5446 vec
<ipa_param_descriptor
> descriptors
= vNULL
;
5447 struct func_body_info fbi
;
5448 struct ipa_agg_replacement_value
*aggval
;
5450 bool cfg_changed
= false, something_changed
= false;
5452 gcc_checking_assert (cfun
);
5453 gcc_checking_assert (current_function_decl
);
5456 fprintf (dump_file
, "Modification phase of node %s/%i\n",
5457 node
->name (), node
->order
);
5459 aggval
= ipa_get_agg_replacements_for_node (node
);
5462 param_count
= count_formal_params (node
->decl
);
5463 if (param_count
== 0)
5465 adjust_agg_replacement_values (node
, aggval
);
5467 ipa_dump_agg_replacement_values (dump_file
, aggval
);
5471 fbi
.bb_infos
= vNULL
;
5472 fbi
.bb_infos
.safe_grow_cleared (last_basic_block_for_fn (cfun
));
5473 fbi
.param_count
= param_count
;
5476 descriptors
.safe_grow_cleared (param_count
);
5477 ipa_populate_param_decls (node
, descriptors
);
5478 calculate_dominance_info (CDI_DOMINATORS
);
5479 ipcp_modif_dom_walker (&fbi
, descriptors
, aggval
, &something_changed
,
5480 &cfg_changed
).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
5483 struct ipa_bb_info
*bi
;
5484 FOR_EACH_VEC_ELT (fbi
.bb_infos
, i
, bi
)
5485 free_ipa_bb_info (bi
);
5486 fbi
.bb_infos
.release ();
5487 free_dominance_info (CDI_DOMINATORS
);
5488 (*ipa_node_agg_replacements
)[node
->uid
] = NULL
;
5489 descriptors
.release ();
5491 if (!something_changed
)
5493 else if (cfg_changed
)
5494 return TODO_update_ssa_only_virtuals
| TODO_cleanup_cfg
;
5496 return TODO_update_ssa_only_virtuals
;