1 /* Interprocedural analyses.
2 Copyright (C) 2005-2014 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
24 #include "basic-block.h"
25 #include "tree-ssa-alias.h"
26 #include "internal-fn.h"
27 #include "gimple-fold.h"
29 #include "gimple-expr.h"
33 #include "stor-layout.h"
34 #include "print-tree.h"
36 #include "gimple-iterator.h"
37 #include "gimplify-me.h"
38 #include "gimple-walk.h"
39 #include "langhooks.h"
43 #include "gimple-ssa.h"
45 #include "tree-phinodes.h"
46 #include "ssa-iterators.h"
47 #include "tree-into-ssa.h"
49 #include "tree-pass.h"
50 #include "tree-inline.h"
51 #include "ipa-inline.h"
53 #include "diagnostic.h"
54 #include "gimple-pretty-print.h"
55 #include "lto-streamer.h"
56 #include "data-streamer.h"
57 #include "tree-streamer.h"
59 #include "ipa-utils.h"
60 #include "stringpool.h"
61 #include "tree-ssanames.h"
67 /* Intermediate information that we get from alias analysis about a particular
68 parameter in a particular basic_block. When a parameter or the memory it
69 references is marked modified, we use that information in all dominatd
70 blocks without cosulting alias analysis oracle. */
72 struct param_aa_status
74 /* Set when this structure contains meaningful information. If not, the
75 structure describing a dominating BB should be used instead. */
78 /* Whether we have seen something which might have modified the data in
79 question. PARM is for the parameter itself, REF is for data it points to
80 but using the alias type of individual accesses and PT is the same thing
81 but for computing aggregate pass-through functions using a very inclusive
83 bool parm_modified
, ref_modified
, pt_modified
;
86 /* Information related to a given BB that used only when looking at function
91 /* Call graph edges going out of this BB. */
92 vec
<cgraph_edge_p
> cg_edges
;
93 /* Alias analysis statuses of each formal parameter at this bb. */
94 vec
<param_aa_status
> param_aa_statuses
;
97 /* Structure with global information that is only used when looking at function
100 struct func_body_info
102 /* The node that is being analyzed. */
106 struct ipa_node_params
*info
;
108 /* Information about individual BBs. */
109 vec
<ipa_bb_info
> bb_infos
;
111 /* Number of parameters. */
114 /* Number of statements already walked by when analyzing this function. */
115 unsigned int aa_walked
;
118 /* Vector where the parameter infos are actually stored. */
119 vec
<ipa_node_params
> ipa_node_params_vector
;
120 /* Vector of known aggregate values in cloned nodes. */
121 vec
<ipa_agg_replacement_value_p
, va_gc
> *ipa_node_agg_replacements
;
122 /* Vector where the parameter infos are actually stored. */
123 vec
<ipa_edge_args
, va_gc
> *ipa_edge_args_vector
;
125 /* Holders of ipa cgraph hooks: */
126 static struct cgraph_edge_hook_list
*edge_removal_hook_holder
;
127 static struct cgraph_node_hook_list
*node_removal_hook_holder
;
128 static struct cgraph_2edge_hook_list
*edge_duplication_hook_holder
;
129 static struct cgraph_2node_hook_list
*node_duplication_hook_holder
;
130 static struct cgraph_node_hook_list
*function_insertion_hook_holder
;
132 /* Description of a reference to an IPA constant. */
133 struct ipa_cst_ref_desc
135 /* Edge that corresponds to the statement which took the reference. */
136 struct cgraph_edge
*cs
;
137 /* Linked list of duplicates created when call graph edges are cloned. */
138 struct ipa_cst_ref_desc
*next_duplicate
;
139 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
140 if out of control. */
144 /* Allocation pool for reference descriptions. */
146 static alloc_pool ipa_refdesc_pool
;
148 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
149 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
152 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node
*node
)
154 tree fs_opts
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node
->decl
);
155 struct cl_optimization
*os
;
159 os
= TREE_OPTIMIZATION (fs_opts
);
160 return !os
->x_optimize
|| !os
->x_flag_ipa_cp
;
163 /* Return index of the formal whose tree is PTREE in function which corresponds
167 ipa_get_param_decl_index_1 (vec
<ipa_param_descriptor
> descriptors
, tree ptree
)
171 count
= descriptors
.length ();
172 for (i
= 0; i
< count
; i
++)
173 if (descriptors
[i
].decl
== ptree
)
179 /* Return index of the formal whose tree is PTREE in function which corresponds
183 ipa_get_param_decl_index (struct ipa_node_params
*info
, tree ptree
)
185 return ipa_get_param_decl_index_1 (info
->descriptors
, ptree
);
188 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
192 ipa_populate_param_decls (struct cgraph_node
*node
,
193 vec
<ipa_param_descriptor
> &descriptors
)
201 gcc_assert (gimple_has_body_p (fndecl
));
202 fnargs
= DECL_ARGUMENTS (fndecl
);
204 for (parm
= fnargs
; parm
; parm
= DECL_CHAIN (parm
))
206 descriptors
[param_num
].decl
= parm
;
207 descriptors
[param_num
].move_cost
= estimate_move_cost (TREE_TYPE (parm
));
212 /* Return how many formal parameters FNDECL has. */
215 count_formal_params (tree fndecl
)
219 gcc_assert (gimple_has_body_p (fndecl
));
221 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
227 /* Return the declaration of Ith formal parameter of the function corresponding
228 to INFO. Note there is no setter function as this array is built just once
229 using ipa_initialize_node_params. */
232 ipa_dump_param (FILE *file
, struct ipa_node_params
*info
, int i
)
234 fprintf (file
, "param #%i", i
);
235 if (info
->descriptors
[i
].decl
)
238 print_generic_expr (file
, info
->descriptors
[i
].decl
, 0);
242 /* Initialize the ipa_node_params structure associated with NODE
243 to hold PARAM_COUNT parameters. */
246 ipa_alloc_node_params (struct cgraph_node
*node
, int param_count
)
248 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
250 if (!info
->descriptors
.exists () && param_count
)
251 info
->descriptors
.safe_grow_cleared (param_count
);
254 /* Initialize the ipa_node_params structure associated with NODE by counting
255 the function parameters, creating the descriptors and populating their
259 ipa_initialize_node_params (struct cgraph_node
*node
)
261 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
263 if (!info
->descriptors
.exists ())
265 ipa_alloc_node_params (node
, count_formal_params (node
->decl
));
266 ipa_populate_param_decls (node
, info
->descriptors
);
270 /* Print the jump functions associated with call graph edge CS to file F. */
273 ipa_print_node_jump_functions_for_edge (FILE *f
, struct cgraph_edge
*cs
)
277 count
= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
));
278 for (i
= 0; i
< count
; i
++)
280 struct ipa_jump_func
*jump_func
;
281 enum jump_func_type type
;
283 jump_func
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), i
);
284 type
= jump_func
->type
;
286 fprintf (f
, " param %d: ", i
);
287 if (type
== IPA_JF_UNKNOWN
)
288 fprintf (f
, "UNKNOWN\n");
289 else if (type
== IPA_JF_KNOWN_TYPE
)
291 fprintf (f
, "KNOWN TYPE: base ");
292 print_generic_expr (f
, jump_func
->value
.known_type
.base_type
, 0);
293 fprintf (f
, ", offset "HOST_WIDE_INT_PRINT_DEC
", component ",
294 jump_func
->value
.known_type
.offset
);
295 print_generic_expr (f
, jump_func
->value
.known_type
.component_type
, 0);
298 else if (type
== IPA_JF_CONST
)
300 tree val
= jump_func
->value
.constant
.value
;
301 fprintf (f
, "CONST: ");
302 print_generic_expr (f
, val
, 0);
303 if (TREE_CODE (val
) == ADDR_EXPR
304 && TREE_CODE (TREE_OPERAND (val
, 0)) == CONST_DECL
)
307 print_generic_expr (f
, DECL_INITIAL (TREE_OPERAND (val
, 0)),
312 else if (type
== IPA_JF_PASS_THROUGH
)
314 fprintf (f
, "PASS THROUGH: ");
315 fprintf (f
, "%d, op %s",
316 jump_func
->value
.pass_through
.formal_id
,
317 get_tree_code_name(jump_func
->value
.pass_through
.operation
));
318 if (jump_func
->value
.pass_through
.operation
!= NOP_EXPR
)
321 print_generic_expr (f
,
322 jump_func
->value
.pass_through
.operand
, 0);
324 if (jump_func
->value
.pass_through
.agg_preserved
)
325 fprintf (f
, ", agg_preserved");
326 if (jump_func
->value
.pass_through
.type_preserved
)
327 fprintf (f
, ", type_preserved");
330 else if (type
== IPA_JF_ANCESTOR
)
332 fprintf (f
, "ANCESTOR: ");
333 fprintf (f
, "%d, offset "HOST_WIDE_INT_PRINT_DEC
", ",
334 jump_func
->value
.ancestor
.formal_id
,
335 jump_func
->value
.ancestor
.offset
);
336 print_generic_expr (f
, jump_func
->value
.ancestor
.type
, 0);
337 if (jump_func
->value
.ancestor
.agg_preserved
)
338 fprintf (f
, ", agg_preserved");
339 if (jump_func
->value
.ancestor
.type_preserved
)
340 fprintf (f
, ", type_preserved");
344 if (jump_func
->agg
.items
)
346 struct ipa_agg_jf_item
*item
;
349 fprintf (f
, " Aggregate passed by %s:\n",
350 jump_func
->agg
.by_ref
? "reference" : "value");
351 FOR_EACH_VEC_SAFE_ELT (jump_func
->agg
.items
, j
, item
)
353 fprintf (f
, " offset: " HOST_WIDE_INT_PRINT_DEC
", ",
355 if (TYPE_P (item
->value
))
356 fprintf (f
, "clobber of " HOST_WIDE_INT_PRINT_DEC
" bits",
357 tree_to_uhwi (TYPE_SIZE (item
->value
)));
360 fprintf (f
, "cst: ");
361 print_generic_expr (f
, item
->value
, 0);
370 /* Print the jump functions of all arguments on all call graph edges going from
374 ipa_print_node_jump_functions (FILE *f
, struct cgraph_node
*node
)
376 struct cgraph_edge
*cs
;
378 fprintf (f
, " Jump functions of caller %s/%i:\n", node
->name (),
380 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
382 if (!ipa_edge_args_info_available_for_edge_p (cs
))
385 fprintf (f
, " callsite %s/%i -> %s/%i : \n",
386 xstrdup (node
->name ()), node
->order
,
387 xstrdup (cs
->callee
->name ()),
389 ipa_print_node_jump_functions_for_edge (f
, cs
);
392 for (cs
= node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
394 struct cgraph_indirect_call_info
*ii
;
395 if (!ipa_edge_args_info_available_for_edge_p (cs
))
398 ii
= cs
->indirect_info
;
399 if (ii
->agg_contents
)
400 fprintf (f
, " indirect %s callsite, calling param %i, "
401 "offset " HOST_WIDE_INT_PRINT_DEC
", %s",
402 ii
->member_ptr
? "member ptr" : "aggregate",
403 ii
->param_index
, ii
->offset
,
404 ii
->by_ref
? "by reference" : "by_value");
406 fprintf (f
, " indirect %s callsite, calling param %i, "
407 "offset " HOST_WIDE_INT_PRINT_DEC
,
408 ii
->polymorphic
? "polymorphic" : "simple", ii
->param_index
,
413 fprintf (f
, ", for stmt ");
414 print_gimple_stmt (f
, cs
->call_stmt
, 0, TDF_SLIM
);
418 ipa_print_node_jump_functions_for_edge (f
, cs
);
422 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
425 ipa_print_all_jump_functions (FILE *f
)
427 struct cgraph_node
*node
;
429 fprintf (f
, "\nJump functions:\n");
430 FOR_EACH_FUNCTION (node
)
432 ipa_print_node_jump_functions (f
, node
);
436 /* Set JFUNC to be a known type jump function. */
439 ipa_set_jf_known_type (struct ipa_jump_func
*jfunc
, HOST_WIDE_INT offset
,
440 tree base_type
, tree component_type
)
442 /* Recording and propagating main variants increases change that types
444 base_type
= TYPE_MAIN_VARIANT (base_type
);
445 component_type
= TYPE_MAIN_VARIANT (component_type
);
447 gcc_assert (contains_polymorphic_type_p (base_type
)
448 && contains_polymorphic_type_p (component_type
));
449 if (!flag_devirtualize
)
451 jfunc
->type
= IPA_JF_KNOWN_TYPE
;
452 jfunc
->value
.known_type
.offset
= offset
,
453 jfunc
->value
.known_type
.base_type
= base_type
;
454 jfunc
->value
.known_type
.component_type
= component_type
;
455 gcc_assert (component_type
);
458 /* Set JFUNC to be a copy of another jmp (to be used by jump function
459 combination code). The two functions will share their rdesc. */
462 ipa_set_jf_cst_copy (struct ipa_jump_func
*dst
,
463 struct ipa_jump_func
*src
)
466 gcc_checking_assert (src
->type
== IPA_JF_CONST
);
467 dst
->type
= IPA_JF_CONST
;
468 dst
->value
.constant
= src
->value
.constant
;
471 /* Set JFUNC to be a constant jmp function. */
474 ipa_set_jf_constant (struct ipa_jump_func
*jfunc
, tree constant
,
475 struct cgraph_edge
*cs
)
477 constant
= unshare_expr (constant
);
478 if (constant
&& EXPR_P (constant
))
479 SET_EXPR_LOCATION (constant
, UNKNOWN_LOCATION
);
480 jfunc
->type
= IPA_JF_CONST
;
481 jfunc
->value
.constant
.value
= unshare_expr_without_location (constant
);
483 if (TREE_CODE (constant
) == ADDR_EXPR
484 && TREE_CODE (TREE_OPERAND (constant
, 0)) == FUNCTION_DECL
)
486 struct ipa_cst_ref_desc
*rdesc
;
487 if (!ipa_refdesc_pool
)
488 ipa_refdesc_pool
= create_alloc_pool ("IPA-PROP ref descriptions",
489 sizeof (struct ipa_cst_ref_desc
), 32);
491 rdesc
= (struct ipa_cst_ref_desc
*) pool_alloc (ipa_refdesc_pool
);
493 rdesc
->next_duplicate
= NULL
;
495 jfunc
->value
.constant
.rdesc
= rdesc
;
498 jfunc
->value
.constant
.rdesc
= NULL
;
501 /* Set JFUNC to be a simple pass-through jump function. */
503 ipa_set_jf_simple_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
504 bool agg_preserved
, bool type_preserved
)
506 jfunc
->type
= IPA_JF_PASS_THROUGH
;
507 jfunc
->value
.pass_through
.operand
= NULL_TREE
;
508 jfunc
->value
.pass_through
.formal_id
= formal_id
;
509 jfunc
->value
.pass_through
.operation
= NOP_EXPR
;
510 jfunc
->value
.pass_through
.agg_preserved
= agg_preserved
;
511 jfunc
->value
.pass_through
.type_preserved
= type_preserved
;
514 /* Set JFUNC to be an arithmetic pass through jump function. */
517 ipa_set_jf_arith_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
518 tree operand
, enum tree_code operation
)
520 jfunc
->type
= IPA_JF_PASS_THROUGH
;
521 jfunc
->value
.pass_through
.operand
= unshare_expr_without_location (operand
);
522 jfunc
->value
.pass_through
.formal_id
= formal_id
;
523 jfunc
->value
.pass_through
.operation
= operation
;
524 jfunc
->value
.pass_through
.agg_preserved
= false;
525 jfunc
->value
.pass_through
.type_preserved
= false;
528 /* Set JFUNC to be an ancestor jump function. */
531 ipa_set_ancestor_jf (struct ipa_jump_func
*jfunc
, HOST_WIDE_INT offset
,
532 tree type
, int formal_id
, bool agg_preserved
,
535 if (!flag_devirtualize
)
536 type_preserved
= false;
540 type
= TYPE_MAIN_VARIANT (type
);
541 gcc_assert (!type_preserved
|| contains_polymorphic_type_p (type
));
542 jfunc
->type
= IPA_JF_ANCESTOR
;
543 jfunc
->value
.ancestor
.formal_id
= formal_id
;
544 jfunc
->value
.ancestor
.offset
= offset
;
545 jfunc
->value
.ancestor
.type
= type_preserved
? type
: NULL
;
546 jfunc
->value
.ancestor
.agg_preserved
= agg_preserved
;
547 jfunc
->value
.ancestor
.type_preserved
= type_preserved
;
550 /* Extract the acual BINFO being described by JFUNC which must be a known type
554 ipa_binfo_from_known_type_jfunc (struct ipa_jump_func
*jfunc
)
556 if (!RECORD_OR_UNION_TYPE_P (jfunc
->value
.known_type
.base_type
))
559 tree base_binfo
= TYPE_BINFO (jfunc
->value
.known_type
.base_type
);
563 return get_binfo_at_offset (base_binfo
,
564 jfunc
->value
.known_type
.offset
,
565 jfunc
->value
.known_type
.component_type
);
568 /* Get IPA BB information about the given BB. FBI is the context of analyzis
569 of this function body. */
571 static struct ipa_bb_info
*
572 ipa_get_bb_info (struct func_body_info
*fbi
, basic_block bb
)
574 gcc_checking_assert (fbi
);
575 return &fbi
->bb_infos
[bb
->index
];
578 /* Structure to be passed in between detect_type_change and
579 check_stmt_for_type_change. */
581 struct type_change_info
583 /* Offset into the object where there is the virtual method pointer we are
585 HOST_WIDE_INT offset
;
586 /* The declaration or SSA_NAME pointer of the base that we are checking for
589 /* If we actually can tell the type that the object has changed to, it is
590 stored in this field. Otherwise it remains NULL_TREE. */
591 tree known_current_type
;
592 /* Set to true if dynamic type change has been detected. */
593 bool type_maybe_changed
;
594 /* Set to true if multiple types have been encountered. known_current_type
595 must be disregarded in that case. */
596 bool multiple_types_encountered
;
599 /* Return true if STMT can modify a virtual method table pointer.
601 This function makes special assumptions about both constructors and
602 destructors which are all the functions that are allowed to alter the VMT
603 pointers. It assumes that destructors begin with assignment into all VMT
604 pointers and that constructors essentially look in the following way:
606 1) The very first thing they do is that they call constructors of ancestor
607 sub-objects that have them.
609 2) Then VMT pointers of this and all its ancestors is set to new values
610 corresponding to the type corresponding to the constructor.
612 3) Only afterwards, other stuff such as constructor of member sub-objects
613 and the code written by the user is run. Only this may include calling
614 virtual functions, directly or indirectly.
616 There is no way to call a constructor of an ancestor sub-object in any
619 This means that we do not have to care whether constructors get the correct
620 type information because they will always change it (in fact, if we define
621 the type to be given by the VMT pointer, it is undefined).
623 The most important fact to derive from the above is that if, for some
624 statement in the section 3, we try to detect whether the dynamic type has
625 changed, we can safely ignore all calls as we examine the function body
626 backwards until we reach statements in section 2 because these calls cannot
627 be ancestor constructors or destructors (if the input is not bogus) and so
628 do not change the dynamic type (this holds true only for automatically
629 allocated objects but at the moment we devirtualize only these). We then
630 must detect that statements in section 2 change the dynamic type and can try
631 to derive the new type. That is enough and we can stop, we will never see
632 the calls into constructors of sub-objects in this code. Therefore we can
633 safely ignore all call statements that we traverse.
637 stmt_may_be_vtbl_ptr_store (gimple stmt
)
639 if (is_gimple_call (stmt
))
641 if (gimple_clobber_p (stmt
))
643 else if (is_gimple_assign (stmt
))
645 tree lhs
= gimple_assign_lhs (stmt
);
647 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs
)))
649 if (flag_strict_aliasing
650 && !POINTER_TYPE_P (TREE_TYPE (lhs
)))
653 if (TREE_CODE (lhs
) == COMPONENT_REF
654 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs
, 1)))
656 /* In the future we might want to use get_base_ref_and_offset to find
657 if there is a field corresponding to the offset and if so, proceed
658 almost like if it was a component ref. */
664 /* If STMT can be proved to be an assignment to the virtual method table
665 pointer of ANALYZED_OBJ and the type associated with the new table
666 identified, return the type. Otherwise return NULL_TREE. */
669 extr_type_from_vtbl_ptr_store (gimple stmt
, struct type_change_info
*tci
)
671 HOST_WIDE_INT offset
, size
, max_size
;
672 tree lhs
, rhs
, base
, binfo
;
674 if (!gimple_assign_single_p (stmt
))
677 lhs
= gimple_assign_lhs (stmt
);
678 rhs
= gimple_assign_rhs1 (stmt
);
679 if (TREE_CODE (lhs
) != COMPONENT_REF
680 || !DECL_VIRTUAL_P (TREE_OPERAND (lhs
, 1)))
683 base
= get_ref_base_and_extent (lhs
, &offset
, &size
, &max_size
);
684 if (offset
!= tci
->offset
685 || size
!= POINTER_SIZE
686 || max_size
!= POINTER_SIZE
)
688 if (TREE_CODE (base
) == MEM_REF
)
690 if (TREE_CODE (tci
->object
) != MEM_REF
691 || TREE_OPERAND (tci
->object
, 0) != TREE_OPERAND (base
, 0)
692 || !tree_int_cst_equal (TREE_OPERAND (tci
->object
, 1),
693 TREE_OPERAND (base
, 1)))
696 else if (tci
->object
!= base
)
699 binfo
= vtable_pointer_value_to_binfo (rhs
);
701 /* FIXME: vtable_pointer_value_to_binfo may return BINFO of a
702 base of outer type. In this case we would need to either
703 work on binfos or translate it back to outer type and offset.
704 KNOWN_TYPE jump functions are not ready for that, yet. */
705 if (!binfo
|| TYPE_BINFO (BINFO_TYPE (binfo
)) != binfo
)
708 return BINFO_TYPE (binfo
);
711 /* Callback of walk_aliased_vdefs and a helper function for
712 detect_type_change to check whether a particular statement may modify
713 the virtual table pointer, and if possible also determine the new type of
714 the (sub-)object. It stores its result into DATA, which points to a
715 type_change_info structure. */
718 check_stmt_for_type_change (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef
, void *data
)
720 gimple stmt
= SSA_NAME_DEF_STMT (vdef
);
721 struct type_change_info
*tci
= (struct type_change_info
*) data
;
723 if (stmt_may_be_vtbl_ptr_store (stmt
))
727 type
= extr_type_from_vtbl_ptr_store (stmt
, tci
);
728 gcc_assert (!type
|| TYPE_MAIN_VARIANT (type
) == type
);
729 if (tci
->type_maybe_changed
730 && type
!= tci
->known_current_type
)
731 tci
->multiple_types_encountered
= true;
732 tci
->known_current_type
= type
;
733 tci
->type_maybe_changed
= true;
740 /* See if ARG is PARAM_DECl describing instance passed by pointer
741 or reference in FUNCTION. Return false if the dynamic type may change
742 in between beggining of the function until CALL is invoked.
744 Generally functions are not allowed to change type of such instances,
745 but they call destructors. We assume that methods can not destroy the THIS
746 pointer. Also as a special cases, constructor and destructors may change
747 type of the THIS pointer. */
750 param_type_may_change_p (tree function
, tree arg
, gimple call
)
752 /* Pure functions can not do any changes on the dynamic type;
753 that require writting to memory. */
754 if (flags_from_decl_or_type (function
) & (ECF_PURE
| ECF_CONST
))
756 /* We need to check if we are within inlined consturctor
757 or destructor (ideally we would have way to check that the
758 inline cdtor is actually working on ARG, but we don't have
759 easy tie on this, so punt on all non-pure cdtors.
760 We may also record the types of cdtors and once we know type
761 of the instance match them.
763 Also code unification optimizations may merge calls from
764 different blocks making return values unreliable. So
765 do nothing during late optimization. */
766 if (DECL_STRUCT_FUNCTION (function
)->after_inlining
)
768 if (TREE_CODE (arg
) == SSA_NAME
769 && SSA_NAME_IS_DEFAULT_DEF (arg
)
770 && TREE_CODE (SSA_NAME_VAR (arg
)) == PARM_DECL
)
772 /* Normal (non-THIS) argument. */
773 if ((SSA_NAME_VAR (arg
) != DECL_ARGUMENTS (function
)
774 || TREE_CODE (TREE_TYPE (function
)) != METHOD_TYPE
)
775 /* THIS pointer of an method - here we we want to watch constructors
776 and destructors as those definitely may change the dynamic
778 || (TREE_CODE (TREE_TYPE (function
)) == METHOD_TYPE
779 && !DECL_CXX_CONSTRUCTOR_P (function
)
780 && !DECL_CXX_DESTRUCTOR_P (function
)
781 && (SSA_NAME_VAR (arg
) == DECL_ARGUMENTS (function
))))
783 /* Walk the inline stack and watch out for ctors/dtors. */
784 for (tree block
= gimple_block (call
); block
&& TREE_CODE (block
) == BLOCK
;
785 block
= BLOCK_SUPERCONTEXT (block
))
786 if (BLOCK_ABSTRACT_ORIGIN (block
)
787 && TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block
)) == FUNCTION_DECL
)
789 tree fn
= BLOCK_ABSTRACT_ORIGIN (block
);
791 if (flags_from_decl_or_type (fn
) & (ECF_PURE
| ECF_CONST
))
793 if (TREE_CODE (TREE_TYPE (fn
)) == METHOD_TYPE
794 && (DECL_CXX_CONSTRUCTOR_P (fn
)
795 || DECL_CXX_DESTRUCTOR_P (fn
)))
804 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
805 callsite CALL) by looking for assignments to its virtual table pointer. If
806 it is, return true and fill in the jump function JFUNC with relevant type
807 information or set it to unknown. ARG is the object itself (not a pointer
808 to it, unless dereferenced). BASE is the base of the memory access as
809 returned by get_ref_base_and_extent, as is the offset.
811 This is helper function for detect_type_change and detect_type_change_ssa
812 that does the heavy work which is usually unnecesary. */
815 detect_type_change_from_memory_writes (tree arg
, tree base
, tree comp_type
,
816 gimple call
, struct ipa_jump_func
*jfunc
,
817 HOST_WIDE_INT offset
)
819 struct type_change_info tci
;
821 bool entry_reached
= false;
823 gcc_checking_assert (DECL_P (arg
)
824 || TREE_CODE (arg
) == MEM_REF
825 || handled_component_p (arg
));
827 comp_type
= TYPE_MAIN_VARIANT (comp_type
);
829 /* Const calls cannot call virtual methods through VMT and so type changes do
831 if (!flag_devirtualize
|| !gimple_vuse (call
)
832 /* Be sure expected_type is polymorphic. */
834 || TREE_CODE (comp_type
) != RECORD_TYPE
835 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type
))
836 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type
))))
839 ao_ref_init (&ao
, arg
);
842 ao
.size
= POINTER_SIZE
;
843 ao
.max_size
= ao
.size
;
846 tci
.object
= get_base_address (arg
);
847 tci
.known_current_type
= NULL_TREE
;
848 tci
.type_maybe_changed
= false;
849 tci
.multiple_types_encountered
= false;
851 walk_aliased_vdefs (&ao
, gimple_vuse (call
), check_stmt_for_type_change
,
852 &tci
, NULL
, &entry_reached
);
853 if (!tci
.type_maybe_changed
)
856 if (!tci
.known_current_type
857 || tci
.multiple_types_encountered
859 /* When the walk reached function entry, it means that type
860 is set along some paths but not along others. */
862 jfunc
->type
= IPA_JF_UNKNOWN
;
864 ipa_set_jf_known_type (jfunc
, 0, tci
.known_current_type
, comp_type
);
869 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
870 If it is, return true and fill in the jump function JFUNC with relevant type
871 information or set it to unknown. ARG is the object itself (not a pointer
872 to it, unless dereferenced). BASE is the base of the memory access as
873 returned by get_ref_base_and_extent, as is the offset. */
876 detect_type_change (tree arg
, tree base
, tree comp_type
, gimple call
,
877 struct ipa_jump_func
*jfunc
, HOST_WIDE_INT offset
)
879 if (!flag_devirtualize
)
882 if (TREE_CODE (base
) == MEM_REF
883 && !param_type_may_change_p (current_function_decl
,
884 TREE_OPERAND (base
, 0),
887 return detect_type_change_from_memory_writes (arg
, base
, comp_type
,
888 call
, jfunc
, offset
);
891 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
892 SSA name (its dereference will become the base and the offset is assumed to
896 detect_type_change_ssa (tree arg
, tree comp_type
,
897 gimple call
, struct ipa_jump_func
*jfunc
)
899 gcc_checking_assert (TREE_CODE (arg
) == SSA_NAME
);
900 if (!flag_devirtualize
901 || !POINTER_TYPE_P (TREE_TYPE (arg
)))
904 if (!param_type_may_change_p (current_function_decl
, arg
, call
))
907 arg
= build2 (MEM_REF
, ptr_type_node
, arg
,
908 build_int_cst (ptr_type_node
, 0));
910 return detect_type_change_from_memory_writes (arg
, arg
, comp_type
,
914 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
915 boolean variable pointed to by DATA. */
918 mark_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
921 bool *b
= (bool *) data
;
926 /* Return true if we have already walked so many statements in AA that we
927 should really just start giving up. */
930 aa_overwalked (struct func_body_info
*fbi
)
932 gcc_checking_assert (fbi
);
933 return fbi
->aa_walked
> (unsigned) PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS
);
936 /* Find the nearest valid aa status for parameter specified by INDEX that
939 static struct param_aa_status
*
940 find_dominating_aa_status (struct func_body_info
*fbi
, basic_block bb
,
945 bb
= get_immediate_dominator (CDI_DOMINATORS
, bb
);
948 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
949 if (!bi
->param_aa_statuses
.is_empty ()
950 && bi
->param_aa_statuses
[index
].valid
)
951 return &bi
->param_aa_statuses
[index
];
955 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
956 structures and/or intialize the result with a dominating description as
959 static struct param_aa_status
*
960 parm_bb_aa_status_for_bb (struct func_body_info
*fbi
, basic_block bb
,
963 gcc_checking_assert (fbi
);
964 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
965 if (bi
->param_aa_statuses
.is_empty ())
966 bi
->param_aa_statuses
.safe_grow_cleared (fbi
->param_count
);
967 struct param_aa_status
*paa
= &bi
->param_aa_statuses
[index
];
970 gcc_checking_assert (!paa
->parm_modified
971 && !paa
->ref_modified
972 && !paa
->pt_modified
);
973 struct param_aa_status
*dom_paa
;
974 dom_paa
= find_dominating_aa_status (fbi
, bb
, index
);
984 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
985 a value known not to be modified in this function before reaching the
986 statement STMT. FBI holds information about the function we have so far
987 gathered but do not survive the summary building stage. */
990 parm_preserved_before_stmt_p (struct func_body_info
*fbi
, int index
,
991 gimple stmt
, tree parm_load
)
993 struct param_aa_status
*paa
;
994 bool modified
= false;
997 /* FIXME: FBI can be NULL if we are being called from outside
998 ipa_node_analysis or ipcp_transform_function, which currently happens
999 during inlining analysis. It would be great to extend fbi's lifetime and
1000 always have it. Currently, we are just not afraid of too much walking in
1004 if (aa_overwalked (fbi
))
1006 paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (stmt
), index
);
1007 if (paa
->parm_modified
)
1013 gcc_checking_assert (gimple_vuse (stmt
) != NULL_TREE
);
1014 ao_ref_init (&refd
, parm_load
);
1015 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), mark_modified
,
1018 fbi
->aa_walked
+= walked
;
1019 if (paa
&& modified
)
1020 paa
->parm_modified
= true;
1024 /* If STMT is an assignment that loads a value from an parameter declaration,
1025 return the index of the parameter in ipa_node_params which has not been
1026 modified. Otherwise return -1. */
1029 load_from_unmodified_param (struct func_body_info
*fbi
,
1030 vec
<ipa_param_descriptor
> descriptors
,
1036 if (!gimple_assign_single_p (stmt
))
1039 op1
= gimple_assign_rhs1 (stmt
);
1040 if (TREE_CODE (op1
) != PARM_DECL
)
1043 index
= ipa_get_param_decl_index_1 (descriptors
, op1
);
1045 || !parm_preserved_before_stmt_p (fbi
, index
, stmt
, op1
))
1051 /* Return true if memory reference REF (which must be a load through parameter
1052 with INDEX) loads data that are known to be unmodified in this function
1053 before reaching statement STMT. */
1056 parm_ref_data_preserved_p (struct func_body_info
*fbi
,
1057 int index
, gimple stmt
, tree ref
)
1059 struct param_aa_status
*paa
;
1060 bool modified
= false;
1063 /* FIXME: FBI can be NULL if we are being called from outside
1064 ipa_node_analysis or ipcp_transform_function, which currently happens
1065 during inlining analysis. It would be great to extend fbi's lifetime and
1066 always have it. Currently, we are just not afraid of too much walking in
1070 if (aa_overwalked (fbi
))
1072 paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (stmt
), index
);
1073 if (paa
->ref_modified
)
1079 gcc_checking_assert (gimple_vuse (stmt
));
1080 ao_ref_init (&refd
, ref
);
1081 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), mark_modified
,
1084 fbi
->aa_walked
+= walked
;
1085 if (paa
&& modified
)
1086 paa
->ref_modified
= true;
1090 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
1091 is known to be unmodified in this function before reaching call statement
1092 CALL into which it is passed. FBI describes the function body. */
1095 parm_ref_data_pass_through_p (struct func_body_info
*fbi
, int index
,
1096 gimple call
, tree parm
)
1098 bool modified
= false;
1101 /* It's unnecessary to calculate anything about memory contnets for a const
1102 function because it is not goin to use it. But do not cache the result
1103 either. Also, no such calculations for non-pointers. */
1104 if (!gimple_vuse (call
)
1105 || !POINTER_TYPE_P (TREE_TYPE (parm
))
1106 || aa_overwalked (fbi
))
1109 struct param_aa_status
*paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (call
),
1111 if (paa
->pt_modified
)
1114 ao_ref_init_from_ptr_and_size (&refd
, parm
, NULL_TREE
);
1115 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (call
), mark_modified
,
1117 fbi
->aa_walked
+= walked
;
1119 paa
->pt_modified
= true;
1123 /* Return true if we can prove that OP is a memory reference loading unmodified
1124 data from an aggregate passed as a parameter and if the aggregate is passed
1125 by reference, that the alias type of the load corresponds to the type of the
1126 formal parameter (so that we can rely on this type for TBAA in callers).
1127 INFO and PARMS_AINFO describe parameters of the current function (but the
1128 latter can be NULL), STMT is the load statement. If function returns true,
1129 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1130 within the aggregate and whether it is a load from a value passed by
1131 reference respectively. */
1134 ipa_load_from_parm_agg_1 (struct func_body_info
*fbi
,
1135 vec
<ipa_param_descriptor
> descriptors
,
1136 gimple stmt
, tree op
, int *index_p
,
1137 HOST_WIDE_INT
*offset_p
, HOST_WIDE_INT
*size_p
,
1141 HOST_WIDE_INT size
, max_size
;
1142 tree base
= get_ref_base_and_extent (op
, offset_p
, &size
, &max_size
);
1144 if (max_size
== -1 || max_size
!= size
|| *offset_p
< 0)
1149 int index
= ipa_get_param_decl_index_1 (descriptors
, base
);
1151 && parm_preserved_before_stmt_p (fbi
, index
, stmt
, op
))
1162 if (TREE_CODE (base
) != MEM_REF
1163 || TREE_CODE (TREE_OPERAND (base
, 0)) != SSA_NAME
1164 || !integer_zerop (TREE_OPERAND (base
, 1)))
1167 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base
, 0)))
1169 tree parm
= SSA_NAME_VAR (TREE_OPERAND (base
, 0));
1170 index
= ipa_get_param_decl_index_1 (descriptors
, parm
);
1174 /* This branch catches situations where a pointer parameter is not a
1175 gimple register, for example:
1177 void hip7(S*) (struct S * p)
1179 void (*<T2e4>) (struct S *) D.1867;
1184 D.1867_2 = p.1_1->f;
1189 gimple def
= SSA_NAME_DEF_STMT (TREE_OPERAND (base
, 0));
1190 index
= load_from_unmodified_param (fbi
, descriptors
, def
);
1194 && parm_ref_data_preserved_p (fbi
, index
, stmt
, op
))
1205 /* Just like the previous function, just without the param_analysis_info
1206 pointer, for users outside of this file. */
1209 ipa_load_from_parm_agg (struct ipa_node_params
*info
, gimple stmt
,
1210 tree op
, int *index_p
, HOST_WIDE_INT
*offset_p
,
1213 return ipa_load_from_parm_agg_1 (NULL
, info
->descriptors
, stmt
, op
, index_p
,
1214 offset_p
, NULL
, by_ref_p
);
1217 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1218 of an assignment statement STMT, try to determine whether we are actually
1219 handling any of the following cases and construct an appropriate jump
1220 function into JFUNC if so:
1222 1) The passed value is loaded from a formal parameter which is not a gimple
1223 register (most probably because it is addressable, the value has to be
1224 scalar) and we can guarantee the value has not changed. This case can
1225 therefore be described by a simple pass-through jump function. For example:
1234 2) The passed value can be described by a simple arithmetic pass-through
1241 D.2064_4 = a.1(D) + 4;
1244 This case can also occur in combination of the previous one, e.g.:
1252 D.2064_4 = a.0_3 + 4;
1255 3) The passed value is an address of an object within another one (which
1256 also passed by reference). Such situations are described by an ancestor
1257 jump function and describe situations such as:
1259 B::foo() (struct B * const this)
1263 D.1845_2 = &this_1(D)->D.1748;
1266 INFO is the structure describing individual parameters access different
1267 stages of IPA optimizations. PARMS_AINFO contains the information that is
1268 only needed for intraprocedural analysis. */
1271 compute_complex_assign_jump_func (struct func_body_info
*fbi
,
1272 struct ipa_node_params
*info
,
1273 struct ipa_jump_func
*jfunc
,
1274 gimple call
, gimple stmt
, tree name
,
1277 HOST_WIDE_INT offset
, size
, max_size
;
1278 tree op1
, tc_ssa
, base
, ssa
;
1281 op1
= gimple_assign_rhs1 (stmt
);
1283 if (TREE_CODE (op1
) == SSA_NAME
)
1285 if (SSA_NAME_IS_DEFAULT_DEF (op1
))
1286 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (op1
));
1288 index
= load_from_unmodified_param (fbi
, info
->descriptors
,
1289 SSA_NAME_DEF_STMT (op1
));
1294 index
= load_from_unmodified_param (fbi
, info
->descriptors
, stmt
);
1295 tc_ssa
= gimple_assign_lhs (stmt
);
1300 tree op2
= gimple_assign_rhs2 (stmt
);
1304 if (!is_gimple_ip_invariant (op2
)
1305 || (TREE_CODE_CLASS (gimple_expr_code (stmt
)) != tcc_comparison
1306 && !useless_type_conversion_p (TREE_TYPE (name
),
1310 ipa_set_jf_arith_pass_through (jfunc
, index
, op2
,
1311 gimple_assign_rhs_code (stmt
));
1313 else if (gimple_assign_single_p (stmt
))
1315 bool agg_p
= parm_ref_data_pass_through_p (fbi
, index
, call
, tc_ssa
);
1316 bool type_p
= false;
1318 if (param_type
&& POINTER_TYPE_P (param_type
))
1319 type_p
= !detect_type_change_ssa (tc_ssa
, TREE_TYPE (param_type
),
1321 if (type_p
|| jfunc
->type
== IPA_JF_UNKNOWN
)
1322 ipa_set_jf_simple_pass_through (jfunc
, index
, agg_p
, type_p
);
1327 if (TREE_CODE (op1
) != ADDR_EXPR
)
1329 op1
= TREE_OPERAND (op1
, 0);
1330 if (TREE_CODE (TREE_TYPE (op1
)) != RECORD_TYPE
)
1332 base
= get_ref_base_and_extent (op1
, &offset
, &size
, &max_size
);
1333 if (TREE_CODE (base
) != MEM_REF
1334 /* If this is a varying address, punt. */
1336 || max_size
!= size
)
1338 offset
+= mem_ref_offset (base
).to_short_addr () * BITS_PER_UNIT
;
1339 ssa
= TREE_OPERAND (base
, 0);
1340 if (TREE_CODE (ssa
) != SSA_NAME
1341 || !SSA_NAME_IS_DEFAULT_DEF (ssa
)
1345 /* Dynamic types are changed in constructors and destructors. */
1346 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (ssa
));
1347 if (index
>= 0 && param_type
&& POINTER_TYPE_P (param_type
))
1349 bool type_p
= (contains_polymorphic_type_p (TREE_TYPE (param_type
))
1350 && !detect_type_change (op1
, base
, TREE_TYPE (param_type
),
1351 call
, jfunc
, offset
));
1352 if (type_p
|| jfunc
->type
== IPA_JF_UNKNOWN
)
1353 ipa_set_ancestor_jf (jfunc
, offset
,
1354 type_p
? TREE_TYPE (param_type
) : NULL
, index
,
1355 parm_ref_data_pass_through_p (fbi
, index
,
1356 call
, ssa
), type_p
);
1360 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1363 iftmp.1_3 = &obj_2(D)->D.1762;
1365 The base of the MEM_REF must be a default definition SSA NAME of a
1366 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1367 whole MEM_REF expression is returned and the offset calculated from any
1368 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1369 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1372 get_ancestor_addr_info (gimple assign
, tree
*obj_p
, HOST_WIDE_INT
*offset
)
1374 HOST_WIDE_INT size
, max_size
;
1375 tree expr
, parm
, obj
;
1377 if (!gimple_assign_single_p (assign
))
1379 expr
= gimple_assign_rhs1 (assign
);
1381 if (TREE_CODE (expr
) != ADDR_EXPR
)
1383 expr
= TREE_OPERAND (expr
, 0);
1385 expr
= get_ref_base_and_extent (expr
, offset
, &size
, &max_size
);
1387 if (TREE_CODE (expr
) != MEM_REF
1388 /* If this is a varying address, punt. */
1393 parm
= TREE_OPERAND (expr
, 0);
1394 if (TREE_CODE (parm
) != SSA_NAME
1395 || !SSA_NAME_IS_DEFAULT_DEF (parm
)
1396 || TREE_CODE (SSA_NAME_VAR (parm
)) != PARM_DECL
)
1399 *offset
+= mem_ref_offset (expr
).to_short_addr () * BITS_PER_UNIT
;
1405 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1406 statement PHI, try to find out whether NAME is in fact a
1407 multiple-inheritance typecast from a descendant into an ancestor of a formal
1408 parameter and thus can be described by an ancestor jump function and if so,
1409 write the appropriate function into JFUNC.
1411 Essentially we want to match the following pattern:
1419 iftmp.1_3 = &obj_2(D)->D.1762;
1422 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1423 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1427 compute_complex_ancestor_jump_func (struct func_body_info
*fbi
,
1428 struct ipa_node_params
*info
,
1429 struct ipa_jump_func
*jfunc
,
1430 gimple call
, gimple phi
, tree param_type
)
1432 HOST_WIDE_INT offset
;
1433 gimple assign
, cond
;
1434 basic_block phi_bb
, assign_bb
, cond_bb
;
1435 tree tmp
, parm
, expr
, obj
;
1438 if (gimple_phi_num_args (phi
) != 2)
1441 if (integer_zerop (PHI_ARG_DEF (phi
, 1)))
1442 tmp
= PHI_ARG_DEF (phi
, 0);
1443 else if (integer_zerop (PHI_ARG_DEF (phi
, 0)))
1444 tmp
= PHI_ARG_DEF (phi
, 1);
1447 if (TREE_CODE (tmp
) != SSA_NAME
1448 || SSA_NAME_IS_DEFAULT_DEF (tmp
)
1449 || !POINTER_TYPE_P (TREE_TYPE (tmp
))
1450 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp
))) != RECORD_TYPE
)
1453 assign
= SSA_NAME_DEF_STMT (tmp
);
1454 assign_bb
= gimple_bb (assign
);
1455 if (!single_pred_p (assign_bb
))
1457 expr
= get_ancestor_addr_info (assign
, &obj
, &offset
);
1460 parm
= TREE_OPERAND (expr
, 0);
1461 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (parm
));
1465 cond_bb
= single_pred (assign_bb
);
1466 cond
= last_stmt (cond_bb
);
1468 || gimple_code (cond
) != GIMPLE_COND
1469 || gimple_cond_code (cond
) != NE_EXPR
1470 || gimple_cond_lhs (cond
) != parm
1471 || !integer_zerop (gimple_cond_rhs (cond
)))
1474 phi_bb
= gimple_bb (phi
);
1475 for (i
= 0; i
< 2; i
++)
1477 basic_block pred
= EDGE_PRED (phi_bb
, i
)->src
;
1478 if (pred
!= assign_bb
&& pred
!= cond_bb
)
1482 bool type_p
= false;
1483 if (param_type
&& POINTER_TYPE_P (param_type
)
1484 && contains_polymorphic_type_p (TREE_TYPE (param_type
)))
1485 type_p
= !detect_type_change (obj
, expr
, TREE_TYPE (param_type
),
1486 call
, jfunc
, offset
);
1487 if (type_p
|| jfunc
->type
== IPA_JF_UNKNOWN
)
1488 ipa_set_ancestor_jf (jfunc
, offset
, type_p
? TREE_TYPE (param_type
) : NULL
,
1490 parm_ref_data_pass_through_p (fbi
, index
, call
, parm
),
1494 /* Given OP which is passed as an actual argument to a called function,
1495 determine if it is possible to construct a KNOWN_TYPE jump function for it
1496 and if so, create one and store it to JFUNC.
1497 EXPECTED_TYPE represents a type the argument should be in */
1500 compute_known_type_jump_func (tree op
, struct ipa_jump_func
*jfunc
,
1501 gimple call
, tree expected_type
)
1503 HOST_WIDE_INT offset
, size
, max_size
;
1506 if (!flag_devirtualize
1507 || TREE_CODE (op
) != ADDR_EXPR
1508 || !contains_polymorphic_type_p (TREE_TYPE (TREE_TYPE (op
)))
1509 /* Be sure expected_type is polymorphic. */
1511 || !contains_polymorphic_type_p (expected_type
))
1514 op
= TREE_OPERAND (op
, 0);
1515 base
= get_ref_base_and_extent (op
, &offset
, &size
, &max_size
);
1519 || !contains_polymorphic_type_p (TREE_TYPE (base
)))
1522 if (decl_maybe_in_construction_p (base
, TREE_TYPE (base
),
1523 call
, current_function_decl
)
1524 /* Even if the var seems to be in construction by inline call stack,
1525 we may work out the actual type by walking memory writes. */
1526 && (!is_global_var (base
)
1527 && detect_type_change (op
, base
, expected_type
, call
, jfunc
, offset
)))
1530 ipa_set_jf_known_type (jfunc
, offset
, TREE_TYPE (base
),
1534 /* Inspect the given TYPE and return true iff it has the same structure (the
1535 same number of fields of the same types) as a C++ member pointer. If
1536 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1537 corresponding fields there. */
1540 type_like_member_ptr_p (tree type
, tree
*method_ptr
, tree
*delta
)
1544 if (TREE_CODE (type
) != RECORD_TYPE
)
1547 fld
= TYPE_FIELDS (type
);
1548 if (!fld
|| !POINTER_TYPE_P (TREE_TYPE (fld
))
1549 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld
))) != METHOD_TYPE
1550 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
1556 fld
= DECL_CHAIN (fld
);
1557 if (!fld
|| INTEGRAL_TYPE_P (fld
)
1558 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
1563 if (DECL_CHAIN (fld
))
1569 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1570 return the rhs of its defining statement. Otherwise return RHS as it
1574 get_ssa_def_if_simple_copy (tree rhs
)
1576 while (TREE_CODE (rhs
) == SSA_NAME
&& !SSA_NAME_IS_DEFAULT_DEF (rhs
))
1578 gimple def_stmt
= SSA_NAME_DEF_STMT (rhs
);
1580 if (gimple_assign_single_p (def_stmt
))
1581 rhs
= gimple_assign_rhs1 (def_stmt
);
1588 /* Simple linked list, describing known contents of an aggregate beforere
1591 struct ipa_known_agg_contents_list
1593 /* Offset and size of the described part of the aggregate. */
1594 HOST_WIDE_INT offset
, size
;
1595 /* Known constant value or NULL if the contents is known to be unknown. */
1597 /* Pointer to the next structure in the list. */
1598 struct ipa_known_agg_contents_list
*next
;
1601 /* Find the proper place in linked list of ipa_known_agg_contents_list
1602 structures where to put a new one with the given LHS_OFFSET and LHS_SIZE,
1603 unless there is a partial overlap, in which case return NULL, or such
1604 element is already there, in which case set *ALREADY_THERE to true. */
1606 static struct ipa_known_agg_contents_list
**
1607 get_place_in_agg_contents_list (struct ipa_known_agg_contents_list
**list
,
1608 HOST_WIDE_INT lhs_offset
,
1609 HOST_WIDE_INT lhs_size
,
1610 bool *already_there
)
1612 struct ipa_known_agg_contents_list
**p
= list
;
1613 while (*p
&& (*p
)->offset
< lhs_offset
)
1615 if ((*p
)->offset
+ (*p
)->size
> lhs_offset
)
1620 if (*p
&& (*p
)->offset
< lhs_offset
+ lhs_size
)
1622 if ((*p
)->offset
== lhs_offset
&& (*p
)->size
== lhs_size
)
1623 /* We already know this value is subsequently overwritten with
1625 *already_there
= true;
1627 /* Otherwise this is a partial overlap which we cannot
1634 /* Build aggregate jump function from LIST, assuming there are exactly
1635 CONST_COUNT constant entries there and that th offset of the passed argument
1636 is ARG_OFFSET and store it into JFUNC. */
1639 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list
*list
,
1640 int const_count
, HOST_WIDE_INT arg_offset
,
1641 struct ipa_jump_func
*jfunc
)
1643 vec_alloc (jfunc
->agg
.items
, const_count
);
1648 struct ipa_agg_jf_item item
;
1649 item
.offset
= list
->offset
- arg_offset
;
1650 gcc_assert ((item
.offset
% BITS_PER_UNIT
) == 0);
1651 item
.value
= unshare_expr_without_location (list
->constant
);
1652 jfunc
->agg
.items
->quick_push (item
);
1658 /* Traverse statements from CALL backwards, scanning whether an aggregate given
1659 in ARG is filled in with constant values. ARG can either be an aggregate
1660 expression or a pointer to an aggregate. ARG_TYPE is the type of the
1661 aggregate. JFUNC is the jump function into which the constants are
1662 subsequently stored. */
1665 determine_locally_known_aggregate_parts (gimple call
, tree arg
, tree arg_type
,
1666 struct ipa_jump_func
*jfunc
)
1668 struct ipa_known_agg_contents_list
*list
= NULL
;
1669 int item_count
= 0, const_count
= 0;
1670 HOST_WIDE_INT arg_offset
, arg_size
;
1671 gimple_stmt_iterator gsi
;
1673 bool check_ref
, by_ref
;
1676 /* The function operates in three stages. First, we prepare check_ref, r,
1677 arg_base and arg_offset based on what is actually passed as an actual
1680 if (POINTER_TYPE_P (arg_type
))
1683 if (TREE_CODE (arg
) == SSA_NAME
)
1686 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type
))))
1691 type_size
= TYPE_SIZE (TREE_TYPE (arg_type
));
1692 arg_size
= tree_to_uhwi (type_size
);
1693 ao_ref_init_from_ptr_and_size (&r
, arg_base
, NULL_TREE
);
1695 else if (TREE_CODE (arg
) == ADDR_EXPR
)
1697 HOST_WIDE_INT arg_max_size
;
1699 arg
= TREE_OPERAND (arg
, 0);
1700 arg_base
= get_ref_base_and_extent (arg
, &arg_offset
, &arg_size
,
1702 if (arg_max_size
== -1
1703 || arg_max_size
!= arg_size
1706 if (DECL_P (arg_base
))
1709 ao_ref_init (&r
, arg_base
);
1719 HOST_WIDE_INT arg_max_size
;
1721 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg
)));
1725 arg_base
= get_ref_base_and_extent (arg
, &arg_offset
, &arg_size
,
1727 if (arg_max_size
== -1
1728 || arg_max_size
!= arg_size
1732 ao_ref_init (&r
, arg
);
1735 /* Second stage walks back the BB, looks at individual statements and as long
1736 as it is confident of how the statements affect contents of the
1737 aggregates, it builds a sorted linked list of ipa_agg_jf_list structures
1739 gsi
= gsi_for_stmt (call
);
1741 for (; !gsi_end_p (gsi
); gsi_prev (&gsi
))
1743 struct ipa_known_agg_contents_list
*n
, **p
;
1744 gimple stmt
= gsi_stmt (gsi
);
1745 HOST_WIDE_INT lhs_offset
, lhs_size
, lhs_max_size
;
1746 tree lhs
, rhs
, lhs_base
;
1748 if (!stmt_may_clobber_ref_p_1 (stmt
, &r
))
1750 if (!gimple_assign_single_p (stmt
))
1753 lhs
= gimple_assign_lhs (stmt
);
1754 rhs
= gimple_assign_rhs1 (stmt
);
1755 if (!is_gimple_reg_type (TREE_TYPE (rhs
))
1756 || TREE_CODE (lhs
) == BIT_FIELD_REF
1757 || contains_bitfld_component_ref_p (lhs
))
1760 lhs_base
= get_ref_base_and_extent (lhs
, &lhs_offset
, &lhs_size
,
1762 if (lhs_max_size
== -1
1763 || lhs_max_size
!= lhs_size
)
1768 if (TREE_CODE (lhs_base
) != MEM_REF
1769 || TREE_OPERAND (lhs_base
, 0) != arg_base
1770 || !integer_zerop (TREE_OPERAND (lhs_base
, 1)))
1773 else if (lhs_base
!= arg_base
)
1775 if (DECL_P (lhs_base
))
1781 bool already_there
= false;
1782 p
= get_place_in_agg_contents_list (&list
, lhs_offset
, lhs_size
,
1789 rhs
= get_ssa_def_if_simple_copy (rhs
);
1790 n
= XALLOCA (struct ipa_known_agg_contents_list
);
1792 n
->offset
= lhs_offset
;
1793 if (is_gimple_ip_invariant (rhs
))
1799 n
->constant
= NULL_TREE
;
1804 if (const_count
== PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS
)
1805 || item_count
== 2 * PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS
))
1809 /* Third stage just goes over the list and creates an appropriate vector of
1810 ipa_agg_jf_item structures out of it, of sourse only if there are
1811 any known constants to begin with. */
1815 jfunc
->agg
.by_ref
= by_ref
;
1816 build_agg_jump_func_from_list (list
, const_count
, arg_offset
, jfunc
);
1821 ipa_get_callee_param_type (struct cgraph_edge
*e
, int i
)
1824 tree type
= (e
->callee
1825 ? TREE_TYPE (e
->callee
->decl
)
1826 : gimple_call_fntype (e
->call_stmt
));
1827 tree t
= TYPE_ARG_TYPES (type
);
1829 for (n
= 0; n
< i
; n
++)
1836 return TREE_VALUE (t
);
1839 t
= DECL_ARGUMENTS (e
->callee
->decl
);
1840 for (n
= 0; n
< i
; n
++)
1847 return TREE_TYPE (t
);
1851 /* Compute jump function for all arguments of callsite CS and insert the
1852 information in the jump_functions array in the ipa_edge_args corresponding
1853 to this callsite. */
1856 ipa_compute_jump_functions_for_edge (struct func_body_info
*fbi
,
1857 struct cgraph_edge
*cs
)
1859 struct ipa_node_params
*info
= IPA_NODE_REF (cs
->caller
);
1860 struct ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
1861 gimple call
= cs
->call_stmt
;
1862 int n
, arg_num
= gimple_call_num_args (call
);
1864 if (arg_num
== 0 || args
->jump_functions
)
1866 vec_safe_grow_cleared (args
->jump_functions
, arg_num
);
1868 if (gimple_call_internal_p (call
))
1870 if (ipa_func_spec_opts_forbid_analysis_p (cs
->caller
))
1873 for (n
= 0; n
< arg_num
; n
++)
1875 struct ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (args
, n
);
1876 tree arg
= gimple_call_arg (call
, n
);
1877 tree param_type
= ipa_get_callee_param_type (cs
, n
);
1879 if (is_gimple_ip_invariant (arg
))
1880 ipa_set_jf_constant (jfunc
, arg
, cs
);
1881 else if (!is_gimple_reg_type (TREE_TYPE (arg
))
1882 && TREE_CODE (arg
) == PARM_DECL
)
1884 int index
= ipa_get_param_decl_index (info
, arg
);
1886 gcc_assert (index
>=0);
1887 /* Aggregate passed by value, check for pass-through, otherwise we
1888 will attempt to fill in aggregate contents later in this
1890 if (parm_preserved_before_stmt_p (fbi
, index
, call
, arg
))
1892 ipa_set_jf_simple_pass_through (jfunc
, index
, false, false);
1896 else if (TREE_CODE (arg
) == SSA_NAME
)
1898 if (SSA_NAME_IS_DEFAULT_DEF (arg
))
1900 int index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (arg
));
1904 agg_p
= parm_ref_data_pass_through_p (fbi
, index
, call
, arg
);
1905 if (param_type
&& POINTER_TYPE_P (param_type
))
1906 type_p
= !detect_type_change_ssa (arg
, TREE_TYPE (param_type
),
1910 if (type_p
|| jfunc
->type
== IPA_JF_UNKNOWN
)
1911 ipa_set_jf_simple_pass_through (jfunc
, index
, agg_p
,
1917 gimple stmt
= SSA_NAME_DEF_STMT (arg
);
1918 if (is_gimple_assign (stmt
))
1919 compute_complex_assign_jump_func (fbi
, info
, jfunc
,
1920 call
, stmt
, arg
, param_type
);
1921 else if (gimple_code (stmt
) == GIMPLE_PHI
)
1922 compute_complex_ancestor_jump_func (fbi
, info
, jfunc
,
1923 call
, stmt
, param_type
);
1927 compute_known_type_jump_func (arg
, jfunc
, call
,
1929 && POINTER_TYPE_P (param_type
)
1930 ? TREE_TYPE (param_type
)
1933 /* If ARG is pointer, we can not use its type to determine the type of aggregate
1934 passed (because type conversions are ignored in gimple). Usually we can
1935 safely get type from function declaration, but in case of K&R prototypes or
1936 variadic functions we can try our luck with type of the pointer passed.
1937 TODO: Since we look for actual initialization of the memory object, we may better
1938 work out the type based on the memory stores we find. */
1940 param_type
= TREE_TYPE (arg
);
1942 if ((jfunc
->type
!= IPA_JF_PASS_THROUGH
1943 || !ipa_get_jf_pass_through_agg_preserved (jfunc
))
1944 && (jfunc
->type
!= IPA_JF_ANCESTOR
1945 || !ipa_get_jf_ancestor_agg_preserved (jfunc
))
1946 && (AGGREGATE_TYPE_P (TREE_TYPE (arg
))
1947 || POINTER_TYPE_P (param_type
)))
1948 determine_locally_known_aggregate_parts (call
, arg
, param_type
, jfunc
);
1952 /* Compute jump functions for all edges - both direct and indirect - outgoing
1956 ipa_compute_jump_functions_for_bb (struct func_body_info
*fbi
, basic_block bb
)
1958 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
1960 struct cgraph_edge
*cs
;
1962 FOR_EACH_VEC_ELT_REVERSE (bi
->cg_edges
, i
, cs
)
1964 struct cgraph_node
*callee
= cs
->callee
;
1968 cgraph_function_or_thunk_node (callee
, NULL
);
1969 /* We do not need to bother analyzing calls to unknown functions
1970 unless they may become known during lto/whopr. */
1971 if (!callee
->definition
&& !flag_lto
)
1974 ipa_compute_jump_functions_for_edge (fbi
, cs
);
1978 /* If STMT looks like a statement loading a value from a member pointer formal
1979 parameter, return that parameter and store the offset of the field to
1980 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
1981 might be clobbered). If USE_DELTA, then we look for a use of the delta
1982 field rather than the pfn. */
1985 ipa_get_stmt_member_ptr_load_param (gimple stmt
, bool use_delta
,
1986 HOST_WIDE_INT
*offset_p
)
1988 tree rhs
, rec
, ref_field
, ref_offset
, fld
, ptr_field
, delta_field
;
1990 if (!gimple_assign_single_p (stmt
))
1993 rhs
= gimple_assign_rhs1 (stmt
);
1994 if (TREE_CODE (rhs
) == COMPONENT_REF
)
1996 ref_field
= TREE_OPERAND (rhs
, 1);
1997 rhs
= TREE_OPERAND (rhs
, 0);
2000 ref_field
= NULL_TREE
;
2001 if (TREE_CODE (rhs
) != MEM_REF
)
2003 rec
= TREE_OPERAND (rhs
, 0);
2004 if (TREE_CODE (rec
) != ADDR_EXPR
)
2006 rec
= TREE_OPERAND (rec
, 0);
2007 if (TREE_CODE (rec
) != PARM_DECL
2008 || !type_like_member_ptr_p (TREE_TYPE (rec
), &ptr_field
, &delta_field
))
2010 ref_offset
= TREE_OPERAND (rhs
, 1);
2017 *offset_p
= int_bit_position (fld
);
2021 if (integer_nonzerop (ref_offset
))
2023 return ref_field
== fld
? rec
: NULL_TREE
;
2026 return tree_int_cst_equal (byte_position (fld
), ref_offset
) ? rec
2030 /* Returns true iff T is an SSA_NAME defined by a statement. */
2033 ipa_is_ssa_with_stmt_def (tree t
)
2035 if (TREE_CODE (t
) == SSA_NAME
2036 && !SSA_NAME_IS_DEFAULT_DEF (t
))
2042 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2043 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2044 indirect call graph edge. */
2046 static struct cgraph_edge
*
2047 ipa_note_param_call (struct cgraph_node
*node
, int param_index
, gimple stmt
)
2049 struct cgraph_edge
*cs
;
2051 cs
= cgraph_edge (node
, stmt
);
2052 cs
->indirect_info
->param_index
= param_index
;
2053 cs
->indirect_info
->agg_contents
= 0;
2054 cs
->indirect_info
->member_ptr
= 0;
2058 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2059 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2060 intermediate information about each formal parameter. Currently it checks
2061 whether the call calls a pointer that is a formal parameter and if so, the
2062 parameter is marked with the called flag and an indirect call graph edge
2063 describing the call is created. This is very simple for ordinary pointers
2064 represented in SSA but not-so-nice when it comes to member pointers. The
2065 ugly part of this function does nothing more than trying to match the
2066 pattern of such a call. An example of such a pattern is the gimple dump
2067 below, the call is on the last line:
2070 f$__delta_5 = f.__delta;
2071 f$__pfn_24 = f.__pfn;
2075 f$__delta_5 = MEM[(struct *)&f];
2076 f$__pfn_24 = MEM[(struct *)&f + 4B];
2078 and a few lines below:
2081 D.2496_3 = (int) f$__pfn_24;
2082 D.2497_4 = D.2496_3 & 1;
2089 D.2500_7 = (unsigned int) f$__delta_5;
2090 D.2501_8 = &S + D.2500_7;
2091 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2092 D.2503_10 = *D.2502_9;
2093 D.2504_12 = f$__pfn_24 + -1;
2094 D.2505_13 = (unsigned int) D.2504_12;
2095 D.2506_14 = D.2503_10 + D.2505_13;
2096 D.2507_15 = *D.2506_14;
2097 iftmp.11_16 = (String:: *) D.2507_15;
2100 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2101 D.2500_19 = (unsigned int) f$__delta_5;
2102 D.2508_20 = &S + D.2500_19;
2103 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2105 Such patterns are results of simple calls to a member pointer:
2107 int doprinting (int (MyString::* f)(int) const)
2109 MyString S ("somestring");
2114 Moreover, the function also looks for called pointers loaded from aggregates
2115 passed by value or reference. */
2118 ipa_analyze_indirect_call_uses (struct func_body_info
*fbi
, gimple call
,
2121 struct ipa_node_params
*info
= fbi
->info
;
2122 HOST_WIDE_INT offset
;
2125 if (SSA_NAME_IS_DEFAULT_DEF (target
))
2127 tree var
= SSA_NAME_VAR (target
);
2128 int index
= ipa_get_param_decl_index (info
, var
);
2130 ipa_note_param_call (fbi
->node
, index
, call
);
2135 gimple def
= SSA_NAME_DEF_STMT (target
);
2136 if (gimple_assign_single_p (def
)
2137 && ipa_load_from_parm_agg_1 (fbi
, info
->descriptors
, def
,
2138 gimple_assign_rhs1 (def
), &index
, &offset
,
2141 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
, call
);
2142 if (cs
->indirect_info
->offset
!= offset
)
2143 cs
->indirect_info
->outer_type
= NULL
;
2144 cs
->indirect_info
->offset
= offset
;
2145 cs
->indirect_info
->agg_contents
= 1;
2146 cs
->indirect_info
->by_ref
= by_ref
;
2150 /* Now we need to try to match the complex pattern of calling a member
2152 if (gimple_code (def
) != GIMPLE_PHI
2153 || gimple_phi_num_args (def
) != 2
2154 || !POINTER_TYPE_P (TREE_TYPE (target
))
2155 || TREE_CODE (TREE_TYPE (TREE_TYPE (target
))) != METHOD_TYPE
)
2158 /* First, we need to check whether one of these is a load from a member
2159 pointer that is a parameter to this function. */
2160 tree n1
= PHI_ARG_DEF (def
, 0);
2161 tree n2
= PHI_ARG_DEF (def
, 1);
2162 if (!ipa_is_ssa_with_stmt_def (n1
) || !ipa_is_ssa_with_stmt_def (n2
))
2164 gimple d1
= SSA_NAME_DEF_STMT (n1
);
2165 gimple d2
= SSA_NAME_DEF_STMT (n2
);
2168 basic_block bb
, virt_bb
;
2169 basic_block join
= gimple_bb (def
);
2170 if ((rec
= ipa_get_stmt_member_ptr_load_param (d1
, false, &offset
)))
2172 if (ipa_get_stmt_member_ptr_load_param (d2
, false, NULL
))
2175 bb
= EDGE_PRED (join
, 0)->src
;
2176 virt_bb
= gimple_bb (d2
);
2178 else if ((rec
= ipa_get_stmt_member_ptr_load_param (d2
, false, &offset
)))
2180 bb
= EDGE_PRED (join
, 1)->src
;
2181 virt_bb
= gimple_bb (d1
);
2186 /* Second, we need to check that the basic blocks are laid out in the way
2187 corresponding to the pattern. */
2189 if (!single_pred_p (virt_bb
) || !single_succ_p (virt_bb
)
2190 || single_pred (virt_bb
) != bb
2191 || single_succ (virt_bb
) != join
)
2194 /* Third, let's see that the branching is done depending on the least
2195 significant bit of the pfn. */
2197 gimple branch
= last_stmt (bb
);
2198 if (!branch
|| gimple_code (branch
) != GIMPLE_COND
)
2201 if ((gimple_cond_code (branch
) != NE_EXPR
2202 && gimple_cond_code (branch
) != EQ_EXPR
)
2203 || !integer_zerop (gimple_cond_rhs (branch
)))
2206 tree cond
= gimple_cond_lhs (branch
);
2207 if (!ipa_is_ssa_with_stmt_def (cond
))
2210 def
= SSA_NAME_DEF_STMT (cond
);
2211 if (!is_gimple_assign (def
)
2212 || gimple_assign_rhs_code (def
) != BIT_AND_EXPR
2213 || !integer_onep (gimple_assign_rhs2 (def
)))
2216 cond
= gimple_assign_rhs1 (def
);
2217 if (!ipa_is_ssa_with_stmt_def (cond
))
2220 def
= SSA_NAME_DEF_STMT (cond
);
2222 if (is_gimple_assign (def
)
2223 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def
)))
2225 cond
= gimple_assign_rhs1 (def
);
2226 if (!ipa_is_ssa_with_stmt_def (cond
))
2228 def
= SSA_NAME_DEF_STMT (cond
);
2232 rec2
= ipa_get_stmt_member_ptr_load_param (def
,
2233 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2234 == ptrmemfunc_vbit_in_delta
),
2239 index
= ipa_get_param_decl_index (info
, rec
);
2241 && parm_preserved_before_stmt_p (fbi
, index
, call
, rec
))
2243 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
, call
);
2244 if (cs
->indirect_info
->offset
!= offset
)
2245 cs
->indirect_info
->outer_type
= NULL
;
2246 cs
->indirect_info
->offset
= offset
;
2247 cs
->indirect_info
->agg_contents
= 1;
2248 cs
->indirect_info
->member_ptr
= 1;
2254 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2255 object referenced in the expression is a formal parameter of the caller
2256 FBI->node (described by FBI->info), create a call note for the
2260 ipa_analyze_virtual_call_uses (struct func_body_info
*fbi
,
2261 gimple call
, tree target
)
2263 tree obj
= OBJ_TYPE_REF_OBJECT (target
);
2265 HOST_WIDE_INT anc_offset
;
2267 if (!flag_devirtualize
)
2270 if (TREE_CODE (obj
) != SSA_NAME
)
2273 struct ipa_node_params
*info
= fbi
->info
;
2274 if (SSA_NAME_IS_DEFAULT_DEF (obj
))
2276 struct ipa_jump_func jfunc
;
2277 if (TREE_CODE (SSA_NAME_VAR (obj
)) != PARM_DECL
)
2281 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (obj
));
2282 gcc_assert (index
>= 0);
2283 if (detect_type_change_ssa (obj
, obj_type_ref_class (target
),
2289 struct ipa_jump_func jfunc
;
2290 gimple stmt
= SSA_NAME_DEF_STMT (obj
);
2293 expr
= get_ancestor_addr_info (stmt
, &obj
, &anc_offset
);
2296 index
= ipa_get_param_decl_index (info
,
2297 SSA_NAME_VAR (TREE_OPERAND (expr
, 0)));
2298 gcc_assert (index
>= 0);
2299 if (detect_type_change (obj
, expr
, obj_type_ref_class (target
),
2300 call
, &jfunc
, anc_offset
))
2304 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
, call
);
2305 struct cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
2306 ii
->offset
= anc_offset
;
2307 ii
->otr_token
= tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target
));
2308 ii
->otr_type
= obj_type_ref_class (target
);
2309 ii
->polymorphic
= 1;
2312 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2313 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2314 containing intermediate information about each formal parameter. */
2317 ipa_analyze_call_uses (struct func_body_info
*fbi
, gimple call
)
2319 tree target
= gimple_call_fn (call
);
2322 || (TREE_CODE (target
) != SSA_NAME
2323 && !virtual_method_call_p (target
)))
2326 /* If we previously turned the call into a direct call, there is
2327 no need to analyze. */
2328 struct cgraph_edge
*cs
= cgraph_edge (fbi
->node
, call
);
2329 if (cs
&& !cs
->indirect_unknown_callee
)
2331 if (TREE_CODE (target
) == SSA_NAME
)
2332 ipa_analyze_indirect_call_uses (fbi
, call
, target
);
2333 else if (virtual_method_call_p (target
))
2334 ipa_analyze_virtual_call_uses (fbi
, call
, target
);
2338 /* Analyze the call statement STMT with respect to formal parameters (described
2339 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2340 formal parameters are called. */
2343 ipa_analyze_stmt_uses (struct func_body_info
*fbi
, gimple stmt
)
2345 if (is_gimple_call (stmt
))
2346 ipa_analyze_call_uses (fbi
, stmt
);
2349 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2350 If OP is a parameter declaration, mark it as used in the info structure
2354 visit_ref_for_mod_analysis (gimple
, tree op
, tree
, void *data
)
2356 struct ipa_node_params
*info
= (struct ipa_node_params
*) data
;
2358 op
= get_base_address (op
);
2360 && TREE_CODE (op
) == PARM_DECL
)
2362 int index
= ipa_get_param_decl_index (info
, op
);
2363 gcc_assert (index
>= 0);
2364 ipa_set_param_used (info
, index
, true);
2370 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2371 the findings in various structures of the associated ipa_node_params
2372 structure, such as parameter flags, notes etc. FBI holds various data about
2373 the function being analyzed. */
2376 ipa_analyze_params_uses_in_bb (struct func_body_info
*fbi
, basic_block bb
)
2378 gimple_stmt_iterator gsi
;
2379 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2381 gimple stmt
= gsi_stmt (gsi
);
2383 if (is_gimple_debug (stmt
))
2386 ipa_analyze_stmt_uses (fbi
, stmt
);
2387 walk_stmt_load_store_addr_ops (stmt
, fbi
->info
,
2388 visit_ref_for_mod_analysis
,
2389 visit_ref_for_mod_analysis
,
2390 visit_ref_for_mod_analysis
);
2392 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2393 walk_stmt_load_store_addr_ops (gsi_stmt (gsi
), fbi
->info
,
2394 visit_ref_for_mod_analysis
,
2395 visit_ref_for_mod_analysis
,
2396 visit_ref_for_mod_analysis
);
2399 /* Calculate controlled uses of parameters of NODE. */
2402 ipa_analyze_controlled_uses (struct cgraph_node
*node
)
2404 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
2406 for (int i
= 0; i
< ipa_get_param_count (info
); i
++)
2408 tree parm
= ipa_get_param (info
, i
);
2409 int controlled_uses
= 0;
2411 /* For SSA regs see if parameter is used. For non-SSA we compute
2412 the flag during modification analysis. */
2413 if (is_gimple_reg (parm
))
2415 tree ddef
= ssa_default_def (DECL_STRUCT_FUNCTION (node
->decl
),
2417 if (ddef
&& !has_zero_uses (ddef
))
2419 imm_use_iterator imm_iter
;
2420 use_operand_p use_p
;
2422 ipa_set_param_used (info
, i
, true);
2423 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, ddef
)
2424 if (!is_gimple_call (USE_STMT (use_p
)))
2426 if (!is_gimple_debug (USE_STMT (use_p
)))
2428 controlled_uses
= IPA_UNDESCRIBED_USE
;
2436 controlled_uses
= 0;
2439 controlled_uses
= IPA_UNDESCRIBED_USE
;
2440 ipa_set_controlled_uses (info
, i
, controlled_uses
);
2444 /* Free stuff in BI. */
2447 free_ipa_bb_info (struct ipa_bb_info
*bi
)
2449 bi
->cg_edges
.release ();
2450 bi
->param_aa_statuses
.release ();
2453 /* Dominator walker driving the analysis. */
2455 class analysis_dom_walker
: public dom_walker
2458 analysis_dom_walker (struct func_body_info
*fbi
)
2459 : dom_walker (CDI_DOMINATORS
), m_fbi (fbi
) {}
2461 virtual void before_dom_children (basic_block
);
2464 struct func_body_info
*m_fbi
;
2468 analysis_dom_walker::before_dom_children (basic_block bb
)
2470 ipa_analyze_params_uses_in_bb (m_fbi
, bb
);
2471 ipa_compute_jump_functions_for_bb (m_fbi
, bb
);
2474 /* Initialize the array describing properties of of formal parameters
2475 of NODE, analyze their uses and compute jump functions associated
2476 with actual arguments of calls from within NODE. */
2479 ipa_analyze_node (struct cgraph_node
*node
)
2481 struct func_body_info fbi
;
2482 struct ipa_node_params
*info
;
2484 ipa_check_create_node_params ();
2485 ipa_check_create_edge_args ();
2486 info
= IPA_NODE_REF (node
);
2488 if (info
->analysis_done
)
2490 info
->analysis_done
= 1;
2492 if (ipa_func_spec_opts_forbid_analysis_p (node
))
2494 for (int i
= 0; i
< ipa_get_param_count (info
); i
++)
2496 ipa_set_param_used (info
, i
, true);
2497 ipa_set_controlled_uses (info
, i
, IPA_UNDESCRIBED_USE
);
2502 struct function
*func
= DECL_STRUCT_FUNCTION (node
->decl
);
2504 calculate_dominance_info (CDI_DOMINATORS
);
2505 ipa_initialize_node_params (node
);
2506 ipa_analyze_controlled_uses (node
);
2509 fbi
.info
= IPA_NODE_REF (node
);
2510 fbi
.bb_infos
= vNULL
;
2511 fbi
.bb_infos
.safe_grow_cleared (last_basic_block_for_fn (cfun
));
2512 fbi
.param_count
= ipa_get_param_count (info
);
2515 for (struct cgraph_edge
*cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
2517 ipa_bb_info
*bi
= ipa_get_bb_info (&fbi
, gimple_bb (cs
->call_stmt
));
2518 bi
->cg_edges
.safe_push (cs
);
2521 for (struct cgraph_edge
*cs
= node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
2523 ipa_bb_info
*bi
= ipa_get_bb_info (&fbi
, gimple_bb (cs
->call_stmt
));
2524 bi
->cg_edges
.safe_push (cs
);
2527 analysis_dom_walker (&fbi
).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
2530 struct ipa_bb_info
*bi
;
2531 FOR_EACH_VEC_ELT (fbi
.bb_infos
, i
, bi
)
2532 free_ipa_bb_info (bi
);
2533 fbi
.bb_infos
.release ();
2534 free_dominance_info (CDI_DOMINATORS
);
2538 /* Given a statement CALL which must be a GIMPLE_CALL calling an OBJ_TYPE_REF
2539 attempt a type-based devirtualization. If successful, return the
2540 target function declaration, otherwise return NULL. */
2543 ipa_intraprocedural_devirtualization (gimple call
)
2545 tree binfo
, token
, fndecl
;
2546 struct ipa_jump_func jfunc
;
2547 tree otr
= gimple_call_fn (call
);
2549 jfunc
.type
= IPA_JF_UNKNOWN
;
2550 compute_known_type_jump_func (OBJ_TYPE_REF_OBJECT (otr
), &jfunc
,
2551 call
, obj_type_ref_class (otr
));
2552 if (jfunc
.type
!= IPA_JF_KNOWN_TYPE
)
2554 binfo
= ipa_binfo_from_known_type_jfunc (&jfunc
);
2557 token
= OBJ_TYPE_REF_TOKEN (otr
);
2558 fndecl
= gimple_get_virt_method_for_binfo (tree_to_uhwi (token
),
2560 #ifdef ENABLE_CHECKING
2562 gcc_assert (possible_polymorphic_call_target_p
2563 (otr
, cgraph_get_node (fndecl
)));
2568 /* Update the jump function DST when the call graph edge corresponding to SRC is
2569 is being inlined, knowing that DST is of type ancestor and src of known
2573 combine_known_type_and_ancestor_jfs (struct ipa_jump_func
*src
,
2574 struct ipa_jump_func
*dst
)
2576 HOST_WIDE_INT combined_offset
;
2579 if (!ipa_get_jf_ancestor_type_preserved (dst
))
2581 dst
->type
= IPA_JF_UNKNOWN
;
2585 combined_offset
= ipa_get_jf_known_type_offset (src
)
2586 + ipa_get_jf_ancestor_offset (dst
);
2587 combined_type
= ipa_get_jf_ancestor_type (dst
);
2589 ipa_set_jf_known_type (dst
, combined_offset
,
2590 ipa_get_jf_known_type_base_type (src
),
2594 /* Update the jump functions associated with call graph edge E when the call
2595 graph edge CS is being inlined, assuming that E->caller is already (possibly
2596 indirectly) inlined into CS->callee and that E has not been inlined. */
2599 update_jump_functions_after_inlining (struct cgraph_edge
*cs
,
2600 struct cgraph_edge
*e
)
2602 struct ipa_edge_args
*top
= IPA_EDGE_REF (cs
);
2603 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
2604 int count
= ipa_get_cs_argument_count (args
);
2607 for (i
= 0; i
< count
; i
++)
2609 struct ipa_jump_func
*dst
= ipa_get_ith_jump_func (args
, i
);
2611 if (dst
->type
== IPA_JF_ANCESTOR
)
2613 struct ipa_jump_func
*src
;
2614 int dst_fid
= dst
->value
.ancestor
.formal_id
;
2616 /* Variable number of arguments can cause havoc if we try to access
2617 one that does not exist in the inlined edge. So make sure we
2619 if (dst_fid
>= ipa_get_cs_argument_count (top
))
2621 dst
->type
= IPA_JF_UNKNOWN
;
2625 src
= ipa_get_ith_jump_func (top
, dst_fid
);
2628 && (dst
->value
.ancestor
.agg_preserved
|| !src
->agg
.by_ref
))
2630 struct ipa_agg_jf_item
*item
;
2633 /* Currently we do not produce clobber aggregate jump functions,
2634 replace with merging when we do. */
2635 gcc_assert (!dst
->agg
.items
);
2637 dst
->agg
.items
= vec_safe_copy (src
->agg
.items
);
2638 dst
->agg
.by_ref
= src
->agg
.by_ref
;
2639 FOR_EACH_VEC_SAFE_ELT (dst
->agg
.items
, j
, item
)
2640 item
->offset
-= dst
->value
.ancestor
.offset
;
2643 if (src
->type
== IPA_JF_KNOWN_TYPE
)
2644 combine_known_type_and_ancestor_jfs (src
, dst
);
2645 else if (src
->type
== IPA_JF_PASS_THROUGH
2646 && src
->value
.pass_through
.operation
== NOP_EXPR
)
2648 dst
->value
.ancestor
.formal_id
= src
->value
.pass_through
.formal_id
;
2649 dst
->value
.ancestor
.agg_preserved
&=
2650 src
->value
.pass_through
.agg_preserved
;
2651 dst
->value
.ancestor
.type_preserved
&=
2652 src
->value
.pass_through
.type_preserved
;
2654 else if (src
->type
== IPA_JF_ANCESTOR
)
2656 dst
->value
.ancestor
.formal_id
= src
->value
.ancestor
.formal_id
;
2657 dst
->value
.ancestor
.offset
+= src
->value
.ancestor
.offset
;
2658 dst
->value
.ancestor
.agg_preserved
&=
2659 src
->value
.ancestor
.agg_preserved
;
2660 dst
->value
.ancestor
.type_preserved
&=
2661 src
->value
.ancestor
.type_preserved
;
2664 dst
->type
= IPA_JF_UNKNOWN
;
2666 else if (dst
->type
== IPA_JF_PASS_THROUGH
)
2668 struct ipa_jump_func
*src
;
2669 /* We must check range due to calls with variable number of arguments
2670 and we cannot combine jump functions with operations. */
2671 if (dst
->value
.pass_through
.operation
== NOP_EXPR
2672 && (dst
->value
.pass_through
.formal_id
2673 < ipa_get_cs_argument_count (top
)))
2675 int dst_fid
= dst
->value
.pass_through
.formal_id
;
2676 src
= ipa_get_ith_jump_func (top
, dst_fid
);
2677 bool dst_agg_p
= ipa_get_jf_pass_through_agg_preserved (dst
);
2681 case IPA_JF_UNKNOWN
:
2682 dst
->type
= IPA_JF_UNKNOWN
;
2684 case IPA_JF_KNOWN_TYPE
:
2685 if (ipa_get_jf_pass_through_type_preserved (dst
))
2686 ipa_set_jf_known_type (dst
,
2687 ipa_get_jf_known_type_offset (src
),
2688 ipa_get_jf_known_type_base_type (src
),
2689 ipa_get_jf_known_type_component_type (src
));
2691 dst
->type
= IPA_JF_UNKNOWN
;
2694 ipa_set_jf_cst_copy (dst
, src
);
2697 case IPA_JF_PASS_THROUGH
:
2699 int formal_id
= ipa_get_jf_pass_through_formal_id (src
);
2700 enum tree_code operation
;
2701 operation
= ipa_get_jf_pass_through_operation (src
);
2703 if (operation
== NOP_EXPR
)
2707 && ipa_get_jf_pass_through_agg_preserved (src
);
2708 type_p
= ipa_get_jf_pass_through_type_preserved (src
)
2709 && ipa_get_jf_pass_through_type_preserved (dst
);
2710 ipa_set_jf_simple_pass_through (dst
, formal_id
,
2715 tree operand
= ipa_get_jf_pass_through_operand (src
);
2716 ipa_set_jf_arith_pass_through (dst
, formal_id
, operand
,
2721 case IPA_JF_ANCESTOR
:
2725 && ipa_get_jf_ancestor_agg_preserved (src
);
2726 type_p
= ipa_get_jf_ancestor_type_preserved (src
)
2727 && ipa_get_jf_pass_through_type_preserved (dst
);
2728 ipa_set_ancestor_jf (dst
,
2729 ipa_get_jf_ancestor_offset (src
),
2730 ipa_get_jf_ancestor_type (src
),
2731 ipa_get_jf_ancestor_formal_id (src
),
2740 && (dst_agg_p
|| !src
->agg
.by_ref
))
2742 /* Currently we do not produce clobber aggregate jump
2743 functions, replace with merging when we do. */
2744 gcc_assert (!dst
->agg
.items
);
2746 dst
->agg
.by_ref
= src
->agg
.by_ref
;
2747 dst
->agg
.items
= vec_safe_copy (src
->agg
.items
);
2751 dst
->type
= IPA_JF_UNKNOWN
;
2756 /* If TARGET is an addr_expr of a function declaration, make it the destination
2757 of an indirect edge IE and return the edge. Otherwise, return NULL. */
2759 struct cgraph_edge
*
2760 ipa_make_edge_direct_to_target (struct cgraph_edge
*ie
, tree target
)
2762 struct cgraph_node
*callee
;
2763 struct inline_edge_summary
*es
= inline_edge_summary (ie
);
2764 bool unreachable
= false;
2766 if (TREE_CODE (target
) == ADDR_EXPR
)
2767 target
= TREE_OPERAND (target
, 0);
2768 if (TREE_CODE (target
) != FUNCTION_DECL
)
2770 target
= canonicalize_constructor_val (target
, NULL
);
2771 if (!target
|| TREE_CODE (target
) != FUNCTION_DECL
)
2773 if (ie
->indirect_info
->member_ptr
)
2774 /* Member pointer call that goes through a VMT lookup. */
2777 if (dump_enabled_p ())
2779 location_t loc
= gimple_location_safe (ie
->call_stmt
);
2780 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, loc
,
2781 "discovered direct call to non-function in %s/%i, "
2782 "making it __builtin_unreachable\n",
2783 ie
->caller
->name (), ie
->caller
->order
);
2786 target
= builtin_decl_implicit (BUILT_IN_UNREACHABLE
);
2787 callee
= cgraph_get_create_node (target
);
2791 callee
= cgraph_get_node (target
);
2794 callee
= cgraph_get_node (target
);
2796 /* Because may-edges are not explicitely represented and vtable may be external,
2797 we may create the first reference to the object in the unit. */
2798 if (!callee
|| callee
->global
.inlined_to
)
2801 /* We are better to ensure we can refer to it.
2802 In the case of static functions we are out of luck, since we already
2803 removed its body. In the case of public functions we may or may
2804 not introduce the reference. */
2805 if (!canonicalize_constructor_val (target
, NULL
)
2806 || !TREE_PUBLIC (target
))
2809 fprintf (dump_file
, "ipa-prop: Discovered call to a known target "
2810 "(%s/%i -> %s/%i) but can not refer to it. Giving up.\n",
2811 xstrdup (ie
->caller
->name ()),
2813 xstrdup (ie
->callee
->name ()),
2817 callee
= cgraph_get_create_node (target
);
2820 if (!dbg_cnt (devirt
))
2823 ipa_check_create_node_params ();
2825 /* We can not make edges to inline clones. It is bug that someone removed
2826 the cgraph node too early. */
2827 gcc_assert (!callee
->global
.inlined_to
);
2829 if (dump_file
&& !unreachable
)
2831 fprintf (dump_file
, "ipa-prop: Discovered %s call to a known target "
2832 "(%s/%i -> %s/%i), for stmt ",
2833 ie
->indirect_info
->polymorphic
? "a virtual" : "an indirect",
2834 xstrdup (ie
->caller
->name ()),
2836 xstrdup (callee
->name ()),
2839 print_gimple_stmt (dump_file
, ie
->call_stmt
, 2, TDF_SLIM
);
2841 fprintf (dump_file
, "with uid %i\n", ie
->lto_stmt_uid
);
2843 if (dump_enabled_p ())
2845 location_t loc
= gimple_location_safe (ie
->call_stmt
);
2847 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, loc
,
2848 "converting indirect call in %s to direct call to %s\n",
2849 ie
->caller
->name (), callee
->name ());
2851 ie
= cgraph_make_edge_direct (ie
, callee
);
2852 es
= inline_edge_summary (ie
);
2853 es
->call_stmt_size
-= (eni_size_weights
.indirect_call_cost
2854 - eni_size_weights
.call_cost
);
2855 es
->call_stmt_time
-= (eni_time_weights
.indirect_call_cost
2856 - eni_time_weights
.call_cost
);
2861 /* Retrieve value from aggregate jump function AGG for the given OFFSET or
2862 return NULL if there is not any. BY_REF specifies whether the value has to
2863 be passed by reference or by value. */
2866 ipa_find_agg_cst_for_param (struct ipa_agg_jump_function
*agg
,
2867 HOST_WIDE_INT offset
, bool by_ref
)
2869 struct ipa_agg_jf_item
*item
;
2872 if (by_ref
!= agg
->by_ref
)
2875 FOR_EACH_VEC_SAFE_ELT (agg
->items
, i
, item
)
2876 if (item
->offset
== offset
)
2878 /* Currently we do not have clobber values, return NULL for them once
2880 gcc_checking_assert (is_gimple_ip_invariant (item
->value
));
2886 /* Remove a reference to SYMBOL from the list of references of a node given by
2887 reference description RDESC. Return true if the reference has been
2888 successfully found and removed. */
2891 remove_described_reference (symtab_node
*symbol
, struct ipa_cst_ref_desc
*rdesc
)
2893 struct ipa_ref
*to_del
;
2894 struct cgraph_edge
*origin
;
2899 to_del
= origin
->caller
->find_reference (symbol
, origin
->call_stmt
,
2900 origin
->lto_stmt_uid
);
2904 to_del
->remove_reference ();
2906 fprintf (dump_file
, "ipa-prop: Removed a reference from %s/%i to %s.\n",
2907 xstrdup (origin
->caller
->name ()),
2908 origin
->caller
->order
, xstrdup (symbol
->name ()));
2912 /* If JFUNC has a reference description with refcount different from
2913 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
2914 NULL. JFUNC must be a constant jump function. */
2916 static struct ipa_cst_ref_desc
*
2917 jfunc_rdesc_usable (struct ipa_jump_func
*jfunc
)
2919 struct ipa_cst_ref_desc
*rdesc
= ipa_get_jf_constant_rdesc (jfunc
);
2920 if (rdesc
&& rdesc
->refcount
!= IPA_UNDESCRIBED_USE
)
2926 /* If the value of constant jump function JFUNC is an address of a function
2927 declaration, return the associated call graph node. Otherwise return
2930 static cgraph_node
*
2931 cgraph_node_for_jfunc (struct ipa_jump_func
*jfunc
)
2933 gcc_checking_assert (jfunc
->type
== IPA_JF_CONST
);
2934 tree cst
= ipa_get_jf_constant (jfunc
);
2935 if (TREE_CODE (cst
) != ADDR_EXPR
2936 || TREE_CODE (TREE_OPERAND (cst
, 0)) != FUNCTION_DECL
)
2939 return cgraph_get_node (TREE_OPERAND (cst
, 0));
2943 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
2944 refcount and if it hits zero, remove reference to SYMBOL from the caller of
2945 the edge specified in the rdesc. Return false if either the symbol or the
2946 reference could not be found, otherwise return true. */
2949 try_decrement_rdesc_refcount (struct ipa_jump_func
*jfunc
)
2951 struct ipa_cst_ref_desc
*rdesc
;
2952 if (jfunc
->type
== IPA_JF_CONST
2953 && (rdesc
= jfunc_rdesc_usable (jfunc
))
2954 && --rdesc
->refcount
== 0)
2956 symtab_node
*symbol
= cgraph_node_for_jfunc (jfunc
);
2960 return remove_described_reference (symbol
, rdesc
);
2965 /* Try to find a destination for indirect edge IE that corresponds to a simple
2966 call or a call of a member function pointer and where the destination is a
2967 pointer formal parameter described by jump function JFUNC. If it can be
2968 determined, return the newly direct edge, otherwise return NULL.
2969 NEW_ROOT_INFO is the node info that JFUNC lattices are relative to. */
2971 static struct cgraph_edge
*
2972 try_make_edge_direct_simple_call (struct cgraph_edge
*ie
,
2973 struct ipa_jump_func
*jfunc
,
2974 struct ipa_node_params
*new_root_info
)
2976 struct cgraph_edge
*cs
;
2978 bool agg_contents
= ie
->indirect_info
->agg_contents
;
2980 if (ie
->indirect_info
->agg_contents
)
2981 target
= ipa_find_agg_cst_for_param (&jfunc
->agg
,
2982 ie
->indirect_info
->offset
,
2983 ie
->indirect_info
->by_ref
);
2985 target
= ipa_value_from_jfunc (new_root_info
, jfunc
);
2988 cs
= ipa_make_edge_direct_to_target (ie
, target
);
2990 if (cs
&& !agg_contents
)
2993 gcc_checking_assert (cs
->callee
2995 || jfunc
->type
!= IPA_JF_CONST
2996 || !cgraph_node_for_jfunc (jfunc
)
2997 || cs
->callee
== cgraph_node_for_jfunc (jfunc
)));
2998 ok
= try_decrement_rdesc_refcount (jfunc
);
2999 gcc_checking_assert (ok
);
3005 /* Return the target to be used in cases of impossible devirtualization. IE
3006 and target (the latter can be NULL) are dumped when dumping is enabled. */
3009 ipa_impossible_devirt_target (struct cgraph_edge
*ie
, tree target
)
3015 "Type inconsistent devirtualization: %s/%i->%s\n",
3016 ie
->caller
->name (), ie
->caller
->order
,
3017 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target
)));
3020 "No devirtualization target in %s/%i\n",
3021 ie
->caller
->name (), ie
->caller
->order
);
3023 tree new_target
= builtin_decl_implicit (BUILT_IN_UNREACHABLE
);
3024 cgraph_get_create_node (new_target
);
3028 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3029 call based on a formal parameter which is described by jump function JFUNC
3030 and if it can be determined, make it direct and return the direct edge.
3031 Otherwise, return NULL. NEW_ROOT_INFO is the node info that JFUNC lattices
3034 static struct cgraph_edge
*
3035 try_make_edge_direct_virtual_call (struct cgraph_edge
*ie
,
3036 struct ipa_jump_func
*jfunc
,
3037 struct ipa_node_params
*new_root_info
)
3041 if (!flag_devirtualize
)
3044 /* First try to do lookup via known virtual table pointer value. */
3045 if (!ie
->indirect_info
->by_ref
)
3048 unsigned HOST_WIDE_INT offset
;
3049 tree t
= ipa_find_agg_cst_for_param (&jfunc
->agg
,
3050 ie
->indirect_info
->offset
,
3052 if (t
&& vtable_pointer_value_to_vtable (t
, &vtable
, &offset
))
3054 target
= gimple_get_virt_method_for_vtable (ie
->indirect_info
->otr_token
,
3058 if ((TREE_CODE (TREE_TYPE (target
)) == FUNCTION_TYPE
3059 && DECL_FUNCTION_CODE (target
) == BUILT_IN_UNREACHABLE
)
3060 || !possible_polymorphic_call_target_p
3061 (ie
, cgraph_get_node (target
)))
3062 target
= ipa_impossible_devirt_target (ie
, target
);
3063 return ipa_make_edge_direct_to_target (ie
, target
);
3068 binfo
= ipa_value_from_jfunc (new_root_info
, jfunc
);
3073 if (TREE_CODE (binfo
) != TREE_BINFO
)
3075 ipa_polymorphic_call_context context
;
3076 vec
<cgraph_node
*>targets
;
3079 if (!get_polymorphic_call_info_from_invariant
3080 (&context
, binfo
, ie
->indirect_info
->otr_type
,
3081 ie
->indirect_info
->offset
))
3083 targets
= possible_polymorphic_call_targets
3084 (ie
->indirect_info
->otr_type
,
3085 ie
->indirect_info
->otr_token
,
3087 if (!final
|| targets
.length () > 1)
3089 if (targets
.length () == 1)
3090 target
= targets
[0]->decl
;
3092 target
= ipa_impossible_devirt_target (ie
, NULL_TREE
);
3096 binfo
= get_binfo_at_offset (binfo
, ie
->indirect_info
->offset
,
3097 ie
->indirect_info
->otr_type
);
3099 target
= gimple_get_virt_method_for_binfo (ie
->indirect_info
->otr_token
,
3107 if (!possible_polymorphic_call_target_p (ie
, cgraph_get_node (target
)))
3108 target
= ipa_impossible_devirt_target (ie
, target
);
3109 return ipa_make_edge_direct_to_target (ie
, target
);
3115 /* Update the param called notes associated with NODE when CS is being inlined,
3116 assuming NODE is (potentially indirectly) inlined into CS->callee.
3117 Moreover, if the callee is discovered to be constant, create a new cgraph
3118 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
3119 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
3122 update_indirect_edges_after_inlining (struct cgraph_edge
*cs
,
3123 struct cgraph_node
*node
,
3124 vec
<cgraph_edge_p
> *new_edges
)
3126 struct ipa_edge_args
*top
;
3127 struct cgraph_edge
*ie
, *next_ie
, *new_direct_edge
;
3128 struct ipa_node_params
*new_root_info
;
3131 ipa_check_create_edge_args ();
3132 top
= IPA_EDGE_REF (cs
);
3133 new_root_info
= IPA_NODE_REF (cs
->caller
->global
.inlined_to
3134 ? cs
->caller
->global
.inlined_to
3137 for (ie
= node
->indirect_calls
; ie
; ie
= next_ie
)
3139 struct cgraph_indirect_call_info
*ici
= ie
->indirect_info
;
3140 struct ipa_jump_func
*jfunc
;
3143 next_ie
= ie
->next_callee
;
3145 if (ici
->param_index
== -1)
3148 /* We must check range due to calls with variable number of arguments: */
3149 if (ici
->param_index
>= ipa_get_cs_argument_count (top
))
3151 ici
->param_index
= -1;
3155 param_index
= ici
->param_index
;
3156 jfunc
= ipa_get_ith_jump_func (top
, param_index
);
3158 if (!flag_indirect_inlining
)
3159 new_direct_edge
= NULL
;
3160 else if (ici
->polymorphic
)
3161 new_direct_edge
= try_make_edge_direct_virtual_call (ie
, jfunc
,
3164 new_direct_edge
= try_make_edge_direct_simple_call (ie
, jfunc
,
3166 /* If speculation was removed, then we need to do nothing. */
3167 if (new_direct_edge
&& new_direct_edge
!= ie
)
3169 new_direct_edge
->indirect_inlining_edge
= 1;
3170 top
= IPA_EDGE_REF (cs
);
3173 else if (new_direct_edge
)
3175 new_direct_edge
->indirect_inlining_edge
= 1;
3176 if (new_direct_edge
->call_stmt
)
3177 new_direct_edge
->call_stmt_cannot_inline_p
3178 = !gimple_check_call_matching_types (
3179 new_direct_edge
->call_stmt
,
3180 new_direct_edge
->callee
->decl
, false);
3183 new_edges
->safe_push (new_direct_edge
);
3186 top
= IPA_EDGE_REF (cs
);
3188 else if (jfunc
->type
== IPA_JF_PASS_THROUGH
3189 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
3191 if ((ici
->agg_contents
3192 && !ipa_get_jf_pass_through_agg_preserved (jfunc
))
3193 || (ici
->polymorphic
3194 && !ipa_get_jf_pass_through_type_preserved (jfunc
)))
3195 ici
->param_index
= -1;
3197 ici
->param_index
= ipa_get_jf_pass_through_formal_id (jfunc
);
3199 else if (jfunc
->type
== IPA_JF_ANCESTOR
)
3201 if ((ici
->agg_contents
3202 && !ipa_get_jf_ancestor_agg_preserved (jfunc
))
3203 || (ici
->polymorphic
3204 && !ipa_get_jf_ancestor_type_preserved (jfunc
)))
3205 ici
->param_index
= -1;
3208 ici
->param_index
= ipa_get_jf_ancestor_formal_id (jfunc
);
3209 if (ipa_get_jf_ancestor_offset (jfunc
))
3210 ici
->outer_type
= NULL
;
3211 ici
->offset
+= ipa_get_jf_ancestor_offset (jfunc
);
3215 /* Either we can find a destination for this edge now or never. */
3216 ici
->param_index
= -1;
3222 /* Recursively traverse subtree of NODE (including node) made of inlined
3223 cgraph_edges when CS has been inlined and invoke
3224 update_indirect_edges_after_inlining on all nodes and
3225 update_jump_functions_after_inlining on all non-inlined edges that lead out
3226 of this subtree. Newly discovered indirect edges will be added to
3227 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
3231 propagate_info_to_inlined_callees (struct cgraph_edge
*cs
,
3232 struct cgraph_node
*node
,
3233 vec
<cgraph_edge_p
> *new_edges
)
3235 struct cgraph_edge
*e
;
3238 res
= update_indirect_edges_after_inlining (cs
, node
, new_edges
);
3240 for (e
= node
->callees
; e
; e
= e
->next_callee
)
3241 if (!e
->inline_failed
)
3242 res
|= propagate_info_to_inlined_callees (cs
, e
->callee
, new_edges
);
3244 update_jump_functions_after_inlining (cs
, e
);
3245 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
3246 update_jump_functions_after_inlining (cs
, e
);
3251 /* Combine two controlled uses counts as done during inlining. */
3254 combine_controlled_uses_counters (int c
, int d
)
3256 if (c
== IPA_UNDESCRIBED_USE
|| d
== IPA_UNDESCRIBED_USE
)
3257 return IPA_UNDESCRIBED_USE
;
3262 /* Propagate number of controlled users from CS->caleee to the new root of the
3263 tree of inlined nodes. */
3266 propagate_controlled_uses (struct cgraph_edge
*cs
)
3268 struct ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
3269 struct cgraph_node
*new_root
= cs
->caller
->global
.inlined_to
3270 ? cs
->caller
->global
.inlined_to
: cs
->caller
;
3271 struct ipa_node_params
*new_root_info
= IPA_NODE_REF (new_root
);
3272 struct ipa_node_params
*old_root_info
= IPA_NODE_REF (cs
->callee
);
3275 count
= MIN (ipa_get_cs_argument_count (args
),
3276 ipa_get_param_count (old_root_info
));
3277 for (i
= 0; i
< count
; i
++)
3279 struct ipa_jump_func
*jf
= ipa_get_ith_jump_func (args
, i
);
3280 struct ipa_cst_ref_desc
*rdesc
;
3282 if (jf
->type
== IPA_JF_PASS_THROUGH
)
3285 src_idx
= ipa_get_jf_pass_through_formal_id (jf
);
3286 c
= ipa_get_controlled_uses (new_root_info
, src_idx
);
3287 d
= ipa_get_controlled_uses (old_root_info
, i
);
3289 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf
)
3290 == NOP_EXPR
|| c
== IPA_UNDESCRIBED_USE
);
3291 c
= combine_controlled_uses_counters (c
, d
);
3292 ipa_set_controlled_uses (new_root_info
, src_idx
, c
);
3293 if (c
== 0 && new_root_info
->ipcp_orig_node
)
3295 struct cgraph_node
*n
;
3296 struct ipa_ref
*ref
;
3297 tree t
= new_root_info
->known_vals
[src_idx
];
3299 if (t
&& TREE_CODE (t
) == ADDR_EXPR
3300 && TREE_CODE (TREE_OPERAND (t
, 0)) == FUNCTION_DECL
3301 && (n
= cgraph_get_node (TREE_OPERAND (t
, 0)))
3302 && (ref
= new_root
->find_reference (n
, NULL
, 0)))
3305 fprintf (dump_file
, "ipa-prop: Removing cloning-created "
3306 "reference from %s/%i to %s/%i.\n",
3307 xstrdup (new_root
->name ()),
3309 xstrdup (n
->name ()), n
->order
);
3310 ref
->remove_reference ();
3314 else if (jf
->type
== IPA_JF_CONST
3315 && (rdesc
= jfunc_rdesc_usable (jf
)))
3317 int d
= ipa_get_controlled_uses (old_root_info
, i
);
3318 int c
= rdesc
->refcount
;
3319 rdesc
->refcount
= combine_controlled_uses_counters (c
, d
);
3320 if (rdesc
->refcount
== 0)
3322 tree cst
= ipa_get_jf_constant (jf
);
3323 struct cgraph_node
*n
;
3324 gcc_checking_assert (TREE_CODE (cst
) == ADDR_EXPR
3325 && TREE_CODE (TREE_OPERAND (cst
, 0))
3327 n
= cgraph_get_node (TREE_OPERAND (cst
, 0));
3330 struct cgraph_node
*clone
;
3332 ok
= remove_described_reference (n
, rdesc
);
3333 gcc_checking_assert (ok
);
3336 while (clone
->global
.inlined_to
3337 && clone
!= rdesc
->cs
->caller
3338 && IPA_NODE_REF (clone
)->ipcp_orig_node
)
3340 struct ipa_ref
*ref
;
3341 ref
= clone
->find_reference (n
, NULL
, 0);
3345 fprintf (dump_file
, "ipa-prop: Removing "
3346 "cloning-created reference "
3347 "from %s/%i to %s/%i.\n",
3348 xstrdup (clone
->name ()),
3350 xstrdup (n
->name ()),
3352 ref
->remove_reference ();
3354 clone
= clone
->callers
->caller
;
3361 for (i
= ipa_get_param_count (old_root_info
);
3362 i
< ipa_get_cs_argument_count (args
);
3365 struct ipa_jump_func
*jf
= ipa_get_ith_jump_func (args
, i
);
3367 if (jf
->type
== IPA_JF_CONST
)
3369 struct ipa_cst_ref_desc
*rdesc
= jfunc_rdesc_usable (jf
);
3371 rdesc
->refcount
= IPA_UNDESCRIBED_USE
;
3373 else if (jf
->type
== IPA_JF_PASS_THROUGH
)
3374 ipa_set_controlled_uses (new_root_info
,
3375 jf
->value
.pass_through
.formal_id
,
3376 IPA_UNDESCRIBED_USE
);
3380 /* Update jump functions and call note functions on inlining the call site CS.
3381 CS is expected to lead to a node already cloned by
3382 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
3383 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
3387 ipa_propagate_indirect_call_infos (struct cgraph_edge
*cs
,
3388 vec
<cgraph_edge_p
> *new_edges
)
3391 /* Do nothing if the preparation phase has not been carried out yet
3392 (i.e. during early inlining). */
3393 if (!ipa_node_params_vector
.exists ())
3395 gcc_assert (ipa_edge_args_vector
);
3397 propagate_controlled_uses (cs
);
3398 changed
= propagate_info_to_inlined_callees (cs
, cs
->callee
, new_edges
);
3403 /* Frees all dynamically allocated structures that the argument info points
3407 ipa_free_edge_args_substructures (struct ipa_edge_args
*args
)
3409 vec_free (args
->jump_functions
);
3410 memset (args
, 0, sizeof (*args
));
3413 /* Free all ipa_edge structures. */
3416 ipa_free_all_edge_args (void)
3419 struct ipa_edge_args
*args
;
3421 if (!ipa_edge_args_vector
)
3424 FOR_EACH_VEC_ELT (*ipa_edge_args_vector
, i
, args
)
3425 ipa_free_edge_args_substructures (args
);
3427 vec_free (ipa_edge_args_vector
);
3430 /* Frees all dynamically allocated structures that the param info points
3434 ipa_free_node_params_substructures (struct ipa_node_params
*info
)
3436 info
->descriptors
.release ();
3437 free (info
->lattices
);
3438 /* Lattice values and their sources are deallocated with their alocation
3440 info
->known_vals
.release ();
3441 memset (info
, 0, sizeof (*info
));
3444 /* Free all ipa_node_params structures. */
3447 ipa_free_all_node_params (void)
3450 struct ipa_node_params
*info
;
3452 FOR_EACH_VEC_ELT (ipa_node_params_vector
, i
, info
)
3453 ipa_free_node_params_substructures (info
);
3455 ipa_node_params_vector
.release ();
3458 /* Set the aggregate replacements of NODE to be AGGVALS. */
3461 ipa_set_node_agg_value_chain (struct cgraph_node
*node
,
3462 struct ipa_agg_replacement_value
*aggvals
)
3464 if (vec_safe_length (ipa_node_agg_replacements
) <= (unsigned) cgraph_max_uid
)
3465 vec_safe_grow_cleared (ipa_node_agg_replacements
, cgraph_max_uid
+ 1);
3467 (*ipa_node_agg_replacements
)[node
->uid
] = aggvals
;
3470 /* Hook that is called by cgraph.c when an edge is removed. */
3473 ipa_edge_removal_hook (struct cgraph_edge
*cs
, void *data ATTRIBUTE_UNUSED
)
3475 struct ipa_edge_args
*args
;
3477 /* During IPA-CP updating we can be called on not-yet analyzed clones. */
3478 if (vec_safe_length (ipa_edge_args_vector
) <= (unsigned)cs
->uid
)
3481 args
= IPA_EDGE_REF (cs
);
3482 if (args
->jump_functions
)
3484 struct ipa_jump_func
*jf
;
3486 FOR_EACH_VEC_ELT (*args
->jump_functions
, i
, jf
)
3488 struct ipa_cst_ref_desc
*rdesc
;
3489 try_decrement_rdesc_refcount (jf
);
3490 if (jf
->type
== IPA_JF_CONST
3491 && (rdesc
= ipa_get_jf_constant_rdesc (jf
))
3497 ipa_free_edge_args_substructures (IPA_EDGE_REF (cs
));
3500 /* Hook that is called by cgraph.c when a node is removed. */
3503 ipa_node_removal_hook (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
3505 /* During IPA-CP updating we can be called on not-yet analyze clones. */
3506 if (ipa_node_params_vector
.length () > (unsigned)node
->uid
)
3507 ipa_free_node_params_substructures (IPA_NODE_REF (node
));
3508 if (vec_safe_length (ipa_node_agg_replacements
) > (unsigned)node
->uid
)
3509 (*ipa_node_agg_replacements
)[(unsigned)node
->uid
] = NULL
;
3512 /* Hook that is called by cgraph.c when an edge is duplicated. */
3515 ipa_edge_duplication_hook (struct cgraph_edge
*src
, struct cgraph_edge
*dst
,
3516 __attribute__((unused
)) void *data
)
3518 struct ipa_edge_args
*old_args
, *new_args
;
3521 ipa_check_create_edge_args ();
3523 old_args
= IPA_EDGE_REF (src
);
3524 new_args
= IPA_EDGE_REF (dst
);
3526 new_args
->jump_functions
= vec_safe_copy (old_args
->jump_functions
);
3528 for (i
= 0; i
< vec_safe_length (old_args
->jump_functions
); i
++)
3530 struct ipa_jump_func
*src_jf
= ipa_get_ith_jump_func (old_args
, i
);
3531 struct ipa_jump_func
*dst_jf
= ipa_get_ith_jump_func (new_args
, i
);
3533 dst_jf
->agg
.items
= vec_safe_copy (dst_jf
->agg
.items
);
3535 if (src_jf
->type
== IPA_JF_CONST
)
3537 struct ipa_cst_ref_desc
*src_rdesc
= jfunc_rdesc_usable (src_jf
);
3540 dst_jf
->value
.constant
.rdesc
= NULL
;
3541 else if (src
->caller
== dst
->caller
)
3543 struct ipa_ref
*ref
;
3544 symtab_node
*n
= cgraph_node_for_jfunc (src_jf
);
3545 gcc_checking_assert (n
);
3546 ref
= src
->caller
->find_reference (n
, src
->call_stmt
,
3548 gcc_checking_assert (ref
);
3549 dst
->caller
->clone_reference (ref
, ref
->stmt
);
3551 gcc_checking_assert (ipa_refdesc_pool
);
3552 struct ipa_cst_ref_desc
*dst_rdesc
3553 = (struct ipa_cst_ref_desc
*) pool_alloc (ipa_refdesc_pool
);
3554 dst_rdesc
->cs
= dst
;
3555 dst_rdesc
->refcount
= src_rdesc
->refcount
;
3556 dst_rdesc
->next_duplicate
= NULL
;
3557 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
3559 else if (src_rdesc
->cs
== src
)
3561 struct ipa_cst_ref_desc
*dst_rdesc
;
3562 gcc_checking_assert (ipa_refdesc_pool
);
3564 = (struct ipa_cst_ref_desc
*) pool_alloc (ipa_refdesc_pool
);
3565 dst_rdesc
->cs
= dst
;
3566 dst_rdesc
->refcount
= src_rdesc
->refcount
;
3567 dst_rdesc
->next_duplicate
= src_rdesc
->next_duplicate
;
3568 src_rdesc
->next_duplicate
= dst_rdesc
;
3569 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
3573 struct ipa_cst_ref_desc
*dst_rdesc
;
3574 /* This can happen during inlining, when a JFUNC can refer to a
3575 reference taken in a function up in the tree of inline clones.
3576 We need to find the duplicate that refers to our tree of
3579 gcc_assert (dst
->caller
->global
.inlined_to
);
3580 for (dst_rdesc
= src_rdesc
->next_duplicate
;
3582 dst_rdesc
= dst_rdesc
->next_duplicate
)
3584 struct cgraph_node
*top
;
3585 top
= dst_rdesc
->cs
->caller
->global
.inlined_to
3586 ? dst_rdesc
->cs
->caller
->global
.inlined_to
3587 : dst_rdesc
->cs
->caller
;
3588 if (dst
->caller
->global
.inlined_to
== top
)
3591 gcc_assert (dst_rdesc
);
3592 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
3598 /* Hook that is called by cgraph.c when a node is duplicated. */
3601 ipa_node_duplication_hook (struct cgraph_node
*src
, struct cgraph_node
*dst
,
3602 ATTRIBUTE_UNUSED
void *data
)
3604 struct ipa_node_params
*old_info
, *new_info
;
3605 struct ipa_agg_replacement_value
*old_av
, *new_av
;
3607 ipa_check_create_node_params ();
3608 old_info
= IPA_NODE_REF (src
);
3609 new_info
= IPA_NODE_REF (dst
);
3611 new_info
->descriptors
= old_info
->descriptors
.copy ();
3612 new_info
->lattices
= NULL
;
3613 new_info
->ipcp_orig_node
= old_info
->ipcp_orig_node
;
3615 new_info
->analysis_done
= old_info
->analysis_done
;
3616 new_info
->node_enqueued
= old_info
->node_enqueued
;
3618 old_av
= ipa_get_agg_replacements_for_node (src
);
3625 struct ipa_agg_replacement_value
*v
;
3627 v
= ggc_alloc
<ipa_agg_replacement_value
> ();
3628 memcpy (v
, old_av
, sizeof (*v
));
3631 old_av
= old_av
->next
;
3633 ipa_set_node_agg_value_chain (dst
, new_av
);
3637 /* Analyze newly added function into callgraph. */
3640 ipa_add_new_function (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
3642 if (cgraph_function_with_gimple_body_p (node
))
3643 ipa_analyze_node (node
);
3646 /* Register our cgraph hooks if they are not already there. */
3649 ipa_register_cgraph_hooks (void)
3651 if (!edge_removal_hook_holder
)
3652 edge_removal_hook_holder
=
3653 cgraph_add_edge_removal_hook (&ipa_edge_removal_hook
, NULL
);
3654 if (!node_removal_hook_holder
)
3655 node_removal_hook_holder
=
3656 cgraph_add_node_removal_hook (&ipa_node_removal_hook
, NULL
);
3657 if (!edge_duplication_hook_holder
)
3658 edge_duplication_hook_holder
=
3659 cgraph_add_edge_duplication_hook (&ipa_edge_duplication_hook
, NULL
);
3660 if (!node_duplication_hook_holder
)
3661 node_duplication_hook_holder
=
3662 cgraph_add_node_duplication_hook (&ipa_node_duplication_hook
, NULL
);
3663 function_insertion_hook_holder
=
3664 cgraph_add_function_insertion_hook (&ipa_add_new_function
, NULL
);
3667 /* Unregister our cgraph hooks if they are not already there. */
3670 ipa_unregister_cgraph_hooks (void)
3672 cgraph_remove_edge_removal_hook (edge_removal_hook_holder
);
3673 edge_removal_hook_holder
= NULL
;
3674 cgraph_remove_node_removal_hook (node_removal_hook_holder
);
3675 node_removal_hook_holder
= NULL
;
3676 cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder
);
3677 edge_duplication_hook_holder
= NULL
;
3678 cgraph_remove_node_duplication_hook (node_duplication_hook_holder
);
3679 node_duplication_hook_holder
= NULL
;
3680 cgraph_remove_function_insertion_hook (function_insertion_hook_holder
);
3681 function_insertion_hook_holder
= NULL
;
3684 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
3685 longer needed after ipa-cp. */
3688 ipa_free_all_structures_after_ipa_cp (void)
3692 ipa_free_all_edge_args ();
3693 ipa_free_all_node_params ();
3694 free_alloc_pool (ipcp_sources_pool
);
3695 free_alloc_pool (ipcp_values_pool
);
3696 free_alloc_pool (ipcp_agg_lattice_pool
);
3697 ipa_unregister_cgraph_hooks ();
3698 if (ipa_refdesc_pool
)
3699 free_alloc_pool (ipa_refdesc_pool
);
3703 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
3704 longer needed after indirect inlining. */
3707 ipa_free_all_structures_after_iinln (void)
3709 ipa_free_all_edge_args ();
3710 ipa_free_all_node_params ();
3711 ipa_unregister_cgraph_hooks ();
3712 if (ipcp_sources_pool
)
3713 free_alloc_pool (ipcp_sources_pool
);
3714 if (ipcp_values_pool
)
3715 free_alloc_pool (ipcp_values_pool
);
3716 if (ipcp_agg_lattice_pool
)
3717 free_alloc_pool (ipcp_agg_lattice_pool
);
3718 if (ipa_refdesc_pool
)
3719 free_alloc_pool (ipa_refdesc_pool
);
3722 /* Print ipa_tree_map data structures of all functions in the
3726 ipa_print_node_params (FILE *f
, struct cgraph_node
*node
)
3729 struct ipa_node_params
*info
;
3731 if (!node
->definition
)
3733 info
= IPA_NODE_REF (node
);
3734 fprintf (f
, " function %s/%i parameter descriptors:\n",
3735 node
->name (), node
->order
);
3736 count
= ipa_get_param_count (info
);
3737 for (i
= 0; i
< count
; i
++)
3742 ipa_dump_param (f
, info
, i
);
3743 if (ipa_is_param_used (info
, i
))
3744 fprintf (f
, " used");
3745 c
= ipa_get_controlled_uses (info
, i
);
3746 if (c
== IPA_UNDESCRIBED_USE
)
3747 fprintf (f
, " undescribed_use");
3749 fprintf (f
, " controlled_uses=%i", c
);
3754 /* Print ipa_tree_map data structures of all functions in the
3758 ipa_print_all_params (FILE * f
)
3760 struct cgraph_node
*node
;
3762 fprintf (f
, "\nFunction parameters:\n");
3763 FOR_EACH_FUNCTION (node
)
3764 ipa_print_node_params (f
, node
);
3767 /* Return a heap allocated vector containing formal parameters of FNDECL. */
3770 ipa_get_vector_of_formal_parms (tree fndecl
)
3776 gcc_assert (!flag_wpa
);
3777 count
= count_formal_params (fndecl
);
3778 args
.create (count
);
3779 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
3780 args
.quick_push (parm
);
3785 /* Return a heap allocated vector containing types of formal parameters of
3786 function type FNTYPE. */
3789 ipa_get_vector_of_formal_parm_types (tree fntype
)
3795 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
3798 types
.create (count
);
3799 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
3800 types
.quick_push (TREE_VALUE (t
));
3805 /* Modify the function declaration FNDECL and its type according to the plan in
3806 ADJUSTMENTS. It also sets base fields of individual adjustments structures
3807 to reflect the actual parameters being modified which are determined by the
3808 base_index field. */
3811 ipa_modify_formal_parameters (tree fndecl
, ipa_parm_adjustment_vec adjustments
)
3813 vec
<tree
> oparms
= ipa_get_vector_of_formal_parms (fndecl
);
3814 tree orig_type
= TREE_TYPE (fndecl
);
3815 tree old_arg_types
= TYPE_ARG_TYPES (orig_type
);
3817 /* The following test is an ugly hack, some functions simply don't have any
3818 arguments in their type. This is probably a bug but well... */
3819 bool care_for_types
= (old_arg_types
!= NULL_TREE
);
3820 bool last_parm_void
;
3824 last_parm_void
= (TREE_VALUE (tree_last (old_arg_types
))
3826 otypes
= ipa_get_vector_of_formal_parm_types (orig_type
);
3828 gcc_assert (oparms
.length () + 1 == otypes
.length ());
3830 gcc_assert (oparms
.length () == otypes
.length ());
3834 last_parm_void
= false;
3838 int len
= adjustments
.length ();
3839 tree
*link
= &DECL_ARGUMENTS (fndecl
);
3840 tree new_arg_types
= NULL
;
3841 for (int i
= 0; i
< len
; i
++)
3843 struct ipa_parm_adjustment
*adj
;
3846 adj
= &adjustments
[i
];
3848 if (adj
->op
== IPA_PARM_OP_NEW
)
3851 parm
= oparms
[adj
->base_index
];
3854 if (adj
->op
== IPA_PARM_OP_COPY
)
3857 new_arg_types
= tree_cons (NULL_TREE
, otypes
[adj
->base_index
],
3860 link
= &DECL_CHAIN (parm
);
3862 else if (adj
->op
!= IPA_PARM_OP_REMOVE
)
3868 ptype
= build_pointer_type (adj
->type
);
3872 if (is_gimple_reg_type (ptype
))
3874 unsigned malign
= GET_MODE_ALIGNMENT (TYPE_MODE (ptype
));
3875 if (TYPE_ALIGN (ptype
) < malign
)
3876 ptype
= build_aligned_type (ptype
, malign
);
3881 new_arg_types
= tree_cons (NULL_TREE
, ptype
, new_arg_types
);
3883 new_parm
= build_decl (UNKNOWN_LOCATION
, PARM_DECL
, NULL_TREE
,
3885 const char *prefix
= adj
->arg_prefix
? adj
->arg_prefix
: "SYNTH";
3886 DECL_NAME (new_parm
) = create_tmp_var_name (prefix
);
3887 DECL_ARTIFICIAL (new_parm
) = 1;
3888 DECL_ARG_TYPE (new_parm
) = ptype
;
3889 DECL_CONTEXT (new_parm
) = fndecl
;
3890 TREE_USED (new_parm
) = 1;
3891 DECL_IGNORED_P (new_parm
) = 1;
3892 layout_decl (new_parm
, 0);
3894 if (adj
->op
== IPA_PARM_OP_NEW
)
3898 adj
->new_decl
= new_parm
;
3901 link
= &DECL_CHAIN (new_parm
);
3907 tree new_reversed
= NULL
;
3910 new_reversed
= nreverse (new_arg_types
);
3914 TREE_CHAIN (new_arg_types
) = void_list_node
;
3916 new_reversed
= void_list_node
;
3920 /* Use copy_node to preserve as much as possible from original type
3921 (debug info, attribute lists etc.)
3922 Exception is METHOD_TYPEs must have THIS argument.
3923 When we are asked to remove it, we need to build new FUNCTION_TYPE
3925 tree new_type
= NULL
;
3926 if (TREE_CODE (orig_type
) != METHOD_TYPE
3927 || (adjustments
[0].op
== IPA_PARM_OP_COPY
3928 && adjustments
[0].base_index
== 0))
3930 new_type
= build_distinct_type_copy (orig_type
);
3931 TYPE_ARG_TYPES (new_type
) = new_reversed
;
3936 = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type
),
3938 TYPE_CONTEXT (new_type
) = TYPE_CONTEXT (orig_type
);
3939 DECL_VINDEX (fndecl
) = NULL_TREE
;
3942 /* When signature changes, we need to clear builtin info. */
3943 if (DECL_BUILT_IN (fndecl
))
3945 DECL_BUILT_IN_CLASS (fndecl
) = NOT_BUILT_IN
;
3946 DECL_FUNCTION_CODE (fndecl
) = (enum built_in_function
) 0;
3949 /* This is a new type, not a copy of an old type. Need to reassociate
3950 variants. We can handle everything except the main variant lazily. */
3951 tree t
= TYPE_MAIN_VARIANT (orig_type
);
3954 TYPE_MAIN_VARIANT (new_type
) = t
;
3955 TYPE_NEXT_VARIANT (new_type
) = TYPE_NEXT_VARIANT (t
);
3956 TYPE_NEXT_VARIANT (t
) = new_type
;
3960 TYPE_MAIN_VARIANT (new_type
) = new_type
;
3961 TYPE_NEXT_VARIANT (new_type
) = NULL
;
3964 TREE_TYPE (fndecl
) = new_type
;
3965 DECL_VIRTUAL_P (fndecl
) = 0;
3966 DECL_LANG_SPECIFIC (fndecl
) = NULL
;
3971 /* Modify actual arguments of a function call CS as indicated in ADJUSTMENTS.
3972 If this is a directly recursive call, CS must be NULL. Otherwise it must
3973 contain the corresponding call graph edge. */
3976 ipa_modify_call_arguments (struct cgraph_edge
*cs
, gimple stmt
,
3977 ipa_parm_adjustment_vec adjustments
)
3979 struct cgraph_node
*current_node
= cgraph_get_node (current_function_decl
);
3981 vec
<tree
, va_gc
> **debug_args
= NULL
;
3983 gimple_stmt_iterator gsi
, prev_gsi
;
3987 len
= adjustments
.length ();
3989 callee_decl
= !cs
? gimple_call_fndecl (stmt
) : cs
->callee
->decl
;
3990 current_node
->remove_stmt_references (stmt
);
3992 gsi
= gsi_for_stmt (stmt
);
3994 gsi_prev (&prev_gsi
);
3995 for (i
= 0; i
< len
; i
++)
3997 struct ipa_parm_adjustment
*adj
;
3999 adj
= &adjustments
[i
];
4001 if (adj
->op
== IPA_PARM_OP_COPY
)
4003 tree arg
= gimple_call_arg (stmt
, adj
->base_index
);
4005 vargs
.quick_push (arg
);
4007 else if (adj
->op
!= IPA_PARM_OP_REMOVE
)
4009 tree expr
, base
, off
;
4011 unsigned int deref_align
= 0;
4012 bool deref_base
= false;
4014 /* We create a new parameter out of the value of the old one, we can
4015 do the following kind of transformations:
4017 - A scalar passed by reference is converted to a scalar passed by
4018 value. (adj->by_ref is false and the type of the original
4019 actual argument is a pointer to a scalar).
4021 - A part of an aggregate is passed instead of the whole aggregate.
4022 The part can be passed either by value or by reference, this is
4023 determined by value of adj->by_ref. Moreover, the code below
4024 handles both situations when the original aggregate is passed by
4025 value (its type is not a pointer) and when it is passed by
4026 reference (it is a pointer to an aggregate).
4028 When the new argument is passed by reference (adj->by_ref is true)
4029 it must be a part of an aggregate and therefore we form it by
4030 simply taking the address of a reference inside the original
4033 gcc_checking_assert (adj
->offset
% BITS_PER_UNIT
== 0);
4034 base
= gimple_call_arg (stmt
, adj
->base_index
);
4035 loc
= DECL_P (base
) ? DECL_SOURCE_LOCATION (base
)
4036 : EXPR_LOCATION (base
);
4038 if (TREE_CODE (base
) != ADDR_EXPR
4039 && POINTER_TYPE_P (TREE_TYPE (base
)))
4040 off
= build_int_cst (adj
->alias_ptr_type
,
4041 adj
->offset
/ BITS_PER_UNIT
);
4044 HOST_WIDE_INT base_offset
;
4048 if (TREE_CODE (base
) == ADDR_EXPR
)
4050 base
= TREE_OPERAND (base
, 0);
4056 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
4057 /* Aggregate arguments can have non-invariant addresses. */
4060 base
= build_fold_addr_expr (prev_base
);
4061 off
= build_int_cst (adj
->alias_ptr_type
,
4062 adj
->offset
/ BITS_PER_UNIT
);
4064 else if (TREE_CODE (base
) == MEM_REF
)
4069 deref_align
= TYPE_ALIGN (TREE_TYPE (base
));
4071 off
= build_int_cst (adj
->alias_ptr_type
,
4073 + adj
->offset
/ BITS_PER_UNIT
);
4074 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1),
4076 base
= TREE_OPERAND (base
, 0);
4080 off
= build_int_cst (adj
->alias_ptr_type
,
4082 + adj
->offset
/ BITS_PER_UNIT
);
4083 base
= build_fold_addr_expr (base
);
4089 tree type
= adj
->type
;
4091 unsigned HOST_WIDE_INT misalign
;
4095 align
= deref_align
;
4100 get_pointer_alignment_1 (base
, &align
, &misalign
);
4101 if (TYPE_ALIGN (type
) > align
)
4102 align
= TYPE_ALIGN (type
);
4104 misalign
+= (offset_int::from (off
, SIGNED
).to_short_addr ()
4106 misalign
= misalign
& (align
- 1);
4108 align
= (misalign
& -misalign
);
4109 if (align
< TYPE_ALIGN (type
))
4110 type
= build_aligned_type (type
, align
);
4111 base
= force_gimple_operand_gsi (&gsi
, base
,
4112 true, NULL
, true, GSI_SAME_STMT
);
4113 expr
= fold_build2_loc (loc
, MEM_REF
, type
, base
, off
);
4114 /* If expr is not a valid gimple call argument emit
4115 a load into a temporary. */
4116 if (is_gimple_reg_type (TREE_TYPE (expr
)))
4118 gimple tem
= gimple_build_assign (NULL_TREE
, expr
);
4119 if (gimple_in_ssa_p (cfun
))
4121 gimple_set_vuse (tem
, gimple_vuse (stmt
));
4122 expr
= make_ssa_name (TREE_TYPE (expr
), tem
);
4125 expr
= create_tmp_reg (TREE_TYPE (expr
), NULL
);
4126 gimple_assign_set_lhs (tem
, expr
);
4127 gsi_insert_before (&gsi
, tem
, GSI_SAME_STMT
);
4132 expr
= fold_build2_loc (loc
, MEM_REF
, adj
->type
, base
, off
);
4133 expr
= build_fold_addr_expr (expr
);
4134 expr
= force_gimple_operand_gsi (&gsi
, expr
,
4135 true, NULL
, true, GSI_SAME_STMT
);
4137 vargs
.quick_push (expr
);
4139 if (adj
->op
!= IPA_PARM_OP_COPY
&& MAY_HAVE_DEBUG_STMTS
)
4142 tree ddecl
= NULL_TREE
, origin
= DECL_ORIGIN (adj
->base
), arg
;
4145 arg
= gimple_call_arg (stmt
, adj
->base_index
);
4146 if (!useless_type_conversion_p (TREE_TYPE (origin
), TREE_TYPE (arg
)))
4148 if (!fold_convertible_p (TREE_TYPE (origin
), arg
))
4150 arg
= fold_convert_loc (gimple_location (stmt
),
4151 TREE_TYPE (origin
), arg
);
4153 if (debug_args
== NULL
)
4154 debug_args
= decl_debug_args_insert (callee_decl
);
4155 for (ix
= 0; vec_safe_iterate (*debug_args
, ix
, &ddecl
); ix
+= 2)
4156 if (ddecl
== origin
)
4158 ddecl
= (**debug_args
)[ix
+ 1];
4163 ddecl
= make_node (DEBUG_EXPR_DECL
);
4164 DECL_ARTIFICIAL (ddecl
) = 1;
4165 TREE_TYPE (ddecl
) = TREE_TYPE (origin
);
4166 DECL_MODE (ddecl
) = DECL_MODE (origin
);
4168 vec_safe_push (*debug_args
, origin
);
4169 vec_safe_push (*debug_args
, ddecl
);
4171 def_temp
= gimple_build_debug_bind (ddecl
, unshare_expr (arg
), stmt
);
4172 gsi_insert_before (&gsi
, def_temp
, GSI_SAME_STMT
);
4176 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4178 fprintf (dump_file
, "replacing stmt:");
4179 print_gimple_stmt (dump_file
, gsi_stmt (gsi
), 0, 0);
4182 new_stmt
= gimple_build_call_vec (callee_decl
, vargs
);
4184 if (gimple_call_lhs (stmt
))
4185 gimple_call_set_lhs (new_stmt
, gimple_call_lhs (stmt
));
4187 gimple_set_block (new_stmt
, gimple_block (stmt
));
4188 if (gimple_has_location (stmt
))
4189 gimple_set_location (new_stmt
, gimple_location (stmt
));
4190 gimple_call_set_chain (new_stmt
, gimple_call_chain (stmt
));
4191 gimple_call_copy_flags (new_stmt
, stmt
);
4192 if (gimple_in_ssa_p (cfun
))
4194 gimple_set_vuse (new_stmt
, gimple_vuse (stmt
));
4195 if (gimple_vdef (stmt
))
4197 gimple_set_vdef (new_stmt
, gimple_vdef (stmt
));
4198 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt
)) = new_stmt
;
4202 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4204 fprintf (dump_file
, "with stmt:");
4205 print_gimple_stmt (dump_file
, new_stmt
, 0, 0);
4206 fprintf (dump_file
, "\n");
4208 gsi_replace (&gsi
, new_stmt
, true);
4210 cgraph_set_call_stmt (cs
, new_stmt
);
4213 ipa_record_stmt_references (current_node
, gsi_stmt (gsi
));
4216 while (gsi_stmt (gsi
) != gsi_stmt (prev_gsi
));
4219 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
4220 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
4221 specifies whether the function should care about type incompatibility the
4222 current and new expressions. If it is false, the function will leave
4223 incompatibility issues to the caller. Return true iff the expression
4227 ipa_modify_expr (tree
*expr
, bool convert
,
4228 ipa_parm_adjustment_vec adjustments
)
4230 struct ipa_parm_adjustment
*cand
4231 = ipa_get_adjustment_candidate (&expr
, &convert
, adjustments
, false);
4237 src
= build_simple_mem_ref (cand
->new_decl
);
4239 src
= cand
->new_decl
;
4241 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4243 fprintf (dump_file
, "About to replace expr ");
4244 print_generic_expr (dump_file
, *expr
, 0);
4245 fprintf (dump_file
, " with ");
4246 print_generic_expr (dump_file
, src
, 0);
4247 fprintf (dump_file
, "\n");
4250 if (convert
&& !useless_type_conversion_p (TREE_TYPE (*expr
), cand
->type
))
4252 tree vce
= build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (*expr
), src
);
4260 /* If T is an SSA_NAME, return NULL if it is not a default def or
4261 return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
4262 the base variable is always returned, regardless if it is a default
4263 def. Return T if it is not an SSA_NAME. */
4266 get_ssa_base_param (tree t
, bool ignore_default_def
)
4268 if (TREE_CODE (t
) == SSA_NAME
)
4270 if (ignore_default_def
|| SSA_NAME_IS_DEFAULT_DEF (t
))
4271 return SSA_NAME_VAR (t
);
4278 /* Given an expression, return an adjustment entry specifying the
4279 transformation to be done on EXPR. If no suitable adjustment entry
4280 was found, returns NULL.
4282 If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
4283 default def, otherwise bail on them.
4285 If CONVERT is non-NULL, this function will set *CONVERT if the
4286 expression provided is a component reference. ADJUSTMENTS is the
4287 adjustments vector. */
4289 ipa_parm_adjustment
*
4290 ipa_get_adjustment_candidate (tree
**expr
, bool *convert
,
4291 ipa_parm_adjustment_vec adjustments
,
4292 bool ignore_default_def
)
4294 if (TREE_CODE (**expr
) == BIT_FIELD_REF
4295 || TREE_CODE (**expr
) == IMAGPART_EXPR
4296 || TREE_CODE (**expr
) == REALPART_EXPR
)
4298 *expr
= &TREE_OPERAND (**expr
, 0);
4303 HOST_WIDE_INT offset
, size
, max_size
;
4304 tree base
= get_ref_base_and_extent (**expr
, &offset
, &size
, &max_size
);
4305 if (!base
|| size
== -1 || max_size
== -1)
4308 if (TREE_CODE (base
) == MEM_REF
)
4310 offset
+= mem_ref_offset (base
).to_short_addr () * BITS_PER_UNIT
;
4311 base
= TREE_OPERAND (base
, 0);
4314 base
= get_ssa_base_param (base
, ignore_default_def
);
4315 if (!base
|| TREE_CODE (base
) != PARM_DECL
)
4318 struct ipa_parm_adjustment
*cand
= NULL
;
4319 unsigned int len
= adjustments
.length ();
4320 for (unsigned i
= 0; i
< len
; i
++)
4322 struct ipa_parm_adjustment
*adj
= &adjustments
[i
];
4324 if (adj
->base
== base
4325 && (adj
->offset
== offset
|| adj
->op
== IPA_PARM_OP_REMOVE
))
4332 if (!cand
|| cand
->op
== IPA_PARM_OP_COPY
|| cand
->op
== IPA_PARM_OP_REMOVE
)
4337 /* Return true iff BASE_INDEX is in ADJUSTMENTS more than once. */
4340 index_in_adjustments_multiple_times_p (int base_index
,
4341 ipa_parm_adjustment_vec adjustments
)
4343 int i
, len
= adjustments
.length ();
4346 for (i
= 0; i
< len
; i
++)
4348 struct ipa_parm_adjustment
*adj
;
4349 adj
= &adjustments
[i
];
4351 if (adj
->base_index
== base_index
)
4363 /* Return adjustments that should have the same effect on function parameters
4364 and call arguments as if they were first changed according to adjustments in
4365 INNER and then by adjustments in OUTER. */
4367 ipa_parm_adjustment_vec
4368 ipa_combine_adjustments (ipa_parm_adjustment_vec inner
,
4369 ipa_parm_adjustment_vec outer
)
4371 int i
, outlen
= outer
.length ();
4372 int inlen
= inner
.length ();
4374 ipa_parm_adjustment_vec adjustments
, tmp
;
4377 for (i
= 0; i
< inlen
; i
++)
4379 struct ipa_parm_adjustment
*n
;
4382 if (n
->op
== IPA_PARM_OP_REMOVE
)
4386 /* FIXME: Handling of new arguments are not implemented yet. */
4387 gcc_assert (n
->op
!= IPA_PARM_OP_NEW
);
4388 tmp
.quick_push (*n
);
4392 adjustments
.create (outlen
+ removals
);
4393 for (i
= 0; i
< outlen
; i
++)
4395 struct ipa_parm_adjustment r
;
4396 struct ipa_parm_adjustment
*out
= &outer
[i
];
4397 struct ipa_parm_adjustment
*in
= &tmp
[out
->base_index
];
4399 memset (&r
, 0, sizeof (r
));
4400 gcc_assert (in
->op
!= IPA_PARM_OP_REMOVE
);
4401 if (out
->op
== IPA_PARM_OP_REMOVE
)
4403 if (!index_in_adjustments_multiple_times_p (in
->base_index
, tmp
))
4405 r
.op
= IPA_PARM_OP_REMOVE
;
4406 adjustments
.quick_push (r
);
4412 /* FIXME: Handling of new arguments are not implemented yet. */
4413 gcc_assert (out
->op
!= IPA_PARM_OP_NEW
);
4416 r
.base_index
= in
->base_index
;
4419 /* FIXME: Create nonlocal value too. */
4421 if (in
->op
== IPA_PARM_OP_COPY
&& out
->op
== IPA_PARM_OP_COPY
)
4422 r
.op
= IPA_PARM_OP_COPY
;
4423 else if (in
->op
== IPA_PARM_OP_COPY
)
4424 r
.offset
= out
->offset
;
4425 else if (out
->op
== IPA_PARM_OP_COPY
)
4426 r
.offset
= in
->offset
;
4428 r
.offset
= in
->offset
+ out
->offset
;
4429 adjustments
.quick_push (r
);
4432 for (i
= 0; i
< inlen
; i
++)
4434 struct ipa_parm_adjustment
*n
= &inner
[i
];
4436 if (n
->op
== IPA_PARM_OP_REMOVE
)
4437 adjustments
.quick_push (*n
);
4444 /* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
4445 friendly way, assuming they are meant to be applied to FNDECL. */
4448 ipa_dump_param_adjustments (FILE *file
, ipa_parm_adjustment_vec adjustments
,
4451 int i
, len
= adjustments
.length ();
4453 vec
<tree
> parms
= ipa_get_vector_of_formal_parms (fndecl
);
4455 fprintf (file
, "IPA param adjustments: ");
4456 for (i
= 0; i
< len
; i
++)
4458 struct ipa_parm_adjustment
*adj
;
4459 adj
= &adjustments
[i
];
4462 fprintf (file
, " ");
4466 fprintf (file
, "%i. base_index: %i - ", i
, adj
->base_index
);
4467 print_generic_expr (file
, parms
[adj
->base_index
], 0);
4470 fprintf (file
, ", base: ");
4471 print_generic_expr (file
, adj
->base
, 0);
4475 fprintf (file
, ", new_decl: ");
4476 print_generic_expr (file
, adj
->new_decl
, 0);
4478 if (adj
->new_ssa_base
)
4480 fprintf (file
, ", new_ssa_base: ");
4481 print_generic_expr (file
, adj
->new_ssa_base
, 0);
4484 if (adj
->op
== IPA_PARM_OP_COPY
)
4485 fprintf (file
, ", copy_param");
4486 else if (adj
->op
== IPA_PARM_OP_REMOVE
)
4487 fprintf (file
, ", remove_param");
4489 fprintf (file
, ", offset %li", (long) adj
->offset
);
4491 fprintf (file
, ", by_ref");
4492 print_node_brief (file
, ", type: ", adj
->type
, 0);
4493 fprintf (file
, "\n");
4498 /* Dump the AV linked list. */
4501 ipa_dump_agg_replacement_values (FILE *f
, struct ipa_agg_replacement_value
*av
)
4504 fprintf (f
, " Aggregate replacements:");
4505 for (; av
; av
= av
->next
)
4507 fprintf (f
, "%s %i[" HOST_WIDE_INT_PRINT_DEC
"]=", comma
? "," : "",
4508 av
->index
, av
->offset
);
4509 print_generic_expr (f
, av
->value
, 0);
4515 /* Stream out jump function JUMP_FUNC to OB. */
4518 ipa_write_jump_function (struct output_block
*ob
,
4519 struct ipa_jump_func
*jump_func
)
4521 struct ipa_agg_jf_item
*item
;
4522 struct bitpack_d bp
;
4525 streamer_write_uhwi (ob
, jump_func
->type
);
4526 switch (jump_func
->type
)
4528 case IPA_JF_UNKNOWN
:
4530 case IPA_JF_KNOWN_TYPE
:
4531 streamer_write_uhwi (ob
, jump_func
->value
.known_type
.offset
);
4532 stream_write_tree (ob
, jump_func
->value
.known_type
.base_type
, true);
4533 stream_write_tree (ob
, jump_func
->value
.known_type
.component_type
, true);
4537 EXPR_LOCATION (jump_func
->value
.constant
.value
) == UNKNOWN_LOCATION
);
4538 stream_write_tree (ob
, jump_func
->value
.constant
.value
, true);
4540 case IPA_JF_PASS_THROUGH
:
4541 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.operation
);
4542 if (jump_func
->value
.pass_through
.operation
== NOP_EXPR
)
4544 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4545 bp
= bitpack_create (ob
->main_stream
);
4546 bp_pack_value (&bp
, jump_func
->value
.pass_through
.agg_preserved
, 1);
4547 bp_pack_value (&bp
, jump_func
->value
.pass_through
.type_preserved
, 1);
4548 streamer_write_bitpack (&bp
);
4552 stream_write_tree (ob
, jump_func
->value
.pass_through
.operand
, true);
4553 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4556 case IPA_JF_ANCESTOR
:
4557 streamer_write_uhwi (ob
, jump_func
->value
.ancestor
.offset
);
4558 stream_write_tree (ob
, jump_func
->value
.ancestor
.type
, true);
4559 streamer_write_uhwi (ob
, jump_func
->value
.ancestor
.formal_id
);
4560 bp
= bitpack_create (ob
->main_stream
);
4561 bp_pack_value (&bp
, jump_func
->value
.ancestor
.agg_preserved
, 1);
4562 bp_pack_value (&bp
, jump_func
->value
.ancestor
.type_preserved
, 1);
4563 streamer_write_bitpack (&bp
);
4567 count
= vec_safe_length (jump_func
->agg
.items
);
4568 streamer_write_uhwi (ob
, count
);
4571 bp
= bitpack_create (ob
->main_stream
);
4572 bp_pack_value (&bp
, jump_func
->agg
.by_ref
, 1);
4573 streamer_write_bitpack (&bp
);
4576 FOR_EACH_VEC_SAFE_ELT (jump_func
->agg
.items
, i
, item
)
4578 streamer_write_uhwi (ob
, item
->offset
);
4579 stream_write_tree (ob
, item
->value
, true);
4583 /* Read in jump function JUMP_FUNC from IB. */
4586 ipa_read_jump_function (struct lto_input_block
*ib
,
4587 struct ipa_jump_func
*jump_func
,
4588 struct cgraph_edge
*cs
,
4589 struct data_in
*data_in
)
4591 enum jump_func_type jftype
;
4592 enum tree_code operation
;
4595 jftype
= (enum jump_func_type
) streamer_read_uhwi (ib
);
4598 case IPA_JF_UNKNOWN
:
4599 jump_func
->type
= IPA_JF_UNKNOWN
;
4601 case IPA_JF_KNOWN_TYPE
:
4603 HOST_WIDE_INT offset
= streamer_read_uhwi (ib
);
4604 tree base_type
= stream_read_tree (ib
, data_in
);
4605 tree component_type
= stream_read_tree (ib
, data_in
);
4607 ipa_set_jf_known_type (jump_func
, offset
, base_type
, component_type
);
4611 ipa_set_jf_constant (jump_func
, stream_read_tree (ib
, data_in
), cs
);
4613 case IPA_JF_PASS_THROUGH
:
4614 operation
= (enum tree_code
) streamer_read_uhwi (ib
);
4615 if (operation
== NOP_EXPR
)
4617 int formal_id
= streamer_read_uhwi (ib
);
4618 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4619 bool agg_preserved
= bp_unpack_value (&bp
, 1);
4620 bool type_preserved
= bp_unpack_value (&bp
, 1);
4621 ipa_set_jf_simple_pass_through (jump_func
, formal_id
, agg_preserved
,
4626 tree operand
= stream_read_tree (ib
, data_in
);
4627 int formal_id
= streamer_read_uhwi (ib
);
4628 ipa_set_jf_arith_pass_through (jump_func
, formal_id
, operand
,
4632 case IPA_JF_ANCESTOR
:
4634 HOST_WIDE_INT offset
= streamer_read_uhwi (ib
);
4635 tree type
= stream_read_tree (ib
, data_in
);
4636 int formal_id
= streamer_read_uhwi (ib
);
4637 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4638 bool agg_preserved
= bp_unpack_value (&bp
, 1);
4639 bool type_preserved
= bp_unpack_value (&bp
, 1);
4641 ipa_set_ancestor_jf (jump_func
, offset
, type
, formal_id
, agg_preserved
,
4647 count
= streamer_read_uhwi (ib
);
4648 vec_alloc (jump_func
->agg
.items
, count
);
4651 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4652 jump_func
->agg
.by_ref
= bp_unpack_value (&bp
, 1);
4654 for (i
= 0; i
< count
; i
++)
4656 struct ipa_agg_jf_item item
;
4657 item
.offset
= streamer_read_uhwi (ib
);
4658 item
.value
= stream_read_tree (ib
, data_in
);
4659 jump_func
->agg
.items
->quick_push (item
);
4663 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
4664 relevant to indirect inlining to OB. */
4667 ipa_write_indirect_edge_info (struct output_block
*ob
,
4668 struct cgraph_edge
*cs
)
4670 struct cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
4671 struct bitpack_d bp
;
4673 streamer_write_hwi (ob
, ii
->param_index
);
4674 streamer_write_hwi (ob
, ii
->offset
);
4675 bp
= bitpack_create (ob
->main_stream
);
4676 bp_pack_value (&bp
, ii
->polymorphic
, 1);
4677 bp_pack_value (&bp
, ii
->agg_contents
, 1);
4678 bp_pack_value (&bp
, ii
->member_ptr
, 1);
4679 bp_pack_value (&bp
, ii
->by_ref
, 1);
4680 bp_pack_value (&bp
, ii
->maybe_in_construction
, 1);
4681 bp_pack_value (&bp
, ii
->maybe_derived_type
, 1);
4682 streamer_write_bitpack (&bp
);
4684 if (ii
->polymorphic
)
4686 streamer_write_hwi (ob
, ii
->otr_token
);
4687 stream_write_tree (ob
, ii
->otr_type
, true);
4688 stream_write_tree (ob
, ii
->outer_type
, true);
4692 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
4693 relevant to indirect inlining from IB. */
4696 ipa_read_indirect_edge_info (struct lto_input_block
*ib
,
4697 struct data_in
*data_in ATTRIBUTE_UNUSED
,
4698 struct cgraph_edge
*cs
)
4700 struct cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
4701 struct bitpack_d bp
;
4703 ii
->param_index
= (int) streamer_read_hwi (ib
);
4704 ii
->offset
= (HOST_WIDE_INT
) streamer_read_hwi (ib
);
4705 bp
= streamer_read_bitpack (ib
);
4706 ii
->polymorphic
= bp_unpack_value (&bp
, 1);
4707 ii
->agg_contents
= bp_unpack_value (&bp
, 1);
4708 ii
->member_ptr
= bp_unpack_value (&bp
, 1);
4709 ii
->by_ref
= bp_unpack_value (&bp
, 1);
4710 ii
->maybe_in_construction
= bp_unpack_value (&bp
, 1);
4711 ii
->maybe_derived_type
= bp_unpack_value (&bp
, 1);
4712 if (ii
->polymorphic
)
4714 ii
->otr_token
= (HOST_WIDE_INT
) streamer_read_hwi (ib
);
4715 ii
->otr_type
= stream_read_tree (ib
, data_in
);
4716 ii
->outer_type
= stream_read_tree (ib
, data_in
);
4720 /* Stream out NODE info to OB. */
4723 ipa_write_node_info (struct output_block
*ob
, struct cgraph_node
*node
)
4726 lto_symtab_encoder_t encoder
;
4727 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
4729 struct cgraph_edge
*e
;
4730 struct bitpack_d bp
;
4732 encoder
= ob
->decl_state
->symtab_node_encoder
;
4733 node_ref
= lto_symtab_encoder_encode (encoder
, node
);
4734 streamer_write_uhwi (ob
, node_ref
);
4736 streamer_write_uhwi (ob
, ipa_get_param_count (info
));
4737 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
4738 streamer_write_uhwi (ob
, ipa_get_param_move_cost (info
, j
));
4739 bp
= bitpack_create (ob
->main_stream
);
4740 gcc_assert (info
->analysis_done
4741 || ipa_get_param_count (info
) == 0);
4742 gcc_assert (!info
->node_enqueued
);
4743 gcc_assert (!info
->ipcp_orig_node
);
4744 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
4745 bp_pack_value (&bp
, ipa_is_param_used (info
, j
), 1);
4746 streamer_write_bitpack (&bp
);
4747 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
4748 streamer_write_hwi (ob
, ipa_get_controlled_uses (info
, j
));
4749 for (e
= node
->callees
; e
; e
= e
->next_callee
)
4751 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4753 streamer_write_uhwi (ob
, ipa_get_cs_argument_count (args
));
4754 for (j
= 0; j
< ipa_get_cs_argument_count (args
); j
++)
4755 ipa_write_jump_function (ob
, ipa_get_ith_jump_func (args
, j
));
4757 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
4759 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4761 streamer_write_uhwi (ob
, ipa_get_cs_argument_count (args
));
4762 for (j
= 0; j
< ipa_get_cs_argument_count (args
); j
++)
4763 ipa_write_jump_function (ob
, ipa_get_ith_jump_func (args
, j
));
4764 ipa_write_indirect_edge_info (ob
, e
);
4768 /* Stream in NODE info from IB. */
4771 ipa_read_node_info (struct lto_input_block
*ib
, struct cgraph_node
*node
,
4772 struct data_in
*data_in
)
4774 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
4776 struct cgraph_edge
*e
;
4777 struct bitpack_d bp
;
4779 ipa_alloc_node_params (node
, streamer_read_uhwi (ib
));
4781 for (k
= 0; k
< ipa_get_param_count (info
); k
++)
4782 info
->descriptors
[k
].move_cost
= streamer_read_uhwi (ib
);
4784 bp
= streamer_read_bitpack (ib
);
4785 if (ipa_get_param_count (info
) != 0)
4786 info
->analysis_done
= true;
4787 info
->node_enqueued
= false;
4788 for (k
= 0; k
< ipa_get_param_count (info
); k
++)
4789 ipa_set_param_used (info
, k
, bp_unpack_value (&bp
, 1));
4790 for (k
= 0; k
< ipa_get_param_count (info
); k
++)
4791 ipa_set_controlled_uses (info
, k
, streamer_read_hwi (ib
));
4792 for (e
= node
->callees
; e
; e
= e
->next_callee
)
4794 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4795 int count
= streamer_read_uhwi (ib
);
4799 vec_safe_grow_cleared (args
->jump_functions
, count
);
4801 for (k
= 0; k
< ipa_get_cs_argument_count (args
); k
++)
4802 ipa_read_jump_function (ib
, ipa_get_ith_jump_func (args
, k
), e
,
4805 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
4807 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4808 int count
= streamer_read_uhwi (ib
);
4812 vec_safe_grow_cleared (args
->jump_functions
, count
);
4813 for (k
= 0; k
< ipa_get_cs_argument_count (args
); k
++)
4814 ipa_read_jump_function (ib
, ipa_get_ith_jump_func (args
, k
), e
,
4817 ipa_read_indirect_edge_info (ib
, data_in
, e
);
4821 /* Write jump functions for nodes in SET. */
4824 ipa_prop_write_jump_functions (void)
4826 struct cgraph_node
*node
;
4827 struct output_block
*ob
;
4828 unsigned int count
= 0;
4829 lto_symtab_encoder_iterator lsei
;
4830 lto_symtab_encoder_t encoder
;
4833 if (!ipa_node_params_vector
.exists ())
4836 ob
= create_output_block (LTO_section_jump_functions
);
4837 encoder
= ob
->decl_state
->symtab_node_encoder
;
4838 ob
->cgraph_node
= NULL
;
4839 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
4840 lsei_next_function_in_partition (&lsei
))
4842 node
= lsei_cgraph_node (lsei
);
4843 if (cgraph_function_with_gimple_body_p (node
)
4844 && IPA_NODE_REF (node
) != NULL
)
4848 streamer_write_uhwi (ob
, count
);
4850 /* Process all of the functions. */
4851 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
4852 lsei_next_function_in_partition (&lsei
))
4854 node
= lsei_cgraph_node (lsei
);
4855 if (cgraph_function_with_gimple_body_p (node
)
4856 && IPA_NODE_REF (node
) != NULL
)
4857 ipa_write_node_info (ob
, node
);
4859 streamer_write_char_stream (ob
->main_stream
, 0);
4860 produce_asm (ob
, NULL
);
4861 destroy_output_block (ob
);
4864 /* Read section in file FILE_DATA of length LEN with data DATA. */
4867 ipa_prop_read_section (struct lto_file_decl_data
*file_data
, const char *data
,
4870 const struct lto_function_header
*header
=
4871 (const struct lto_function_header
*) data
;
4872 const int cfg_offset
= sizeof (struct lto_function_header
);
4873 const int main_offset
= cfg_offset
+ header
->cfg_size
;
4874 const int string_offset
= main_offset
+ header
->main_size
;
4875 struct data_in
*data_in
;
4876 struct lto_input_block ib_main
;
4880 LTO_INIT_INPUT_BLOCK (ib_main
, (const char *) data
+ main_offset
, 0,
4884 lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
4885 header
->string_size
, vNULL
);
4886 count
= streamer_read_uhwi (&ib_main
);
4888 for (i
= 0; i
< count
; i
++)
4891 struct cgraph_node
*node
;
4892 lto_symtab_encoder_t encoder
;
4894 index
= streamer_read_uhwi (&ib_main
);
4895 encoder
= file_data
->symtab_node_encoder
;
4896 node
= cgraph (lto_symtab_encoder_deref (encoder
, index
));
4897 gcc_assert (node
->definition
);
4898 ipa_read_node_info (&ib_main
, node
, data_in
);
4900 lto_free_section_data (file_data
, LTO_section_jump_functions
, NULL
, data
,
4902 lto_data_in_delete (data_in
);
4905 /* Read ipcp jump functions. */
4908 ipa_prop_read_jump_functions (void)
4910 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
4911 struct lto_file_decl_data
*file_data
;
4914 ipa_check_create_node_params ();
4915 ipa_check_create_edge_args ();
4916 ipa_register_cgraph_hooks ();
4918 while ((file_data
= file_data_vec
[j
++]))
4921 const char *data
= lto_get_section_data (file_data
, LTO_section_jump_functions
, NULL
, &len
);
4924 ipa_prop_read_section (file_data
, data
, len
);
4928 /* After merging units, we can get mismatch in argument counts.
4929 Also decl merging might've rendered parameter lists obsolete.
4930 Also compute called_with_variable_arg info. */
4933 ipa_update_after_lto_read (void)
4935 ipa_check_create_node_params ();
4936 ipa_check_create_edge_args ();
4940 write_agg_replacement_chain (struct output_block
*ob
, struct cgraph_node
*node
)
4943 unsigned int count
= 0;
4944 lto_symtab_encoder_t encoder
;
4945 struct ipa_agg_replacement_value
*aggvals
, *av
;
4947 aggvals
= ipa_get_agg_replacements_for_node (node
);
4948 encoder
= ob
->decl_state
->symtab_node_encoder
;
4949 node_ref
= lto_symtab_encoder_encode (encoder
, node
);
4950 streamer_write_uhwi (ob
, node_ref
);
4952 for (av
= aggvals
; av
; av
= av
->next
)
4954 streamer_write_uhwi (ob
, count
);
4956 for (av
= aggvals
; av
; av
= av
->next
)
4958 struct bitpack_d bp
;
4960 streamer_write_uhwi (ob
, av
->offset
);
4961 streamer_write_uhwi (ob
, av
->index
);
4962 stream_write_tree (ob
, av
->value
, true);
4964 bp
= bitpack_create (ob
->main_stream
);
4965 bp_pack_value (&bp
, av
->by_ref
, 1);
4966 streamer_write_bitpack (&bp
);
4970 /* Stream in the aggregate value replacement chain for NODE from IB. */
4973 read_agg_replacement_chain (struct lto_input_block
*ib
,
4974 struct cgraph_node
*node
,
4975 struct data_in
*data_in
)
4977 struct ipa_agg_replacement_value
*aggvals
= NULL
;
4978 unsigned int count
, i
;
4980 count
= streamer_read_uhwi (ib
);
4981 for (i
= 0; i
<count
; i
++)
4983 struct ipa_agg_replacement_value
*av
;
4984 struct bitpack_d bp
;
4986 av
= ggc_alloc
<ipa_agg_replacement_value
> ();
4987 av
->offset
= streamer_read_uhwi (ib
);
4988 av
->index
= streamer_read_uhwi (ib
);
4989 av
->value
= stream_read_tree (ib
, data_in
);
4990 bp
= streamer_read_bitpack (ib
);
4991 av
->by_ref
= bp_unpack_value (&bp
, 1);
4995 ipa_set_node_agg_value_chain (node
, aggvals
);
4998 /* Write all aggregate replacement for nodes in set. */
5001 ipa_prop_write_all_agg_replacement (void)
5003 struct cgraph_node
*node
;
5004 struct output_block
*ob
;
5005 unsigned int count
= 0;
5006 lto_symtab_encoder_iterator lsei
;
5007 lto_symtab_encoder_t encoder
;
5009 if (!ipa_node_agg_replacements
)
5012 ob
= create_output_block (LTO_section_ipcp_transform
);
5013 encoder
= ob
->decl_state
->symtab_node_encoder
;
5014 ob
->cgraph_node
= NULL
;
5015 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5016 lsei_next_function_in_partition (&lsei
))
5018 node
= lsei_cgraph_node (lsei
);
5019 if (cgraph_function_with_gimple_body_p (node
)
5020 && ipa_get_agg_replacements_for_node (node
) != NULL
)
5024 streamer_write_uhwi (ob
, count
);
5026 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5027 lsei_next_function_in_partition (&lsei
))
5029 node
= lsei_cgraph_node (lsei
);
5030 if (cgraph_function_with_gimple_body_p (node
)
5031 && ipa_get_agg_replacements_for_node (node
) != NULL
)
5032 write_agg_replacement_chain (ob
, node
);
5034 streamer_write_char_stream (ob
->main_stream
, 0);
5035 produce_asm (ob
, NULL
);
5036 destroy_output_block (ob
);
5039 /* Read replacements section in file FILE_DATA of length LEN with data
5043 read_replacements_section (struct lto_file_decl_data
*file_data
,
5047 const struct lto_function_header
*header
=
5048 (const struct lto_function_header
*) data
;
5049 const int cfg_offset
= sizeof (struct lto_function_header
);
5050 const int main_offset
= cfg_offset
+ header
->cfg_size
;
5051 const int string_offset
= main_offset
+ header
->main_size
;
5052 struct data_in
*data_in
;
5053 struct lto_input_block ib_main
;
5057 LTO_INIT_INPUT_BLOCK (ib_main
, (const char *) data
+ main_offset
, 0,
5060 data_in
= lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
5061 header
->string_size
, vNULL
);
5062 count
= streamer_read_uhwi (&ib_main
);
5064 for (i
= 0; i
< count
; i
++)
5067 struct cgraph_node
*node
;
5068 lto_symtab_encoder_t encoder
;
5070 index
= streamer_read_uhwi (&ib_main
);
5071 encoder
= file_data
->symtab_node_encoder
;
5072 node
= cgraph (lto_symtab_encoder_deref (encoder
, index
));
5073 gcc_assert (node
->definition
);
5074 read_agg_replacement_chain (&ib_main
, node
, data_in
);
5076 lto_free_section_data (file_data
, LTO_section_jump_functions
, NULL
, data
,
5078 lto_data_in_delete (data_in
);
5081 /* Read IPA-CP aggregate replacements. */
5084 ipa_prop_read_all_agg_replacement (void)
5086 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
5087 struct lto_file_decl_data
*file_data
;
5090 while ((file_data
= file_data_vec
[j
++]))
5093 const char *data
= lto_get_section_data (file_data
,
5094 LTO_section_ipcp_transform
,
5097 read_replacements_section (file_data
, data
, len
);
5101 /* Adjust the aggregate replacements in AGGVAL to reflect parameters skipped in
5105 adjust_agg_replacement_values (struct cgraph_node
*node
,
5106 struct ipa_agg_replacement_value
*aggval
)
5108 struct ipa_agg_replacement_value
*v
;
5109 int i
, c
= 0, d
= 0, *adj
;
5111 if (!node
->clone
.combined_args_to_skip
)
5114 for (v
= aggval
; v
; v
= v
->next
)
5116 gcc_assert (v
->index
>= 0);
5122 adj
= XALLOCAVEC (int, c
);
5123 for (i
= 0; i
< c
; i
++)
5124 if (bitmap_bit_p (node
->clone
.combined_args_to_skip
, i
))
5132 for (v
= aggval
; v
; v
= v
->next
)
5133 v
->index
= adj
[v
->index
];
5136 /* Dominator walker driving the ipcp modification phase. */
5138 class ipcp_modif_dom_walker
: public dom_walker
5141 ipcp_modif_dom_walker (struct func_body_info
*fbi
,
5142 vec
<ipa_param_descriptor
> descs
,
5143 struct ipa_agg_replacement_value
*av
,
5145 : dom_walker (CDI_DOMINATORS
), m_fbi (fbi
), m_descriptors (descs
),
5146 m_aggval (av
), m_something_changed (sc
), m_cfg_changed (cc
) {}
5148 virtual void before_dom_children (basic_block
);
5151 struct func_body_info
*m_fbi
;
5152 vec
<ipa_param_descriptor
> m_descriptors
;
5153 struct ipa_agg_replacement_value
*m_aggval
;
5154 bool *m_something_changed
, *m_cfg_changed
;
5158 ipcp_modif_dom_walker::before_dom_children (basic_block bb
)
5160 gimple_stmt_iterator gsi
;
5161 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
5163 struct ipa_agg_replacement_value
*v
;
5164 gimple stmt
= gsi_stmt (gsi
);
5166 HOST_WIDE_INT offset
, size
;
5170 if (!gimple_assign_load_p (stmt
))
5172 rhs
= gimple_assign_rhs1 (stmt
);
5173 if (!is_gimple_reg_type (TREE_TYPE (rhs
)))
5178 while (handled_component_p (t
))
5180 /* V_C_E can do things like convert an array of integers to one
5181 bigger integer and similar things we do not handle below. */
5182 if (TREE_CODE (rhs
) == VIEW_CONVERT_EXPR
)
5187 t
= TREE_OPERAND (t
, 0);
5192 if (!ipa_load_from_parm_agg_1 (m_fbi
, m_descriptors
, stmt
, rhs
, &index
,
5193 &offset
, &size
, &by_ref
))
5195 for (v
= m_aggval
; v
; v
= v
->next
)
5196 if (v
->index
== index
5197 && v
->offset
== offset
)
5200 || v
->by_ref
!= by_ref
5201 || tree_to_shwi (TYPE_SIZE (TREE_TYPE (v
->value
))) != size
)
5204 gcc_checking_assert (is_gimple_ip_invariant (v
->value
));
5205 if (!useless_type_conversion_p (TREE_TYPE (rhs
), TREE_TYPE (v
->value
)))
5207 if (fold_convertible_p (TREE_TYPE (rhs
), v
->value
))
5208 val
= fold_build1 (NOP_EXPR
, TREE_TYPE (rhs
), v
->value
);
5209 else if (TYPE_SIZE (TREE_TYPE (rhs
))
5210 == TYPE_SIZE (TREE_TYPE (v
->value
)))
5211 val
= fold_build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (rhs
), v
->value
);
5216 fprintf (dump_file
, " const ");
5217 print_generic_expr (dump_file
, v
->value
, 0);
5218 fprintf (dump_file
, " can't be converted to type of ");
5219 print_generic_expr (dump_file
, rhs
, 0);
5220 fprintf (dump_file
, "\n");
5228 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5230 fprintf (dump_file
, "Modifying stmt:\n ");
5231 print_gimple_stmt (dump_file
, stmt
, 0, 0);
5233 gimple_assign_set_rhs_from_tree (&gsi
, val
);
5236 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5238 fprintf (dump_file
, "into:\n ");
5239 print_gimple_stmt (dump_file
, stmt
, 0, 0);
5240 fprintf (dump_file
, "\n");
5243 *m_something_changed
= true;
5244 if (maybe_clean_eh_stmt (stmt
)
5245 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
5246 *m_cfg_changed
= true;
5251 /* IPCP transformation phase doing propagation of aggregate values. */
5254 ipcp_transform_function (struct cgraph_node
*node
)
5256 vec
<ipa_param_descriptor
> descriptors
= vNULL
;
5257 struct func_body_info fbi
;
5258 struct ipa_agg_replacement_value
*aggval
;
5260 bool cfg_changed
= false, something_changed
= false;
5262 gcc_checking_assert (cfun
);
5263 gcc_checking_assert (current_function_decl
);
5266 fprintf (dump_file
, "Modification phase of node %s/%i\n",
5267 node
->name (), node
->order
);
5269 aggval
= ipa_get_agg_replacements_for_node (node
);
5272 param_count
= count_formal_params (node
->decl
);
5273 if (param_count
== 0)
5275 adjust_agg_replacement_values (node
, aggval
);
5277 ipa_dump_agg_replacement_values (dump_file
, aggval
);
5281 fbi
.bb_infos
= vNULL
;
5282 fbi
.bb_infos
.safe_grow_cleared (last_basic_block_for_fn (cfun
));
5283 fbi
.param_count
= param_count
;
5286 descriptors
.safe_grow_cleared (param_count
);
5287 ipa_populate_param_decls (node
, descriptors
);
5288 calculate_dominance_info (CDI_DOMINATORS
);
5289 ipcp_modif_dom_walker (&fbi
, descriptors
, aggval
, &something_changed
,
5290 &cfg_changed
).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
5293 struct ipa_bb_info
*bi
;
5294 FOR_EACH_VEC_ELT (fbi
.bb_infos
, i
, bi
)
5295 free_ipa_bb_info (bi
);
5296 fbi
.bb_infos
.release ();
5297 free_dominance_info (CDI_DOMINATORS
);
5298 (*ipa_node_agg_replacements
)[node
->uid
] = NULL
;
5299 descriptors
.release ();
5301 if (!something_changed
)
5303 else if (cfg_changed
)
5304 return TODO_update_ssa_only_virtuals
| TODO_cleanup_cfg
;
5306 return TODO_update_ssa_only_virtuals
;