1 /* Interprocedural analyses.
2 Copyright (C) 2005-2021 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"
27 #include "alloc-pool.h"
28 #include "tree-pass.h"
30 #include "tree-streamer.h"
32 #include "diagnostic.h"
33 #include "fold-const.h"
34 #include "gimple-fold.h"
37 #include "stor-layout.h"
38 #include "print-tree.h"
40 #include "gimple-iterator.h"
41 #include "gimplify-me.h"
42 #include "gimple-walk.h"
43 #include "symbol-summary.h"
47 #include "tree-inline.h"
48 #include "ipa-fnsummary.h"
49 #include "gimple-pretty-print.h"
50 #include "ipa-utils.h"
54 #include "tree-cfgcleanup.h"
56 #include "symtab-clones.h"
57 #include "attr-fnspec.h"
58 #include "gimple-range.h"
60 /* Function summary where the parameter infos are actually stored. */
61 ipa_node_params_t
*ipa_node_params_sum
= NULL
;
63 function_summary
<ipcp_transformation
*> *ipcp_transformation_sum
= NULL
;
65 /* Edge summary for IPA-CP edge information. */
66 ipa_edge_args_sum_t
*ipa_edge_args_sum
;
68 /* Traits for a hash table for reusing already existing ipa_bits. */
70 struct ipa_bit_ggc_hash_traits
: public ggc_cache_remove
<ipa_bits
*>
72 typedef ipa_bits
*value_type
;
73 typedef ipa_bits
*compare_type
;
75 hash (const ipa_bits
*p
)
77 hashval_t t
= (hashval_t
) p
->value
.to_shwi ();
78 return iterative_hash_host_wide_int (p
->mask
.to_shwi (), t
);
81 equal (const ipa_bits
*a
, const ipa_bits
*b
)
83 return a
->value
== b
->value
&& a
->mask
== b
->mask
;
85 static const bool empty_zero_p
= true;
87 mark_empty (ipa_bits
*&p
)
92 is_empty (const ipa_bits
*p
)
97 is_deleted (const ipa_bits
*p
)
99 return p
== reinterpret_cast<const ipa_bits
*> (1);
102 mark_deleted (ipa_bits
*&p
)
104 p
= reinterpret_cast<ipa_bits
*> (1);
108 /* Hash table for avoid repeated allocations of equal ipa_bits. */
109 static GTY ((cache
)) hash_table
<ipa_bit_ggc_hash_traits
> *ipa_bits_hash_table
;
111 /* Traits for a hash table for reusing value_ranges used for IPA. Note that
112 the equiv bitmap is not hashed and is expected to be NULL. */
114 struct ipa_vr_ggc_hash_traits
: public ggc_cache_remove
<value_range
*>
116 typedef value_range
*value_type
;
117 typedef value_range
*compare_type
;
119 hash (const value_range
*p
)
121 inchash::hash
hstate (p
->kind ());
122 inchash::add_expr (p
->min (), hstate
);
123 inchash::add_expr (p
->max (), hstate
);
124 return hstate
.end ();
127 equal (const value_range
*a
, const value_range
*b
)
129 return (a
->equal_p (*b
)
130 && types_compatible_p (a
->type (), b
->type ()));
132 static const bool empty_zero_p
= true;
134 mark_empty (value_range
*&p
)
139 is_empty (const value_range
*p
)
144 is_deleted (const value_range
*p
)
146 return p
== reinterpret_cast<const value_range
*> (1);
149 mark_deleted (value_range
*&p
)
151 p
= reinterpret_cast<value_range
*> (1);
155 /* Hash table for avoid repeated allocations of equal value_ranges. */
156 static GTY ((cache
)) hash_table
<ipa_vr_ggc_hash_traits
> *ipa_vr_hash_table
;
158 /* Holders of ipa cgraph hooks: */
159 static struct cgraph_node_hook_list
*function_insertion_hook_holder
;
161 /* Description of a reference to an IPA constant. */
162 struct ipa_cst_ref_desc
164 /* Edge that corresponds to the statement which took the reference. */
165 struct cgraph_edge
*cs
;
166 /* Linked list of duplicates created when call graph edges are cloned. */
167 struct ipa_cst_ref_desc
*next_duplicate
;
168 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
169 if out of control. */
173 /* Allocation pool for reference descriptions. */
175 static object_allocator
<ipa_cst_ref_desc
> ipa_refdesc_pool
176 ("IPA-PROP ref descriptions");
178 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
179 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
182 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node
*node
)
184 tree fs_opts
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node
->decl
);
188 return !opt_for_fn (node
->decl
, optimize
) || !opt_for_fn (node
->decl
, flag_ipa_cp
);
191 /* Return index of the formal whose tree is PTREE in function which corresponds
195 ipa_get_param_decl_index_1 (vec
<ipa_param_descriptor
, va_gc
> *descriptors
,
200 count
= vec_safe_length (descriptors
);
201 for (i
= 0; i
< count
; i
++)
202 if ((*descriptors
)[i
].decl_or_type
== ptree
)
208 /* Return index of the formal whose tree is PTREE in function which corresponds
212 ipa_get_param_decl_index (class ipa_node_params
*info
, tree ptree
)
214 return ipa_get_param_decl_index_1 (info
->descriptors
, ptree
);
217 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
221 ipa_populate_param_decls (struct cgraph_node
*node
,
222 vec
<ipa_param_descriptor
, va_gc
> &descriptors
)
230 gcc_assert (gimple_has_body_p (fndecl
));
231 fnargs
= DECL_ARGUMENTS (fndecl
);
233 for (parm
= fnargs
; parm
; parm
= DECL_CHAIN (parm
))
235 descriptors
[param_num
].decl_or_type
= parm
;
236 unsigned int cost
= estimate_move_cost (TREE_TYPE (parm
), true);
237 descriptors
[param_num
].move_cost
= cost
;
238 /* Watch overflow, move_cost is a bitfield. */
239 gcc_checking_assert (cost
== descriptors
[param_num
].move_cost
);
244 /* Return how many formal parameters FNDECL has. */
247 count_formal_params (tree fndecl
)
251 gcc_assert (gimple_has_body_p (fndecl
));
253 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
259 /* Return the declaration of Ith formal parameter of the function corresponding
260 to INFO. Note there is no setter function as this array is built just once
261 using ipa_initialize_node_params. */
264 ipa_dump_param (FILE *file
, class ipa_node_params
*info
, int i
)
266 fprintf (file
, "param #%i", i
);
267 if ((*info
->descriptors
)[i
].decl_or_type
)
270 print_generic_expr (file
, (*info
->descriptors
)[i
].decl_or_type
);
274 /* If necessary, allocate vector of parameter descriptors in info of NODE.
275 Return true if they were allocated, false if not. */
278 ipa_alloc_node_params (struct cgraph_node
*node
, int param_count
)
280 ipa_node_params
*info
= ipa_node_params_sum
->get_create (node
);
282 if (!info
->descriptors
&& param_count
)
284 vec_safe_grow_cleared (info
->descriptors
, param_count
, true);
291 /* Initialize the ipa_node_params structure associated with NODE by counting
292 the function parameters, creating the descriptors and populating their
296 ipa_initialize_node_params (struct cgraph_node
*node
)
298 ipa_node_params
*info
= ipa_node_params_sum
->get_create (node
);
300 if (!info
->descriptors
301 && ipa_alloc_node_params (node
, count_formal_params (node
->decl
)))
302 ipa_populate_param_decls (node
, *info
->descriptors
);
305 /* Print the jump functions associated with call graph edge CS to file F. */
308 ipa_print_node_jump_functions_for_edge (FILE *f
, struct cgraph_edge
*cs
)
310 ipa_edge_args
*args
= ipa_edge_args_sum
->get (cs
);
311 int count
= ipa_get_cs_argument_count (args
);
313 for (int i
= 0; i
< count
; i
++)
315 struct ipa_jump_func
*jump_func
;
316 enum jump_func_type type
;
318 jump_func
= ipa_get_ith_jump_func (args
, i
);
319 type
= jump_func
->type
;
321 fprintf (f
, " param %d: ", i
);
322 if (type
== IPA_JF_UNKNOWN
)
323 fprintf (f
, "UNKNOWN\n");
324 else if (type
== IPA_JF_CONST
)
326 tree val
= jump_func
->value
.constant
.value
;
327 fprintf (f
, "CONST: ");
328 print_generic_expr (f
, val
);
329 if (TREE_CODE (val
) == ADDR_EXPR
330 && TREE_CODE (TREE_OPERAND (val
, 0)) == CONST_DECL
)
333 print_generic_expr (f
, DECL_INITIAL (TREE_OPERAND (val
, 0)));
337 else if (type
== IPA_JF_PASS_THROUGH
)
339 fprintf (f
, "PASS THROUGH: ");
340 fprintf (f
, "%d, op %s",
341 jump_func
->value
.pass_through
.formal_id
,
342 get_tree_code_name(jump_func
->value
.pass_through
.operation
));
343 if (jump_func
->value
.pass_through
.operation
!= NOP_EXPR
)
346 print_generic_expr (f
, jump_func
->value
.pass_through
.operand
);
348 if (jump_func
->value
.pass_through
.agg_preserved
)
349 fprintf (f
, ", agg_preserved");
352 else if (type
== IPA_JF_ANCESTOR
)
354 fprintf (f
, "ANCESTOR: ");
355 fprintf (f
, "%d, offset " HOST_WIDE_INT_PRINT_DEC
,
356 jump_func
->value
.ancestor
.formal_id
,
357 jump_func
->value
.ancestor
.offset
);
358 if (jump_func
->value
.ancestor
.agg_preserved
)
359 fprintf (f
, ", agg_preserved");
363 if (jump_func
->agg
.items
)
365 struct ipa_agg_jf_item
*item
;
368 fprintf (f
, " Aggregate passed by %s:\n",
369 jump_func
->agg
.by_ref
? "reference" : "value");
370 FOR_EACH_VEC_ELT (*jump_func
->agg
.items
, j
, item
)
372 fprintf (f
, " offset: " HOST_WIDE_INT_PRINT_DEC
", ",
374 fprintf (f
, "type: ");
375 print_generic_expr (f
, item
->type
);
377 if (item
->jftype
== IPA_JF_PASS_THROUGH
)
378 fprintf (f
, "PASS THROUGH: %d,",
379 item
->value
.pass_through
.formal_id
);
380 else if (item
->jftype
== IPA_JF_LOAD_AGG
)
382 fprintf (f
, "LOAD AGG: %d",
383 item
->value
.pass_through
.formal_id
);
384 fprintf (f
, " [offset: " HOST_WIDE_INT_PRINT_DEC
", by %s],",
385 item
->value
.load_agg
.offset
,
386 item
->value
.load_agg
.by_ref
? "reference"
390 if (item
->jftype
== IPA_JF_PASS_THROUGH
391 || item
->jftype
== IPA_JF_LOAD_AGG
)
393 fprintf (f
, " op %s",
394 get_tree_code_name (item
->value
.pass_through
.operation
));
395 if (item
->value
.pass_through
.operation
!= NOP_EXPR
)
398 print_generic_expr (f
, item
->value
.pass_through
.operand
);
401 else if (item
->jftype
== IPA_JF_CONST
)
403 fprintf (f
, "CONST: ");
404 print_generic_expr (f
, item
->value
.constant
);
406 else if (item
->jftype
== IPA_JF_UNKNOWN
)
407 fprintf (f
, "UNKNOWN: " HOST_WIDE_INT_PRINT_DEC
" bits",
408 tree_to_uhwi (TYPE_SIZE (item
->type
)));
413 class ipa_polymorphic_call_context
*ctx
414 = ipa_get_ith_polymorhic_call_context (args
, i
);
415 if (ctx
&& !ctx
->useless_p ())
417 fprintf (f
, " Context: ");
418 ctx
->dump (dump_file
);
423 fprintf (f
, " value: ");
424 print_hex (jump_func
->bits
->value
, f
);
425 fprintf (f
, ", mask: ");
426 print_hex (jump_func
->bits
->mask
, f
);
430 fprintf (f
, " Unknown bits\n");
436 (jump_func
->m_vr
->kind () == VR_ANTI_RANGE
) ? "~" : "");
437 print_decs (wi::to_wide (jump_func
->m_vr
->min ()), f
);
439 print_decs (wi::to_wide (jump_func
->m_vr
->max ()), f
);
443 fprintf (f
, " Unknown VR\n");
448 /* Print the jump functions of all arguments on all call graph edges going from
452 ipa_print_node_jump_functions (FILE *f
, struct cgraph_node
*node
)
454 struct cgraph_edge
*cs
;
456 fprintf (f
, " Jump functions of caller %s:\n", node
->dump_name ());
457 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
460 fprintf (f
, " callsite %s -> %s : \n",
462 cs
->callee
->dump_name ());
463 if (!ipa_edge_args_info_available_for_edge_p (cs
))
464 fprintf (f
, " no arg info\n");
466 ipa_print_node_jump_functions_for_edge (f
, cs
);
469 for (cs
= node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
471 class cgraph_indirect_call_info
*ii
;
473 ii
= cs
->indirect_info
;
474 if (ii
->agg_contents
)
475 fprintf (f
, " indirect %s callsite, calling param %i, "
476 "offset " HOST_WIDE_INT_PRINT_DEC
", %s",
477 ii
->member_ptr
? "member ptr" : "aggregate",
478 ii
->param_index
, ii
->offset
,
479 ii
->by_ref
? "by reference" : "by_value");
481 fprintf (f
, " indirect %s callsite, calling param %i, "
482 "offset " HOST_WIDE_INT_PRINT_DEC
,
483 ii
->polymorphic
? "polymorphic" : "simple", ii
->param_index
,
488 fprintf (f
, ", for stmt ");
489 print_gimple_stmt (f
, cs
->call_stmt
, 0, TDF_SLIM
);
494 ii
->context
.dump (f
);
495 if (!ipa_edge_args_info_available_for_edge_p (cs
))
496 fprintf (f
, " no arg info\n");
498 ipa_print_node_jump_functions_for_edge (f
, cs
);
502 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
505 ipa_print_all_jump_functions (FILE *f
)
507 struct cgraph_node
*node
;
509 fprintf (f
, "\nJump functions:\n");
510 FOR_EACH_FUNCTION (node
)
512 ipa_print_node_jump_functions (f
, node
);
516 /* Set jfunc to be a know-really nothing jump function. */
519 ipa_set_jf_unknown (struct ipa_jump_func
*jfunc
)
521 jfunc
->type
= IPA_JF_UNKNOWN
;
524 /* Set JFUNC to be a copy of another jmp (to be used by jump function
525 combination code). The two functions will share their rdesc. */
528 ipa_set_jf_cst_copy (struct ipa_jump_func
*dst
,
529 struct ipa_jump_func
*src
)
532 gcc_checking_assert (src
->type
== IPA_JF_CONST
);
533 dst
->type
= IPA_JF_CONST
;
534 dst
->value
.constant
= src
->value
.constant
;
537 /* Set JFUNC to be a constant jmp function. */
540 ipa_set_jf_constant (struct ipa_jump_func
*jfunc
, tree constant
,
541 struct cgraph_edge
*cs
)
543 jfunc
->type
= IPA_JF_CONST
;
544 jfunc
->value
.constant
.value
= unshare_expr_without_location (constant
);
546 if (TREE_CODE (constant
) == ADDR_EXPR
547 && (TREE_CODE (TREE_OPERAND (constant
, 0)) == FUNCTION_DECL
548 || (TREE_CODE (TREE_OPERAND (constant
, 0)) == VAR_DECL
549 && TREE_STATIC (TREE_OPERAND (constant
, 0)))))
551 struct ipa_cst_ref_desc
*rdesc
;
553 rdesc
= ipa_refdesc_pool
.allocate ();
555 rdesc
->next_duplicate
= NULL
;
557 jfunc
->value
.constant
.rdesc
= rdesc
;
560 jfunc
->value
.constant
.rdesc
= NULL
;
563 /* Set JFUNC to be a simple pass-through jump function. */
565 ipa_set_jf_simple_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
568 jfunc
->type
= IPA_JF_PASS_THROUGH
;
569 jfunc
->value
.pass_through
.operand
= NULL_TREE
;
570 jfunc
->value
.pass_through
.formal_id
= formal_id
;
571 jfunc
->value
.pass_through
.operation
= NOP_EXPR
;
572 jfunc
->value
.pass_through
.agg_preserved
= agg_preserved
;
575 /* Set JFUNC to be an unary pass through jump function. */
578 ipa_set_jf_unary_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
579 enum tree_code operation
)
581 jfunc
->type
= IPA_JF_PASS_THROUGH
;
582 jfunc
->value
.pass_through
.operand
= NULL_TREE
;
583 jfunc
->value
.pass_through
.formal_id
= formal_id
;
584 jfunc
->value
.pass_through
.operation
= operation
;
585 jfunc
->value
.pass_through
.agg_preserved
= false;
587 /* Set JFUNC to be an arithmetic pass through jump function. */
590 ipa_set_jf_arith_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
591 tree operand
, enum tree_code operation
)
593 jfunc
->type
= IPA_JF_PASS_THROUGH
;
594 jfunc
->value
.pass_through
.operand
= unshare_expr_without_location (operand
);
595 jfunc
->value
.pass_through
.formal_id
= formal_id
;
596 jfunc
->value
.pass_through
.operation
= operation
;
597 jfunc
->value
.pass_through
.agg_preserved
= false;
600 /* Set JFUNC to be an ancestor jump function. */
603 ipa_set_ancestor_jf (struct ipa_jump_func
*jfunc
, HOST_WIDE_INT offset
,
604 int formal_id
, bool agg_preserved
)
606 jfunc
->type
= IPA_JF_ANCESTOR
;
607 jfunc
->value
.ancestor
.formal_id
= formal_id
;
608 jfunc
->value
.ancestor
.offset
= offset
;
609 jfunc
->value
.ancestor
.agg_preserved
= agg_preserved
;
612 /* Get IPA BB information about the given BB. FBI is the context of analyzis
613 of this function body. */
615 static struct ipa_bb_info
*
616 ipa_get_bb_info (struct ipa_func_body_info
*fbi
, basic_block bb
)
618 gcc_checking_assert (fbi
);
619 return &fbi
->bb_infos
[bb
->index
];
622 /* Structure to be passed in between detect_type_change and
623 check_stmt_for_type_change. */
625 struct prop_type_change_info
627 /* Offset into the object where there is the virtual method pointer we are
629 HOST_WIDE_INT offset
;
630 /* The declaration or SSA_NAME pointer of the base that we are checking for
633 /* Set to true if dynamic type change has been detected. */
634 bool type_maybe_changed
;
637 /* Return true if STMT can modify a virtual method table pointer.
639 This function makes special assumptions about both constructors and
640 destructors which are all the functions that are allowed to alter the VMT
641 pointers. It assumes that destructors begin with assignment into all VMT
642 pointers and that constructors essentially look in the following way:
644 1) The very first thing they do is that they call constructors of ancestor
645 sub-objects that have them.
647 2) Then VMT pointers of this and all its ancestors is set to new values
648 corresponding to the type corresponding to the constructor.
650 3) Only afterwards, other stuff such as constructor of member sub-objects
651 and the code written by the user is run. Only this may include calling
652 virtual functions, directly or indirectly.
654 There is no way to call a constructor of an ancestor sub-object in any
657 This means that we do not have to care whether constructors get the correct
658 type information because they will always change it (in fact, if we define
659 the type to be given by the VMT pointer, it is undefined).
661 The most important fact to derive from the above is that if, for some
662 statement in the section 3, we try to detect whether the dynamic type has
663 changed, we can safely ignore all calls as we examine the function body
664 backwards until we reach statements in section 2 because these calls cannot
665 be ancestor constructors or destructors (if the input is not bogus) and so
666 do not change the dynamic type (this holds true only for automatically
667 allocated objects but at the moment we devirtualize only these). We then
668 must detect that statements in section 2 change the dynamic type and can try
669 to derive the new type. That is enough and we can stop, we will never see
670 the calls into constructors of sub-objects in this code. Therefore we can
671 safely ignore all call statements that we traverse.
675 stmt_may_be_vtbl_ptr_store (gimple
*stmt
)
677 if (is_gimple_call (stmt
))
679 if (gimple_clobber_p (stmt
))
681 else if (is_gimple_assign (stmt
))
683 tree lhs
= gimple_assign_lhs (stmt
);
685 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs
)))
687 if (flag_strict_aliasing
688 && !POINTER_TYPE_P (TREE_TYPE (lhs
)))
691 if (TREE_CODE (lhs
) == COMPONENT_REF
692 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs
, 1)))
694 /* In the future we might want to use get_ref_base_and_extent to find
695 if there is a field corresponding to the offset and if so, proceed
696 almost like if it was a component ref. */
702 /* Callback of walk_aliased_vdefs and a helper function for detect_type_change
703 to check whether a particular statement may modify the virtual table
704 pointerIt stores its result into DATA, which points to a
705 prop_type_change_info structure. */
708 check_stmt_for_type_change (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef
, void *data
)
710 gimple
*stmt
= SSA_NAME_DEF_STMT (vdef
);
711 struct prop_type_change_info
*tci
= (struct prop_type_change_info
*) data
;
713 if (stmt_may_be_vtbl_ptr_store (stmt
))
715 tci
->type_maybe_changed
= true;
722 /* See if ARG is PARAM_DECl describing instance passed by pointer
723 or reference in FUNCTION. Return false if the dynamic type may change
724 in between beggining of the function until CALL is invoked.
726 Generally functions are not allowed to change type of such instances,
727 but they call destructors. We assume that methods cannot destroy the THIS
728 pointer. Also as a special cases, constructor and destructors may change
729 type of the THIS pointer. */
732 param_type_may_change_p (tree function
, tree arg
, gimple
*call
)
734 /* Pure functions cannot do any changes on the dynamic type;
735 that require writting to memory. */
736 if (flags_from_decl_or_type (function
) & (ECF_PURE
| ECF_CONST
))
738 /* We need to check if we are within inlined consturctor
739 or destructor (ideally we would have way to check that the
740 inline cdtor is actually working on ARG, but we don't have
741 easy tie on this, so punt on all non-pure cdtors.
742 We may also record the types of cdtors and once we know type
743 of the instance match them.
745 Also code unification optimizations may merge calls from
746 different blocks making return values unreliable. So
747 do nothing during late optimization. */
748 if (DECL_STRUCT_FUNCTION (function
)->after_inlining
)
750 if (TREE_CODE (arg
) == SSA_NAME
751 && SSA_NAME_IS_DEFAULT_DEF (arg
)
752 && TREE_CODE (SSA_NAME_VAR (arg
)) == PARM_DECL
)
754 /* Normal (non-THIS) argument. */
755 if ((SSA_NAME_VAR (arg
) != DECL_ARGUMENTS (function
)
756 || TREE_CODE (TREE_TYPE (function
)) != METHOD_TYPE
)
757 /* THIS pointer of an method - here we want to watch constructors
758 and destructors as those definitely may change the dynamic
760 || (TREE_CODE (TREE_TYPE (function
)) == METHOD_TYPE
761 && !DECL_CXX_CONSTRUCTOR_P (function
)
762 && !DECL_CXX_DESTRUCTOR_P (function
)
763 && (SSA_NAME_VAR (arg
) == DECL_ARGUMENTS (function
))))
765 /* Walk the inline stack and watch out for ctors/dtors. */
766 for (tree block
= gimple_block (call
); block
&& TREE_CODE (block
) == BLOCK
;
767 block
= BLOCK_SUPERCONTEXT (block
))
768 if (inlined_polymorphic_ctor_dtor_block_p (block
, false))
776 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
777 callsite CALL) by looking for assignments to its virtual table pointer. If
778 it is, return true. ARG is the object itself (not a pointer
779 to it, unless dereferenced). BASE is the base of the memory access as
780 returned by get_ref_base_and_extent, as is the offset.
782 This is helper function for detect_type_change and detect_type_change_ssa
783 that does the heavy work which is usually unnecesary. */
786 detect_type_change_from_memory_writes (ipa_func_body_info
*fbi
, tree arg
,
787 tree base
, tree comp_type
, gcall
*call
,
788 HOST_WIDE_INT offset
)
790 struct prop_type_change_info tci
;
793 gcc_checking_assert (DECL_P (arg
)
794 || TREE_CODE (arg
) == MEM_REF
795 || handled_component_p (arg
));
797 comp_type
= TYPE_MAIN_VARIANT (comp_type
);
799 /* Const calls cannot call virtual methods through VMT and so type changes do
801 if (!flag_devirtualize
|| !gimple_vuse (call
)
802 /* Be sure expected_type is polymorphic. */
804 || TREE_CODE (comp_type
) != RECORD_TYPE
805 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type
))
806 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type
))))
809 if (fbi
->aa_walk_budget
== 0)
812 ao_ref_init (&ao
, arg
);
815 ao
.size
= POINTER_SIZE
;
816 ao
.max_size
= ao
.size
;
819 tci
.object
= get_base_address (arg
);
820 tci
.type_maybe_changed
= false;
823 = walk_aliased_vdefs (&ao
, gimple_vuse (call
), check_stmt_for_type_change
,
824 &tci
, NULL
, NULL
, fbi
->aa_walk_budget
);
826 fbi
->aa_walk_budget
-= walked
;
828 fbi
->aa_walk_budget
= 0;
830 if (walked
>= 0 && !tci
.type_maybe_changed
)
836 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
837 If it is, return true. ARG is the object itself (not a pointer
838 to it, unless dereferenced). BASE is the base of the memory access as
839 returned by get_ref_base_and_extent, as is the offset. */
842 detect_type_change (ipa_func_body_info
*fbi
, tree arg
, tree base
,
843 tree comp_type
, gcall
*call
,
844 HOST_WIDE_INT offset
)
846 if (!flag_devirtualize
)
849 if (TREE_CODE (base
) == MEM_REF
850 && !param_type_may_change_p (current_function_decl
,
851 TREE_OPERAND (base
, 0),
854 return detect_type_change_from_memory_writes (fbi
, arg
, base
, comp_type
,
858 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
859 SSA name (its dereference will become the base and the offset is assumed to
863 detect_type_change_ssa (ipa_func_body_info
*fbi
, tree arg
, tree comp_type
,
866 gcc_checking_assert (TREE_CODE (arg
) == SSA_NAME
);
867 if (!flag_devirtualize
868 || !POINTER_TYPE_P (TREE_TYPE (arg
)))
871 if (!param_type_may_change_p (current_function_decl
, arg
, call
))
874 arg
= build2 (MEM_REF
, ptr_type_node
, arg
,
875 build_int_cst (ptr_type_node
, 0));
877 return detect_type_change_from_memory_writes (fbi
, arg
, arg
, comp_type
,
881 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
882 boolean variable pointed to by DATA. */
885 mark_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
888 bool *b
= (bool *) data
;
893 /* Find the nearest valid aa status for parameter specified by INDEX that
896 static struct ipa_param_aa_status
*
897 find_dominating_aa_status (struct ipa_func_body_info
*fbi
, basic_block bb
,
902 bb
= get_immediate_dominator (CDI_DOMINATORS
, bb
);
905 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
906 if (!bi
->param_aa_statuses
.is_empty ()
907 && bi
->param_aa_statuses
[index
].valid
)
908 return &bi
->param_aa_statuses
[index
];
912 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
913 structures and/or intialize the result with a dominating description as
916 static struct ipa_param_aa_status
*
917 parm_bb_aa_status_for_bb (struct ipa_func_body_info
*fbi
, basic_block bb
,
920 gcc_checking_assert (fbi
);
921 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
922 if (bi
->param_aa_statuses
.is_empty ())
923 bi
->param_aa_statuses
.safe_grow_cleared (fbi
->param_count
, true);
924 struct ipa_param_aa_status
*paa
= &bi
->param_aa_statuses
[index
];
927 gcc_checking_assert (!paa
->parm_modified
928 && !paa
->ref_modified
929 && !paa
->pt_modified
);
930 struct ipa_param_aa_status
*dom_paa
;
931 dom_paa
= find_dominating_aa_status (fbi
, bb
, index
);
941 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
942 a value known not to be modified in this function before reaching the
943 statement STMT. FBI holds information about the function we have so far
944 gathered but do not survive the summary building stage. */
947 parm_preserved_before_stmt_p (struct ipa_func_body_info
*fbi
, int index
,
948 gimple
*stmt
, tree parm_load
)
950 struct ipa_param_aa_status
*paa
;
951 bool modified
= false;
954 tree base
= get_base_address (parm_load
);
955 gcc_assert (TREE_CODE (base
) == PARM_DECL
);
956 if (TREE_READONLY (base
))
959 gcc_checking_assert (fbi
);
960 paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (stmt
), index
);
961 if (paa
->parm_modified
|| fbi
->aa_walk_budget
== 0)
964 gcc_checking_assert (gimple_vuse (stmt
) != NULL_TREE
);
965 ao_ref_init (&refd
, parm_load
);
966 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), mark_modified
,
967 &modified
, NULL
, NULL
,
968 fbi
->aa_walk_budget
);
972 fbi
->aa_walk_budget
= 0;
975 fbi
->aa_walk_budget
-= walked
;
977 paa
->parm_modified
= true;
981 /* If STMT is an assignment that loads a value from an parameter declaration,
982 return the index of the parameter in ipa_node_params which has not been
983 modified. Otherwise return -1. */
986 load_from_unmodified_param (struct ipa_func_body_info
*fbi
,
987 vec
<ipa_param_descriptor
, va_gc
> *descriptors
,
993 if (!gimple_assign_single_p (stmt
))
996 op1
= gimple_assign_rhs1 (stmt
);
997 if (TREE_CODE (op1
) != PARM_DECL
)
1000 index
= ipa_get_param_decl_index_1 (descriptors
, op1
);
1002 || !parm_preserved_before_stmt_p (fbi
, index
, stmt
, op1
))
1008 /* Return true if memory reference REF (which must be a load through parameter
1009 with INDEX) loads data that are known to be unmodified in this function
1010 before reaching statement STMT. */
1013 parm_ref_data_preserved_p (struct ipa_func_body_info
*fbi
,
1014 int index
, gimple
*stmt
, tree ref
)
1016 struct ipa_param_aa_status
*paa
;
1017 bool modified
= false;
1020 gcc_checking_assert (fbi
);
1021 paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (stmt
), index
);
1022 if (paa
->ref_modified
|| fbi
->aa_walk_budget
== 0)
1025 gcc_checking_assert (gimple_vuse (stmt
));
1026 ao_ref_init (&refd
, ref
);
1027 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), mark_modified
,
1028 &modified
, NULL
, NULL
,
1029 fbi
->aa_walk_budget
);
1033 fbi
->aa_walk_budget
= 0;
1036 fbi
->aa_walk_budget
-= walked
;
1038 paa
->ref_modified
= true;
1042 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
1043 is known to be unmodified in this function before reaching call statement
1044 CALL into which it is passed. FBI describes the function body. */
1047 parm_ref_data_pass_through_p (struct ipa_func_body_info
*fbi
, int index
,
1048 gimple
*call
, tree parm
)
1050 bool modified
= false;
1053 /* It's unnecessary to calculate anything about memory contnets for a const
1054 function because it is not goin to use it. But do not cache the result
1055 either. Also, no such calculations for non-pointers. */
1056 if (!gimple_vuse (call
)
1057 || !POINTER_TYPE_P (TREE_TYPE (parm
)))
1060 struct ipa_param_aa_status
*paa
= parm_bb_aa_status_for_bb (fbi
,
1063 if (paa
->pt_modified
|| fbi
->aa_walk_budget
== 0)
1066 ao_ref_init_from_ptr_and_size (&refd
, parm
, NULL_TREE
);
1067 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (call
), mark_modified
,
1068 &modified
, NULL
, NULL
,
1069 fbi
->aa_walk_budget
);
1072 fbi
->aa_walk_budget
= 0;
1076 fbi
->aa_walk_budget
-= walked
;
1078 paa
->pt_modified
= true;
1082 /* Return true if we can prove that OP is a memory reference loading
1083 data from an aggregate passed as a parameter.
1085 The function works in two modes. If GUARANTEED_UNMODIFIED is NULL, it return
1086 false if it cannot prove that the value has not been modified before the
1087 load in STMT. If GUARANTEED_UNMODIFIED is not NULL, it will return true even
1088 if it cannot prove the value has not been modified, in that case it will
1089 store false to *GUARANTEED_UNMODIFIED, otherwise it will store true there.
1091 INFO and PARMS_AINFO describe parameters of the current function (but the
1092 latter can be NULL), STMT is the load statement. If function returns true,
1093 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1094 within the aggregate and whether it is a load from a value passed by
1095 reference respectively. */
1098 ipa_load_from_parm_agg (struct ipa_func_body_info
*fbi
,
1099 vec
<ipa_param_descriptor
, va_gc
> *descriptors
,
1100 gimple
*stmt
, tree op
, int *index_p
,
1101 HOST_WIDE_INT
*offset_p
, poly_int64
*size_p
,
1102 bool *by_ref_p
, bool *guaranteed_unmodified
)
1107 tree base
= get_ref_base_and_extent_hwi (op
, offset_p
, &size
, &reverse
);
1114 int index
= ipa_get_param_decl_index_1 (descriptors
, base
);
1116 && parm_preserved_before_stmt_p (fbi
, index
, stmt
, op
))
1122 if (guaranteed_unmodified
)
1123 *guaranteed_unmodified
= true;
1129 if (TREE_CODE (base
) != MEM_REF
1130 || TREE_CODE (TREE_OPERAND (base
, 0)) != SSA_NAME
1131 || !integer_zerop (TREE_OPERAND (base
, 1)))
1134 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base
, 0)))
1136 tree parm
= SSA_NAME_VAR (TREE_OPERAND (base
, 0));
1137 index
= ipa_get_param_decl_index_1 (descriptors
, parm
);
1141 /* This branch catches situations where a pointer parameter is not a
1142 gimple register, for example:
1144 void hip7(S*) (struct S * p)
1146 void (*<T2e4>) (struct S *) D.1867;
1151 D.1867_2 = p.1_1->f;
1156 gimple
*def
= SSA_NAME_DEF_STMT (TREE_OPERAND (base
, 0));
1157 index
= load_from_unmodified_param (fbi
, descriptors
, def
);
1162 bool data_preserved
= parm_ref_data_preserved_p (fbi
, index
, stmt
, op
);
1163 if (!data_preserved
&& !guaranteed_unmodified
)
1170 if (guaranteed_unmodified
)
1171 *guaranteed_unmodified
= data_preserved
;
1177 /* If STMT is an assignment that loads a value from a parameter declaration,
1178 or from an aggregate passed as the parameter either by value or reference,
1179 return the index of the parameter in ipa_node_params. Otherwise return -1.
1181 FBI holds gathered information about the function. INFO describes
1182 parameters of the function, STMT is the assignment statement. If it is a
1183 memory load from an aggregate, *OFFSET_P is filled with offset within the
1184 aggregate, and *BY_REF_P specifies whether the aggregate is passed by
1188 load_from_unmodified_param_or_agg (struct ipa_func_body_info
*fbi
,
1189 class ipa_node_params
*info
,
1191 HOST_WIDE_INT
*offset_p
,
1194 int index
= load_from_unmodified_param (fbi
, info
->descriptors
, stmt
);
1197 /* Load value from a parameter declaration. */
1204 if (!gimple_assign_load_p (stmt
))
1207 tree rhs
= gimple_assign_rhs1 (stmt
);
1209 /* Skip memory reference containing VIEW_CONVERT_EXPR. */
1210 for (tree t
= rhs
; handled_component_p (t
); t
= TREE_OPERAND (t
, 0))
1211 if (TREE_CODE (t
) == VIEW_CONVERT_EXPR
)
1214 /* Skip memory reference containing bit-field. */
1215 if (TREE_CODE (rhs
) == BIT_FIELD_REF
1216 || contains_bitfld_component_ref_p (rhs
))
1219 if (!ipa_load_from_parm_agg (fbi
, info
->descriptors
, stmt
, rhs
, &index
,
1220 offset_p
, &size
, by_ref_p
))
1223 gcc_assert (!maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (rhs
))),
1227 tree param_type
= ipa_get_type (info
, index
);
1229 if (!param_type
|| !AGGREGATE_TYPE_P (param_type
))
1232 else if (TREE_THIS_VOLATILE (rhs
))
1238 /* Walk pointer adjustemnts from OP (such as POINTER_PLUS and ADDR_EXPR)
1239 to find original pointer. Initialize RET to the pointer which results from
1241 If offset is known return true and initialize OFFSET_RET. */
1244 unadjusted_ptr_and_unit_offset (tree op
, tree
*ret
, poly_int64
*offset_ret
)
1246 poly_int64 offset
= 0;
1247 bool offset_known
= true;
1250 for (i
= 0; i
< param_ipa_jump_function_lookups
; i
++)
1252 if (TREE_CODE (op
) == ADDR_EXPR
)
1254 poly_int64 extra_offset
= 0;
1255 tree base
= get_addr_base_and_unit_offset (TREE_OPERAND (op
, 0),
1259 base
= get_base_address (TREE_OPERAND (op
, 0));
1260 if (TREE_CODE (base
) != MEM_REF
)
1262 offset_known
= false;
1266 if (TREE_CODE (base
) != MEM_REF
)
1268 offset
+= extra_offset
;
1270 op
= TREE_OPERAND (base
, 0);
1271 if (mem_ref_offset (base
).to_shwi (&extra_offset
))
1272 offset
+= extra_offset
;
1274 offset_known
= false;
1276 else if (TREE_CODE (op
) == SSA_NAME
1277 && !SSA_NAME_IS_DEFAULT_DEF (op
))
1279 gimple
*pstmt
= SSA_NAME_DEF_STMT (op
);
1281 if (gimple_assign_single_p (pstmt
))
1282 op
= gimple_assign_rhs1 (pstmt
);
1283 else if (is_gimple_assign (pstmt
)
1284 && gimple_assign_rhs_code (pstmt
) == POINTER_PLUS_EXPR
)
1286 poly_int64 extra_offset
= 0;
1287 if (ptrdiff_tree_p (gimple_assign_rhs2 (pstmt
),
1289 offset
+= extra_offset
;
1291 offset_known
= false;
1292 op
= gimple_assign_rhs1 (pstmt
);
1301 *offset_ret
= offset
;
1302 return offset_known
;
1305 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1306 of an assignment statement STMT, try to determine whether we are actually
1307 handling any of the following cases and construct an appropriate jump
1308 function into JFUNC if so:
1310 1) The passed value is loaded from a formal parameter which is not a gimple
1311 register (most probably because it is addressable, the value has to be
1312 scalar) and we can guarantee the value has not changed. This case can
1313 therefore be described by a simple pass-through jump function. For example:
1322 2) The passed value can be described by a simple arithmetic pass-through
1329 D.2064_4 = a.1(D) + 4;
1332 This case can also occur in combination of the previous one, e.g.:
1340 D.2064_4 = a.0_3 + 4;
1343 3) The passed value is an address of an object within another one (which
1344 also passed by reference). Such situations are described by an ancestor
1345 jump function and describe situations such as:
1347 B::foo() (struct B * const this)
1351 D.1845_2 = &this_1(D)->D.1748;
1354 INFO is the structure describing individual parameters access different
1355 stages of IPA optimizations. PARMS_AINFO contains the information that is
1356 only needed for intraprocedural analysis. */
1359 compute_complex_assign_jump_func (struct ipa_func_body_info
*fbi
,
1360 class ipa_node_params
*info
,
1361 struct ipa_jump_func
*jfunc
,
1362 gcall
*call
, gimple
*stmt
, tree name
,
1365 HOST_WIDE_INT offset
, size
;
1366 tree op1
, tc_ssa
, base
, ssa
;
1370 op1
= gimple_assign_rhs1 (stmt
);
1372 if (TREE_CODE (op1
) == SSA_NAME
)
1374 if (SSA_NAME_IS_DEFAULT_DEF (op1
))
1375 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (op1
));
1377 index
= load_from_unmodified_param (fbi
, info
->descriptors
,
1378 SSA_NAME_DEF_STMT (op1
));
1383 index
= load_from_unmodified_param (fbi
, info
->descriptors
, stmt
);
1384 tc_ssa
= gimple_assign_lhs (stmt
);
1389 switch (gimple_assign_rhs_class (stmt
))
1391 case GIMPLE_BINARY_RHS
:
1393 tree op2
= gimple_assign_rhs2 (stmt
);
1394 if (!is_gimple_ip_invariant (op2
)
1395 || ((TREE_CODE_CLASS (gimple_assign_rhs_code (stmt
))
1397 && !useless_type_conversion_p (TREE_TYPE (name
),
1401 ipa_set_jf_arith_pass_through (jfunc
, index
, op2
,
1402 gimple_assign_rhs_code (stmt
));
1405 case GIMPLE_SINGLE_RHS
:
1407 bool agg_p
= parm_ref_data_pass_through_p (fbi
, index
, call
,
1409 ipa_set_jf_simple_pass_through (jfunc
, index
, agg_p
);
1412 case GIMPLE_UNARY_RHS
:
1413 if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt
)))
1414 ipa_set_jf_unary_pass_through (jfunc
, index
,
1415 gimple_assign_rhs_code (stmt
));
1421 if (TREE_CODE (op1
) != ADDR_EXPR
)
1423 op1
= TREE_OPERAND (op1
, 0);
1424 if (TREE_CODE (TREE_TYPE (op1
)) != RECORD_TYPE
)
1426 base
= get_ref_base_and_extent_hwi (op1
, &offset
, &size
, &reverse
);
1427 offset_int mem_offset
;
1429 || TREE_CODE (base
) != MEM_REF
1430 || !mem_ref_offset (base
).is_constant (&mem_offset
))
1432 offset
+= mem_offset
.to_short_addr () * BITS_PER_UNIT
;
1433 ssa
= TREE_OPERAND (base
, 0);
1434 if (TREE_CODE (ssa
) != SSA_NAME
1435 || !SSA_NAME_IS_DEFAULT_DEF (ssa
)
1439 /* Dynamic types are changed in constructors and destructors. */
1440 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (ssa
));
1441 if (index
>= 0 && param_type
&& POINTER_TYPE_P (param_type
))
1442 ipa_set_ancestor_jf (jfunc
, offset
, index
,
1443 parm_ref_data_pass_through_p (fbi
, index
, call
, ssa
));
1446 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1449 iftmp.1_3 = &obj_2(D)->D.1762;
1451 The base of the MEM_REF must be a default definition SSA NAME of a
1452 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1453 whole MEM_REF expression is returned and the offset calculated from any
1454 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1455 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1458 get_ancestor_addr_info (gimple
*assign
, tree
*obj_p
, HOST_WIDE_INT
*offset
)
1461 tree expr
, parm
, obj
;
1464 if (!gimple_assign_single_p (assign
))
1466 expr
= gimple_assign_rhs1 (assign
);
1468 if (TREE_CODE (expr
) != ADDR_EXPR
)
1470 expr
= TREE_OPERAND (expr
, 0);
1472 expr
= get_ref_base_and_extent_hwi (expr
, offset
, &size
, &reverse
);
1474 offset_int mem_offset
;
1476 || TREE_CODE (expr
) != MEM_REF
1477 || !mem_ref_offset (expr
).is_constant (&mem_offset
))
1479 parm
= TREE_OPERAND (expr
, 0);
1480 if (TREE_CODE (parm
) != SSA_NAME
1481 || !SSA_NAME_IS_DEFAULT_DEF (parm
)
1482 || TREE_CODE (SSA_NAME_VAR (parm
)) != PARM_DECL
)
1485 *offset
+= mem_offset
.to_short_addr () * BITS_PER_UNIT
;
1491 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1492 statement PHI, try to find out whether NAME is in fact a
1493 multiple-inheritance typecast from a descendant into an ancestor of a formal
1494 parameter and thus can be described by an ancestor jump function and if so,
1495 write the appropriate function into JFUNC.
1497 Essentially we want to match the following pattern:
1505 iftmp.1_3 = &obj_2(D)->D.1762;
1508 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1509 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1513 compute_complex_ancestor_jump_func (struct ipa_func_body_info
*fbi
,
1514 class ipa_node_params
*info
,
1515 struct ipa_jump_func
*jfunc
,
1516 gcall
*call
, gphi
*phi
)
1518 HOST_WIDE_INT offset
;
1519 gimple
*assign
, *cond
;
1520 basic_block phi_bb
, assign_bb
, cond_bb
;
1521 tree tmp
, parm
, expr
, obj
;
1524 if (gimple_phi_num_args (phi
) != 2)
1527 if (integer_zerop (PHI_ARG_DEF (phi
, 1)))
1528 tmp
= PHI_ARG_DEF (phi
, 0);
1529 else if (integer_zerop (PHI_ARG_DEF (phi
, 0)))
1530 tmp
= PHI_ARG_DEF (phi
, 1);
1533 if (TREE_CODE (tmp
) != SSA_NAME
1534 || SSA_NAME_IS_DEFAULT_DEF (tmp
)
1535 || !POINTER_TYPE_P (TREE_TYPE (tmp
))
1536 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp
))) != RECORD_TYPE
)
1539 assign
= SSA_NAME_DEF_STMT (tmp
);
1540 assign_bb
= gimple_bb (assign
);
1541 if (!single_pred_p (assign_bb
))
1543 expr
= get_ancestor_addr_info (assign
, &obj
, &offset
);
1546 parm
= TREE_OPERAND (expr
, 0);
1547 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (parm
));
1551 cond_bb
= single_pred (assign_bb
);
1552 cond
= last_stmt (cond_bb
);
1554 || gimple_code (cond
) != GIMPLE_COND
1555 || gimple_cond_code (cond
) != NE_EXPR
1556 || gimple_cond_lhs (cond
) != parm
1557 || !integer_zerop (gimple_cond_rhs (cond
)))
1560 phi_bb
= gimple_bb (phi
);
1561 for (i
= 0; i
< 2; i
++)
1563 basic_block pred
= EDGE_PRED (phi_bb
, i
)->src
;
1564 if (pred
!= assign_bb
&& pred
!= cond_bb
)
1568 ipa_set_ancestor_jf (jfunc
, offset
, index
,
1569 parm_ref_data_pass_through_p (fbi
, index
, call
, parm
));
1572 /* Inspect the given TYPE and return true iff it has the same structure (the
1573 same number of fields of the same types) as a C++ member pointer. If
1574 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1575 corresponding fields there. */
1578 type_like_member_ptr_p (tree type
, tree
*method_ptr
, tree
*delta
)
1582 if (TREE_CODE (type
) != RECORD_TYPE
)
1585 fld
= TYPE_FIELDS (type
);
1586 if (!fld
|| !POINTER_TYPE_P (TREE_TYPE (fld
))
1587 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld
))) != METHOD_TYPE
1588 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
1594 fld
= DECL_CHAIN (fld
);
1595 if (!fld
|| INTEGRAL_TYPE_P (fld
)
1596 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
1601 if (DECL_CHAIN (fld
))
1607 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1608 return the rhs of its defining statement, and this statement is stored in
1609 *RHS_STMT. Otherwise return RHS as it is. */
1612 get_ssa_def_if_simple_copy (tree rhs
, gimple
**rhs_stmt
)
1614 while (TREE_CODE (rhs
) == SSA_NAME
&& !SSA_NAME_IS_DEFAULT_DEF (rhs
))
1616 gimple
*def_stmt
= SSA_NAME_DEF_STMT (rhs
);
1618 if (gimple_assign_single_p (def_stmt
))
1619 rhs
= gimple_assign_rhs1 (def_stmt
);
1622 *rhs_stmt
= def_stmt
;
1627 /* Simple linked list, describing contents of an aggregate before call. */
1629 struct ipa_known_agg_contents_list
1631 /* Offset and size of the described part of the aggregate. */
1632 HOST_WIDE_INT offset
, size
;
1634 /* Type of the described part of the aggregate. */
1637 /* Known constant value or jump function data describing contents. */
1638 struct ipa_load_agg_data value
;
1640 /* Pointer to the next structure in the list. */
1641 struct ipa_known_agg_contents_list
*next
;
1644 /* Add an aggregate content item into a linked list of
1645 ipa_known_agg_contents_list structure, in which all elements
1646 are sorted ascendingly by offset. */
1649 add_to_agg_contents_list (struct ipa_known_agg_contents_list
**plist
,
1650 struct ipa_known_agg_contents_list
*item
)
1652 struct ipa_known_agg_contents_list
*list
= *plist
;
1654 for (; list
; list
= list
->next
)
1656 if (list
->offset
>= item
->offset
)
1659 plist
= &list
->next
;
1666 /* Check whether a given aggregate content is clobbered by certain element in
1667 a linked list of ipa_known_agg_contents_list. */
1670 clobber_by_agg_contents_list_p (struct ipa_known_agg_contents_list
*list
,
1671 struct ipa_known_agg_contents_list
*item
)
1673 for (; list
; list
= list
->next
)
1675 if (list
->offset
>= item
->offset
)
1676 return list
->offset
< item
->offset
+ item
->size
;
1678 if (list
->offset
+ list
->size
> item
->offset
)
1685 /* Build aggregate jump function from LIST, assuming there are exactly
1686 VALUE_COUNT entries there and that offset of the passed argument
1687 is ARG_OFFSET and store it into JFUNC. */
1690 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list
*list
,
1691 int value_count
, HOST_WIDE_INT arg_offset
,
1692 struct ipa_jump_func
*jfunc
)
1694 vec_safe_reserve (jfunc
->agg
.items
, value_count
, true);
1695 for (; list
; list
= list
->next
)
1697 struct ipa_agg_jf_item item
;
1698 tree operand
= list
->value
.pass_through
.operand
;
1700 if (list
->value
.pass_through
.formal_id
>= 0)
1702 /* Content value is derived from some formal paramerter. */
1703 if (list
->value
.offset
>= 0)
1704 item
.jftype
= IPA_JF_LOAD_AGG
;
1706 item
.jftype
= IPA_JF_PASS_THROUGH
;
1708 item
.value
.load_agg
= list
->value
;
1710 item
.value
.pass_through
.operand
1711 = unshare_expr_without_location (operand
);
1715 /* Content value is known constant. */
1716 item
.jftype
= IPA_JF_CONST
;
1717 item
.value
.constant
= unshare_expr_without_location (operand
);
1722 item
.type
= list
->type
;
1723 gcc_assert (tree_to_shwi (TYPE_SIZE (list
->type
)) == list
->size
);
1725 item
.offset
= list
->offset
- arg_offset
;
1726 gcc_assert ((item
.offset
% BITS_PER_UNIT
) == 0);
1728 jfunc
->agg
.items
->quick_push (item
);
1732 /* Given an assignment statement STMT, try to collect information into
1733 AGG_VALUE that will be used to construct jump function for RHS of the
1734 assignment, from which content value of an aggregate part comes.
1736 Besides constant and simple pass-through jump functions, also try to
1737 identify whether it matches the following pattern that can be described by
1738 a load-value-from-aggregate jump function, which is a derivative of simple
1739 pass-through jump function.
1745 *(q_5 + 4) = *(p_3(D) + 28) op 1;
1749 Here IPA_LOAD_AGG_DATA data structure is informative enough to describe
1750 constant, simple pass-through and load-vale-from-aggregate. If value
1751 is constant, it will be kept in field OPERAND, and field FORMAL_ID is
1752 set to -1. For simple pass-through and load-value-from-aggregate, field
1753 FORMAL_ID specifies the related formal parameter index, and field
1754 OFFSET can be used to distinguish them, -1 means simple pass-through,
1755 otherwise means load-value-from-aggregate. */
1758 analyze_agg_content_value (struct ipa_func_body_info
*fbi
,
1759 struct ipa_load_agg_data
*agg_value
,
1762 tree lhs
= gimple_assign_lhs (stmt
);
1763 tree rhs1
= gimple_assign_rhs1 (stmt
);
1764 enum tree_code code
;
1767 /* Initialize jump function data for the aggregate part. */
1768 memset (agg_value
, 0, sizeof (*agg_value
));
1769 agg_value
->pass_through
.operation
= NOP_EXPR
;
1770 agg_value
->pass_through
.formal_id
= -1;
1771 agg_value
->offset
= -1;
1773 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs
)) /* TODO: Support aggregate type. */
1774 || TREE_THIS_VOLATILE (lhs
)
1775 || TREE_CODE (lhs
) == BIT_FIELD_REF
1776 || contains_bitfld_component_ref_p (lhs
))
1779 /* Skip SSA copies. */
1780 while (gimple_assign_rhs_class (stmt
) == GIMPLE_SINGLE_RHS
)
1782 if (TREE_CODE (rhs1
) != SSA_NAME
|| SSA_NAME_IS_DEFAULT_DEF (rhs1
))
1785 stmt
= SSA_NAME_DEF_STMT (rhs1
);
1786 if (!is_gimple_assign (stmt
))
1789 rhs1
= gimple_assign_rhs1 (stmt
);
1792 if (gphi
*phi
= dyn_cast
<gphi
*> (stmt
))
1794 /* Also special case like the following (a is a formal parameter):
1796 _12 = *a_11(D).dim[0].stride;
1798 # iftmp.22_9 = PHI <_12(2), 1(3)>
1800 parm.6.dim[0].stride = iftmp.22_9;
1802 __x_MOD_foo (&parm.6, b_31(D));
1804 The aggregate function describing parm.6.dim[0].stride is encoded as a
1805 PASS-THROUGH jump function with ASSERT_EXPR operation whith operand 1
1806 (the constant from the PHI node). */
1808 if (gimple_phi_num_args (phi
) != 2)
1810 tree arg0
= gimple_phi_arg_def (phi
, 0);
1811 tree arg1
= gimple_phi_arg_def (phi
, 1);
1814 if (is_gimple_ip_invariant (arg1
))
1819 else if (is_gimple_ip_invariant (arg0
))
1827 rhs1
= get_ssa_def_if_simple_copy (rhs1
, &stmt
);
1828 if (!is_gimple_assign (stmt
))
1832 agg_value
->pass_through
.operand
= operand
;
1834 else if (is_gimple_assign (stmt
))
1836 code
= gimple_assign_rhs_code (stmt
);
1837 switch (gimple_assign_rhs_class (stmt
))
1839 case GIMPLE_SINGLE_RHS
:
1840 if (is_gimple_ip_invariant (rhs1
))
1842 agg_value
->pass_through
.operand
= rhs1
;
1848 case GIMPLE_UNARY_RHS
:
1849 /* NOTE: A GIMPLE_UNARY_RHS operation might not be tcc_unary
1850 (truth_not_expr is example), GIMPLE_BINARY_RHS does not imply
1851 tcc_binary, this subtleness is somewhat misleading.
1853 Since tcc_unary is widely used in IPA-CP code to check an operation
1854 with one operand, here we only allow tc_unary operation to avoid
1855 possible problem. Then we can use (opclass == tc_unary) or not to
1856 distinguish unary and binary. */
1857 if (TREE_CODE_CLASS (code
) != tcc_unary
|| CONVERT_EXPR_CODE_P (code
))
1860 rhs1
= get_ssa_def_if_simple_copy (rhs1
, &stmt
);
1863 case GIMPLE_BINARY_RHS
:
1865 gimple
*rhs1_stmt
= stmt
;
1866 gimple
*rhs2_stmt
= stmt
;
1867 tree rhs2
= gimple_assign_rhs2 (stmt
);
1869 rhs1
= get_ssa_def_if_simple_copy (rhs1
, &rhs1_stmt
);
1870 rhs2
= get_ssa_def_if_simple_copy (rhs2
, &rhs2_stmt
);
1872 if (is_gimple_ip_invariant (rhs2
))
1874 agg_value
->pass_through
.operand
= rhs2
;
1877 else if (is_gimple_ip_invariant (rhs1
))
1879 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
1880 code
= swap_tree_comparison (code
);
1881 else if (!commutative_tree_code (code
))
1884 agg_value
->pass_through
.operand
= rhs1
;
1891 if (TREE_CODE_CLASS (code
) != tcc_comparison
1892 && !useless_type_conversion_p (TREE_TYPE (lhs
),
1905 if (TREE_CODE (rhs1
) != SSA_NAME
)
1906 index
= load_from_unmodified_param_or_agg (fbi
, fbi
->info
, stmt
,
1908 &agg_value
->by_ref
);
1909 else if (SSA_NAME_IS_DEFAULT_DEF (rhs1
))
1910 index
= ipa_get_param_decl_index (fbi
->info
, SSA_NAME_VAR (rhs1
));
1914 if (agg_value
->offset
>= 0)
1915 agg_value
->type
= TREE_TYPE (rhs1
);
1916 agg_value
->pass_through
.formal_id
= index
;
1917 agg_value
->pass_through
.operation
= code
;
1920 agg_value
->pass_through
.operand
= NULL_TREE
;
1923 /* If STMT is a memory store to the object whose address is BASE, extract
1924 information (offset, size, and value) into CONTENT, and return true,
1925 otherwise we conservatively assume the whole object is modified with
1926 unknown content, and return false. CHECK_REF means that access to object
1927 is expected to be in form of MEM_REF expression. */
1930 extract_mem_content (struct ipa_func_body_info
*fbi
,
1931 gimple
*stmt
, tree base
, bool check_ref
,
1932 struct ipa_known_agg_contents_list
*content
)
1934 HOST_WIDE_INT lhs_offset
, lhs_size
;
1937 if (!is_gimple_assign (stmt
))
1940 tree lhs
= gimple_assign_lhs (stmt
);
1941 tree lhs_base
= get_ref_base_and_extent_hwi (lhs
, &lhs_offset
, &lhs_size
,
1948 if (TREE_CODE (lhs_base
) != MEM_REF
1949 || TREE_OPERAND (lhs_base
, 0) != base
1950 || !integer_zerop (TREE_OPERAND (lhs_base
, 1)))
1953 else if (lhs_base
!= base
)
1956 content
->offset
= lhs_offset
;
1957 content
->size
= lhs_size
;
1958 content
->type
= TREE_TYPE (lhs
);
1959 content
->next
= NULL
;
1961 analyze_agg_content_value (fbi
, &content
->value
, stmt
);
1965 /* Traverse statements from CALL backwards, scanning whether an aggregate given
1966 in ARG is filled in constants or values that are derived from caller's
1967 formal parameter in the way described by some kinds of jump functions. FBI
1968 is the context of the caller function for interprocedural analysis. ARG can
1969 either be an aggregate expression or a pointer to an aggregate. ARG_TYPE is
1970 the type of the aggregate, JFUNC is the jump function for the aggregate. */
1973 determine_known_aggregate_parts (struct ipa_func_body_info
*fbi
,
1974 gcall
*call
, tree arg
,
1976 struct ipa_jump_func
*jfunc
)
1978 struct ipa_known_agg_contents_list
*list
= NULL
, *all_list
= NULL
;
1979 bitmap visited
= NULL
;
1980 int item_count
= 0, value_count
= 0;
1981 HOST_WIDE_INT arg_offset
, arg_size
;
1983 bool check_ref
, by_ref
;
1985 int max_agg_items
= opt_for_fn (fbi
->node
->decl
, param_ipa_max_agg_items
);
1987 if (max_agg_items
== 0)
1990 /* The function operates in three stages. First, we prepare check_ref, r,
1991 arg_base and arg_offset based on what is actually passed as an actual
1994 if (POINTER_TYPE_P (arg_type
))
1997 if (TREE_CODE (arg
) == SSA_NAME
)
2000 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type
)))
2001 || !POINTER_TYPE_P (TREE_TYPE (arg
)))
2006 type_size
= TYPE_SIZE (TREE_TYPE (arg_type
));
2007 arg_size
= tree_to_uhwi (type_size
);
2008 ao_ref_init_from_ptr_and_size (&r
, arg_base
, NULL_TREE
);
2010 else if (TREE_CODE (arg
) == ADDR_EXPR
)
2014 arg
= TREE_OPERAND (arg
, 0);
2015 arg_base
= get_ref_base_and_extent_hwi (arg
, &arg_offset
,
2016 &arg_size
, &reverse
);
2019 if (DECL_P (arg_base
))
2022 ao_ref_init (&r
, arg_base
);
2034 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg
)));
2038 arg_base
= get_ref_base_and_extent_hwi (arg
, &arg_offset
,
2039 &arg_size
, &reverse
);
2043 ao_ref_init (&r
, arg
);
2046 /* Second stage traverses virtual SSA web backwards starting from the call
2047 statement, only looks at individual dominating virtual operand (its
2048 definition dominates the call), as long as it is confident that content
2049 of the aggregate is affected by definition of the virtual operand, it
2050 builds a sorted linked list of ipa_agg_jf_list describing that. */
2052 for (tree dom_vuse
= gimple_vuse (call
);
2053 dom_vuse
&& fbi
->aa_walk_budget
> 0;)
2055 gimple
*stmt
= SSA_NAME_DEF_STMT (dom_vuse
);
2057 if (gimple_code (stmt
) == GIMPLE_PHI
)
2059 dom_vuse
= get_continuation_for_phi (stmt
, &r
, true,
2060 fbi
->aa_walk_budget
,
2061 &visited
, false, NULL
, NULL
);
2065 fbi
->aa_walk_budget
--;
2066 if (stmt_may_clobber_ref_p_1 (stmt
, &r
))
2068 struct ipa_known_agg_contents_list
*content
2069 = XALLOCA (struct ipa_known_agg_contents_list
);
2071 if (!extract_mem_content (fbi
, stmt
, arg_base
, check_ref
, content
))
2074 /* Now we get a dominating virtual operand, and need to check
2075 whether its value is clobbered any other dominating one. */
2076 if ((content
->value
.pass_through
.formal_id
>= 0
2077 || content
->value
.pass_through
.operand
)
2078 && !clobber_by_agg_contents_list_p (all_list
, content
))
2080 struct ipa_known_agg_contents_list
*copy
2081 = XALLOCA (struct ipa_known_agg_contents_list
);
2083 /* Add to the list consisting of only dominating virtual
2084 operands, whose definitions can finally reach the call. */
2085 add_to_agg_contents_list (&list
, (*copy
= *content
, copy
));
2087 if (++value_count
== max_agg_items
)
2091 /* Add to the list consisting of all dominating virtual operands. */
2092 add_to_agg_contents_list (&all_list
, content
);
2094 if (++item_count
== 2 * max_agg_items
)
2097 dom_vuse
= gimple_vuse (stmt
);
2101 BITMAP_FREE (visited
);
2103 /* Third stage just goes over the list and creates an appropriate vector of
2104 ipa_agg_jf_item structures out of it, of course only if there are
2105 any meaningful items to begin with. */
2109 jfunc
->agg
.by_ref
= by_ref
;
2110 build_agg_jump_func_from_list (list
, value_count
, arg_offset
, jfunc
);
2115 /* Return the Ith param type of callee associated with call graph
2119 ipa_get_callee_param_type (struct cgraph_edge
*e
, int i
)
2122 tree type
= (e
->callee
2123 ? TREE_TYPE (e
->callee
->decl
)
2124 : gimple_call_fntype (e
->call_stmt
));
2125 tree t
= TYPE_ARG_TYPES (type
);
2127 for (n
= 0; n
< i
; n
++)
2134 return TREE_VALUE (t
);
2137 t
= DECL_ARGUMENTS (e
->callee
->decl
);
2138 for (n
= 0; n
< i
; n
++)
2145 return TREE_TYPE (t
);
2149 /* Return ipa_bits with VALUE and MASK values, which can be either a newly
2150 allocated structure or a previously existing one shared with other jump
2151 functions and/or transformation summaries. */
2154 ipa_get_ipa_bits_for_value (const widest_int
&value
, const widest_int
&mask
)
2160 ipa_bits
**slot
= ipa_bits_hash_table
->find_slot (&tmp
, INSERT
);
2164 ipa_bits
*res
= ggc_alloc
<ipa_bits
> ();
2172 /* Assign to JF a pointer to ipa_bits structure with VALUE and MASK. Use hash
2173 table in order to avoid creating multiple same ipa_bits structures. */
2176 ipa_set_jfunc_bits (ipa_jump_func
*jf
, const widest_int
&value
,
2177 const widest_int
&mask
)
2179 jf
->bits
= ipa_get_ipa_bits_for_value (value
, mask
);
2182 /* Return a pointer to a value_range just like *TMP, but either find it in
2183 ipa_vr_hash_table or allocate it in GC memory. TMP->equiv must be NULL. */
2185 static value_range
*
2186 ipa_get_value_range (value_range
*tmp
)
2188 value_range
**slot
= ipa_vr_hash_table
->find_slot (tmp
, INSERT
);
2192 value_range
*vr
= new (ggc_alloc
<value_range
> ()) value_range
;
2199 /* Return a pointer to a value range consisting of TYPE, MIN, MAX and an empty
2200 equiv set. Use hash table in order to avoid creating multiple same copies of
2203 static value_range
*
2204 ipa_get_value_range (enum value_range_kind kind
, tree min
, tree max
)
2206 value_range
tmp (min
, max
, kind
);
2207 return ipa_get_value_range (&tmp
);
2210 /* Assign to JF a pointer to a value_range structure with TYPE, MIN and MAX and
2211 a NULL equiv bitmap. Use hash table in order to avoid creating multiple
2212 same value_range structures. */
2215 ipa_set_jfunc_vr (ipa_jump_func
*jf
, enum value_range_kind type
,
2218 jf
->m_vr
= ipa_get_value_range (type
, min
, max
);
2221 /* Assign to JF a pointer to a value_range just like TMP but either fetch a
2222 copy from ipa_vr_hash_table or allocate a new on in GC memory. */
2225 ipa_set_jfunc_vr (ipa_jump_func
*jf
, value_range
*tmp
)
2227 jf
->m_vr
= ipa_get_value_range (tmp
);
2230 /* Compute jump function for all arguments of callsite CS and insert the
2231 information in the jump_functions array in the ipa_edge_args corresponding
2232 to this callsite. */
2235 ipa_compute_jump_functions_for_edge (struct ipa_func_body_info
*fbi
,
2236 struct cgraph_edge
*cs
)
2238 ipa_node_params
*info
= ipa_node_params_sum
->get (cs
->caller
);
2239 ipa_edge_args
*args
= ipa_edge_args_sum
->get_create (cs
);
2240 gcall
*call
= cs
->call_stmt
;
2241 int n
, arg_num
= gimple_call_num_args (call
);
2242 bool useful_context
= false;
2245 if (arg_num
== 0 || args
->jump_functions
)
2247 vec_safe_grow_cleared (args
->jump_functions
, arg_num
, true);
2248 if (flag_devirtualize
)
2249 vec_safe_grow_cleared (args
->polymorphic_call_contexts
, arg_num
, true);
2251 if (gimple_call_internal_p (call
))
2253 if (ipa_func_spec_opts_forbid_analysis_p (cs
->caller
))
2256 for (n
= 0; n
< arg_num
; n
++)
2258 struct ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (args
, n
);
2259 tree arg
= gimple_call_arg (call
, n
);
2260 tree param_type
= ipa_get_callee_param_type (cs
, n
);
2261 if (flag_devirtualize
&& POINTER_TYPE_P (TREE_TYPE (arg
)))
2264 class ipa_polymorphic_call_context
context (cs
->caller
->decl
,
2267 context
.get_dynamic_type (instance
, arg
, NULL
, cs
->call_stmt
,
2268 &fbi
->aa_walk_budget
);
2269 *ipa_get_ith_polymorhic_call_context (args
, n
) = context
;
2270 if (!context
.useless_p ())
2271 useful_context
= true;
2274 if (POINTER_TYPE_P (TREE_TYPE (arg
)))
2276 bool addr_nonzero
= false;
2277 bool strict_overflow
= false;
2279 if (TREE_CODE (arg
) == SSA_NAME
2281 && get_range_query (cfun
)->range_of_expr (vr
, arg
)
2283 addr_nonzero
= true;
2284 else if (tree_single_nonzero_warnv_p (arg
, &strict_overflow
))
2285 addr_nonzero
= true;
2289 tree z
= build_int_cst (TREE_TYPE (arg
), 0);
2290 ipa_set_jfunc_vr (jfunc
, VR_ANTI_RANGE
, z
, z
);
2293 gcc_assert (!jfunc
->m_vr
);
2297 if (TREE_CODE (arg
) == SSA_NAME
2299 && get_range_query (cfun
)->range_of_expr (vr
, arg
)
2300 && !vr
.undefined_p ())
2303 range_fold_unary_expr (&resvr
, NOP_EXPR
, param_type
,
2304 &vr
, TREE_TYPE (arg
));
2305 if (!resvr
.undefined_p () && !resvr
.varying_p ())
2306 ipa_set_jfunc_vr (jfunc
, &resvr
);
2308 gcc_assert (!jfunc
->m_vr
);
2311 gcc_assert (!jfunc
->m_vr
);
2314 if (INTEGRAL_TYPE_P (TREE_TYPE (arg
))
2315 && (TREE_CODE (arg
) == SSA_NAME
|| TREE_CODE (arg
) == INTEGER_CST
))
2317 if (TREE_CODE (arg
) == SSA_NAME
)
2318 ipa_set_jfunc_bits (jfunc
, 0,
2319 widest_int::from (get_nonzero_bits (arg
),
2320 TYPE_SIGN (TREE_TYPE (arg
))));
2322 ipa_set_jfunc_bits (jfunc
, wi::to_widest (arg
), 0);
2324 else if (POINTER_TYPE_P (TREE_TYPE (arg
)))
2326 unsigned HOST_WIDE_INT bitpos
;
2329 get_pointer_alignment_1 (arg
, &align
, &bitpos
);
2330 widest_int mask
= wi::bit_and_not
2331 (wi::mask
<widest_int
> (TYPE_PRECISION (TREE_TYPE (arg
)), false),
2332 align
/ BITS_PER_UNIT
- 1);
2333 widest_int value
= bitpos
/ BITS_PER_UNIT
;
2334 ipa_set_jfunc_bits (jfunc
, value
, mask
);
2337 gcc_assert (!jfunc
->bits
);
2339 if (is_gimple_ip_invariant (arg
)
2341 && is_global_var (arg
)
2342 && TREE_READONLY (arg
)))
2343 ipa_set_jf_constant (jfunc
, arg
, cs
);
2344 else if (!is_gimple_reg_type (TREE_TYPE (arg
))
2345 && TREE_CODE (arg
) == PARM_DECL
)
2347 int index
= ipa_get_param_decl_index (info
, arg
);
2349 gcc_assert (index
>=0);
2350 /* Aggregate passed by value, check for pass-through, otherwise we
2351 will attempt to fill in aggregate contents later in this
2353 if (parm_preserved_before_stmt_p (fbi
, index
, call
, arg
))
2355 ipa_set_jf_simple_pass_through (jfunc
, index
, false);
2359 else if (TREE_CODE (arg
) == SSA_NAME
)
2361 if (SSA_NAME_IS_DEFAULT_DEF (arg
))
2363 int index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (arg
));
2367 agg_p
= parm_ref_data_pass_through_p (fbi
, index
, call
, arg
);
2368 ipa_set_jf_simple_pass_through (jfunc
, index
, agg_p
);
2373 gimple
*stmt
= SSA_NAME_DEF_STMT (arg
);
2374 if (is_gimple_assign (stmt
))
2375 compute_complex_assign_jump_func (fbi
, info
, jfunc
,
2376 call
, stmt
, arg
, param_type
);
2377 else if (gimple_code (stmt
) == GIMPLE_PHI
)
2378 compute_complex_ancestor_jump_func (fbi
, info
, jfunc
,
2380 as_a
<gphi
*> (stmt
));
2384 /* If ARG is pointer, we cannot use its type to determine the type of aggregate
2385 passed (because type conversions are ignored in gimple). Usually we can
2386 safely get type from function declaration, but in case of K&R prototypes or
2387 variadic functions we can try our luck with type of the pointer passed.
2388 TODO: Since we look for actual initialization of the memory object, we may better
2389 work out the type based on the memory stores we find. */
2391 param_type
= TREE_TYPE (arg
);
2393 if ((jfunc
->type
!= IPA_JF_PASS_THROUGH
2394 || !ipa_get_jf_pass_through_agg_preserved (jfunc
))
2395 && (jfunc
->type
!= IPA_JF_ANCESTOR
2396 || !ipa_get_jf_ancestor_agg_preserved (jfunc
))
2397 && (AGGREGATE_TYPE_P (TREE_TYPE (arg
))
2398 || POINTER_TYPE_P (param_type
)))
2399 determine_known_aggregate_parts (fbi
, call
, arg
, param_type
, jfunc
);
2401 if (!useful_context
)
2402 vec_free (args
->polymorphic_call_contexts
);
2405 /* Compute jump functions for all edges - both direct and indirect - outgoing
2409 ipa_compute_jump_functions_for_bb (struct ipa_func_body_info
*fbi
, basic_block bb
)
2411 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
2413 struct cgraph_edge
*cs
;
2415 FOR_EACH_VEC_ELT_REVERSE (bi
->cg_edges
, i
, cs
)
2417 struct cgraph_node
*callee
= cs
->callee
;
2421 callee
= callee
->ultimate_alias_target ();
2422 /* We do not need to bother analyzing calls to unknown functions
2423 unless they may become known during lto/whopr. */
2424 if (!callee
->definition
&& !flag_lto
2425 && !gimple_call_fnspec (cs
->call_stmt
).known_p ())
2428 ipa_compute_jump_functions_for_edge (fbi
, cs
);
2432 /* If STMT looks like a statement loading a value from a member pointer formal
2433 parameter, return that parameter and store the offset of the field to
2434 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
2435 might be clobbered). If USE_DELTA, then we look for a use of the delta
2436 field rather than the pfn. */
2439 ipa_get_stmt_member_ptr_load_param (gimple
*stmt
, bool use_delta
,
2440 HOST_WIDE_INT
*offset_p
)
2442 tree rhs
, rec
, ref_field
, ref_offset
, fld
, ptr_field
, delta_field
;
2444 if (!gimple_assign_single_p (stmt
))
2447 rhs
= gimple_assign_rhs1 (stmt
);
2448 if (TREE_CODE (rhs
) == COMPONENT_REF
)
2450 ref_field
= TREE_OPERAND (rhs
, 1);
2451 rhs
= TREE_OPERAND (rhs
, 0);
2454 ref_field
= NULL_TREE
;
2455 if (TREE_CODE (rhs
) != MEM_REF
)
2457 rec
= TREE_OPERAND (rhs
, 0);
2458 if (TREE_CODE (rec
) != ADDR_EXPR
)
2460 rec
= TREE_OPERAND (rec
, 0);
2461 if (TREE_CODE (rec
) != PARM_DECL
2462 || !type_like_member_ptr_p (TREE_TYPE (rec
), &ptr_field
, &delta_field
))
2464 ref_offset
= TREE_OPERAND (rhs
, 1);
2471 *offset_p
= int_bit_position (fld
);
2475 if (integer_nonzerop (ref_offset
))
2477 return ref_field
== fld
? rec
: NULL_TREE
;
2480 return tree_int_cst_equal (byte_position (fld
), ref_offset
) ? rec
2484 /* Returns true iff T is an SSA_NAME defined by a statement. */
2487 ipa_is_ssa_with_stmt_def (tree t
)
2489 if (TREE_CODE (t
) == SSA_NAME
2490 && !SSA_NAME_IS_DEFAULT_DEF (t
))
2496 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2497 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2498 indirect call graph edge.
2499 If POLYMORPHIC is true record is as a destination of polymorphic call. */
2501 static struct cgraph_edge
*
2502 ipa_note_param_call (struct cgraph_node
*node
, int param_index
,
2503 gcall
*stmt
, bool polymorphic
)
2505 struct cgraph_edge
*cs
;
2507 cs
= node
->get_edge (stmt
);
2508 cs
->indirect_info
->param_index
= param_index
;
2509 cs
->indirect_info
->agg_contents
= 0;
2510 cs
->indirect_info
->member_ptr
= 0;
2511 cs
->indirect_info
->guaranteed_unmodified
= 0;
2512 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
2513 ipa_set_param_used_by_indirect_call (info
, param_index
, true);
2514 if (cs
->indirect_info
->polymorphic
|| polymorphic
)
2515 ipa_set_param_used_by_polymorphic_call (info
, param_index
, true);
2519 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2520 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2521 intermediate information about each formal parameter. Currently it checks
2522 whether the call calls a pointer that is a formal parameter and if so, the
2523 parameter is marked with the called flag and an indirect call graph edge
2524 describing the call is created. This is very simple for ordinary pointers
2525 represented in SSA but not-so-nice when it comes to member pointers. The
2526 ugly part of this function does nothing more than trying to match the
2527 pattern of such a call. An example of such a pattern is the gimple dump
2528 below, the call is on the last line:
2531 f$__delta_5 = f.__delta;
2532 f$__pfn_24 = f.__pfn;
2536 f$__delta_5 = MEM[(struct *)&f];
2537 f$__pfn_24 = MEM[(struct *)&f + 4B];
2539 and a few lines below:
2542 D.2496_3 = (int) f$__pfn_24;
2543 D.2497_4 = D.2496_3 & 1;
2550 D.2500_7 = (unsigned int) f$__delta_5;
2551 D.2501_8 = &S + D.2500_7;
2552 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2553 D.2503_10 = *D.2502_9;
2554 D.2504_12 = f$__pfn_24 + -1;
2555 D.2505_13 = (unsigned int) D.2504_12;
2556 D.2506_14 = D.2503_10 + D.2505_13;
2557 D.2507_15 = *D.2506_14;
2558 iftmp.11_16 = (String:: *) D.2507_15;
2561 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2562 D.2500_19 = (unsigned int) f$__delta_5;
2563 D.2508_20 = &S + D.2500_19;
2564 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2566 Such patterns are results of simple calls to a member pointer:
2568 int doprinting (int (MyString::* f)(int) const)
2570 MyString S ("somestring");
2575 Moreover, the function also looks for called pointers loaded from aggregates
2576 passed by value or reference. */
2579 ipa_analyze_indirect_call_uses (struct ipa_func_body_info
*fbi
, gcall
*call
,
2582 class ipa_node_params
*info
= fbi
->info
;
2583 HOST_WIDE_INT offset
;
2586 if (SSA_NAME_IS_DEFAULT_DEF (target
))
2588 tree var
= SSA_NAME_VAR (target
);
2589 int index
= ipa_get_param_decl_index (info
, var
);
2591 ipa_note_param_call (fbi
->node
, index
, call
, false);
2596 gimple
*def
= SSA_NAME_DEF_STMT (target
);
2597 bool guaranteed_unmodified
;
2598 if (gimple_assign_single_p (def
)
2599 && ipa_load_from_parm_agg (fbi
, info
->descriptors
, def
,
2600 gimple_assign_rhs1 (def
), &index
, &offset
,
2601 NULL
, &by_ref
, &guaranteed_unmodified
))
2603 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
,
2605 cs
->indirect_info
->offset
= offset
;
2606 cs
->indirect_info
->agg_contents
= 1;
2607 cs
->indirect_info
->by_ref
= by_ref
;
2608 cs
->indirect_info
->guaranteed_unmodified
= guaranteed_unmodified
;
2612 /* Now we need to try to match the complex pattern of calling a member
2614 if (gimple_code (def
) != GIMPLE_PHI
2615 || gimple_phi_num_args (def
) != 2
2616 || !POINTER_TYPE_P (TREE_TYPE (target
))
2617 || TREE_CODE (TREE_TYPE (TREE_TYPE (target
))) != METHOD_TYPE
)
2620 /* First, we need to check whether one of these is a load from a member
2621 pointer that is a parameter to this function. */
2622 tree n1
= PHI_ARG_DEF (def
, 0);
2623 tree n2
= PHI_ARG_DEF (def
, 1);
2624 if (!ipa_is_ssa_with_stmt_def (n1
) || !ipa_is_ssa_with_stmt_def (n2
))
2626 gimple
*d1
= SSA_NAME_DEF_STMT (n1
);
2627 gimple
*d2
= SSA_NAME_DEF_STMT (n2
);
2630 basic_block bb
, virt_bb
;
2631 basic_block join
= gimple_bb (def
);
2632 if ((rec
= ipa_get_stmt_member_ptr_load_param (d1
, false, &offset
)))
2634 if (ipa_get_stmt_member_ptr_load_param (d2
, false, NULL
))
2637 bb
= EDGE_PRED (join
, 0)->src
;
2638 virt_bb
= gimple_bb (d2
);
2640 else if ((rec
= ipa_get_stmt_member_ptr_load_param (d2
, false, &offset
)))
2642 bb
= EDGE_PRED (join
, 1)->src
;
2643 virt_bb
= gimple_bb (d1
);
2648 /* Second, we need to check that the basic blocks are laid out in the way
2649 corresponding to the pattern. */
2651 if (!single_pred_p (virt_bb
) || !single_succ_p (virt_bb
)
2652 || single_pred (virt_bb
) != bb
2653 || single_succ (virt_bb
) != join
)
2656 /* Third, let's see that the branching is done depending on the least
2657 significant bit of the pfn. */
2659 gimple
*branch
= last_stmt (bb
);
2660 if (!branch
|| gimple_code (branch
) != GIMPLE_COND
)
2663 if ((gimple_cond_code (branch
) != NE_EXPR
2664 && gimple_cond_code (branch
) != EQ_EXPR
)
2665 || !integer_zerop (gimple_cond_rhs (branch
)))
2668 tree cond
= gimple_cond_lhs (branch
);
2669 if (!ipa_is_ssa_with_stmt_def (cond
))
2672 def
= SSA_NAME_DEF_STMT (cond
);
2673 if (!is_gimple_assign (def
)
2674 || gimple_assign_rhs_code (def
) != BIT_AND_EXPR
2675 || !integer_onep (gimple_assign_rhs2 (def
)))
2678 cond
= gimple_assign_rhs1 (def
);
2679 if (!ipa_is_ssa_with_stmt_def (cond
))
2682 def
= SSA_NAME_DEF_STMT (cond
);
2684 if (is_gimple_assign (def
)
2685 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def
)))
2687 cond
= gimple_assign_rhs1 (def
);
2688 if (!ipa_is_ssa_with_stmt_def (cond
))
2690 def
= SSA_NAME_DEF_STMT (cond
);
2694 rec2
= ipa_get_stmt_member_ptr_load_param (def
,
2695 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2696 == ptrmemfunc_vbit_in_delta
),
2701 index
= ipa_get_param_decl_index (info
, rec
);
2703 && parm_preserved_before_stmt_p (fbi
, index
, call
, rec
))
2705 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
,
2707 cs
->indirect_info
->offset
= offset
;
2708 cs
->indirect_info
->agg_contents
= 1;
2709 cs
->indirect_info
->member_ptr
= 1;
2710 cs
->indirect_info
->guaranteed_unmodified
= 1;
2716 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2717 object referenced in the expression is a formal parameter of the caller
2718 FBI->node (described by FBI->info), create a call note for the
2722 ipa_analyze_virtual_call_uses (struct ipa_func_body_info
*fbi
,
2723 gcall
*call
, tree target
)
2725 tree obj
= OBJ_TYPE_REF_OBJECT (target
);
2727 HOST_WIDE_INT anc_offset
;
2729 if (!flag_devirtualize
)
2732 if (TREE_CODE (obj
) != SSA_NAME
)
2735 class ipa_node_params
*info
= fbi
->info
;
2736 if (SSA_NAME_IS_DEFAULT_DEF (obj
))
2738 if (TREE_CODE (SSA_NAME_VAR (obj
)) != PARM_DECL
)
2742 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (obj
));
2743 gcc_assert (index
>= 0);
2744 if (detect_type_change_ssa (fbi
, obj
, obj_type_ref_class (target
),
2750 gimple
*stmt
= SSA_NAME_DEF_STMT (obj
);
2753 expr
= get_ancestor_addr_info (stmt
, &obj
, &anc_offset
);
2756 index
= ipa_get_param_decl_index (info
,
2757 SSA_NAME_VAR (TREE_OPERAND (expr
, 0)));
2758 gcc_assert (index
>= 0);
2759 if (detect_type_change (fbi
, obj
, expr
, obj_type_ref_class (target
),
2764 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
,
2766 class cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
2767 ii
->offset
= anc_offset
;
2768 ii
->otr_token
= tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target
));
2769 ii
->otr_type
= obj_type_ref_class (target
);
2770 ii
->polymorphic
= 1;
2773 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2774 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2775 containing intermediate information about each formal parameter. */
2778 ipa_analyze_call_uses (struct ipa_func_body_info
*fbi
, gcall
*call
)
2780 tree target
= gimple_call_fn (call
);
2783 || (TREE_CODE (target
) != SSA_NAME
2784 && !virtual_method_call_p (target
)))
2787 struct cgraph_edge
*cs
= fbi
->node
->get_edge (call
);
2788 /* If we previously turned the call into a direct call, there is
2789 no need to analyze. */
2790 if (cs
&& !cs
->indirect_unknown_callee
)
2793 if (cs
->indirect_info
->polymorphic
&& flag_devirtualize
)
2796 tree target
= gimple_call_fn (call
);
2797 ipa_polymorphic_call_context
context (current_function_decl
,
2798 target
, call
, &instance
);
2800 gcc_checking_assert (cs
->indirect_info
->otr_type
2801 == obj_type_ref_class (target
));
2802 gcc_checking_assert (cs
->indirect_info
->otr_token
2803 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target
)));
2805 cs
->indirect_info
->vptr_changed
2806 = !context
.get_dynamic_type (instance
,
2807 OBJ_TYPE_REF_OBJECT (target
),
2808 obj_type_ref_class (target
), call
,
2809 &fbi
->aa_walk_budget
);
2810 cs
->indirect_info
->context
= context
;
2813 if (TREE_CODE (target
) == SSA_NAME
)
2814 ipa_analyze_indirect_call_uses (fbi
, call
, target
);
2815 else if (virtual_method_call_p (target
))
2816 ipa_analyze_virtual_call_uses (fbi
, call
, target
);
2820 /* Analyze the call statement STMT with respect to formal parameters (described
2821 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2822 formal parameters are called. */
2825 ipa_analyze_stmt_uses (struct ipa_func_body_info
*fbi
, gimple
*stmt
)
2827 if (is_gimple_call (stmt
))
2828 ipa_analyze_call_uses (fbi
, as_a
<gcall
*> (stmt
));
2831 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2832 If OP is a parameter declaration, mark it as used in the info structure
2836 visit_ref_for_mod_analysis (gimple
*, tree op
, tree
, void *data
)
2838 class ipa_node_params
*info
= (class ipa_node_params
*) data
;
2840 op
= get_base_address (op
);
2842 && TREE_CODE (op
) == PARM_DECL
)
2844 int index
= ipa_get_param_decl_index (info
, op
);
2845 gcc_assert (index
>= 0);
2846 ipa_set_param_used (info
, index
, true);
2852 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2853 the findings in various structures of the associated ipa_node_params
2854 structure, such as parameter flags, notes etc. FBI holds various data about
2855 the function being analyzed. */
2858 ipa_analyze_params_uses_in_bb (struct ipa_func_body_info
*fbi
, basic_block bb
)
2860 gimple_stmt_iterator gsi
;
2861 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2863 gimple
*stmt
= gsi_stmt (gsi
);
2865 if (is_gimple_debug (stmt
))
2868 ipa_analyze_stmt_uses (fbi
, stmt
);
2869 walk_stmt_load_store_addr_ops (stmt
, fbi
->info
,
2870 visit_ref_for_mod_analysis
,
2871 visit_ref_for_mod_analysis
,
2872 visit_ref_for_mod_analysis
);
2874 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2875 walk_stmt_load_store_addr_ops (gsi_stmt (gsi
), fbi
->info
,
2876 visit_ref_for_mod_analysis
,
2877 visit_ref_for_mod_analysis
,
2878 visit_ref_for_mod_analysis
);
2881 /* Return true EXPR is a load from a dereference of SSA_NAME NAME. */
2884 load_from_dereferenced_name (tree expr
, tree name
)
2886 tree base
= get_base_address (expr
);
2887 return (TREE_CODE (base
) == MEM_REF
2888 && TREE_OPERAND (base
, 0) == name
);
2891 /* Calculate controlled uses of parameters of NODE. */
2894 ipa_analyze_controlled_uses (struct cgraph_node
*node
)
2896 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
2898 for (int i
= 0; i
< ipa_get_param_count (info
); i
++)
2900 tree parm
= ipa_get_param (info
, i
);
2902 bool load_dereferenced
= false;
2904 /* For SSA regs see if parameter is used. For non-SSA we compute
2905 the flag during modification analysis. */
2906 if (is_gimple_reg (parm
))
2908 tree ddef
= ssa_default_def (DECL_STRUCT_FUNCTION (node
->decl
),
2910 if (ddef
&& !has_zero_uses (ddef
))
2912 imm_use_iterator imm_iter
;
2915 ipa_set_param_used (info
, i
, true);
2916 FOR_EACH_IMM_USE_STMT (stmt
, imm_iter
, ddef
)
2918 if (is_gimple_debug (stmt
))
2921 int all_stmt_uses
= 0;
2922 use_operand_p use_p
;
2923 FOR_EACH_IMM_USE_ON_STMT (use_p
, imm_iter
)
2926 if (is_gimple_call (stmt
))
2928 if (gimple_call_internal_p (stmt
))
2930 call_uses
= IPA_UNDESCRIBED_USE
;
2933 int recognized_stmt_uses
;
2934 if (gimple_call_fn (stmt
) == ddef
)
2935 recognized_stmt_uses
= 1;
2937 recognized_stmt_uses
= 0;
2938 unsigned arg_count
= gimple_call_num_args (stmt
);
2939 for (unsigned i
= 0; i
< arg_count
; i
++)
2941 tree arg
= gimple_call_arg (stmt
, i
);
2943 recognized_stmt_uses
++;
2944 else if (load_from_dereferenced_name (arg
, ddef
))
2946 load_dereferenced
= true;
2947 recognized_stmt_uses
++;
2951 if (recognized_stmt_uses
!= all_stmt_uses
)
2953 call_uses
= IPA_UNDESCRIBED_USE
;
2957 call_uses
+= all_stmt_uses
;
2959 else if (gimple_assign_single_p (stmt
))
2961 tree rhs
= gimple_assign_rhs1 (stmt
);
2962 if (all_stmt_uses
!= 1
2963 || !load_from_dereferenced_name (rhs
, ddef
))
2965 call_uses
= IPA_UNDESCRIBED_USE
;
2968 load_dereferenced
= true;
2972 call_uses
= IPA_UNDESCRIBED_USE
;
2981 call_uses
= IPA_UNDESCRIBED_USE
;
2982 ipa_set_controlled_uses (info
, i
, call_uses
);
2983 ipa_set_param_load_dereferenced (info
, i
, load_dereferenced
);
2987 /* Free stuff in BI. */
2990 free_ipa_bb_info (struct ipa_bb_info
*bi
)
2992 bi
->cg_edges
.release ();
2993 bi
->param_aa_statuses
.release ();
2996 /* Dominator walker driving the analysis. */
2998 class analysis_dom_walker
: public dom_walker
3001 analysis_dom_walker (struct ipa_func_body_info
*fbi
)
3002 : dom_walker (CDI_DOMINATORS
), m_fbi (fbi
) {}
3004 virtual edge
before_dom_children (basic_block
);
3007 struct ipa_func_body_info
*m_fbi
;
3011 analysis_dom_walker::before_dom_children (basic_block bb
)
3013 ipa_analyze_params_uses_in_bb (m_fbi
, bb
);
3014 ipa_compute_jump_functions_for_bb (m_fbi
, bb
);
3018 /* Release body info FBI. */
3021 ipa_release_body_info (struct ipa_func_body_info
*fbi
)
3024 struct ipa_bb_info
*bi
;
3026 FOR_EACH_VEC_ELT (fbi
->bb_infos
, i
, bi
)
3027 free_ipa_bb_info (bi
);
3028 fbi
->bb_infos
.release ();
3031 /* Initialize the array describing properties of formal parameters
3032 of NODE, analyze their uses and compute jump functions associated
3033 with actual arguments of calls from within NODE. */
3036 ipa_analyze_node (struct cgraph_node
*node
)
3038 struct ipa_func_body_info fbi
;
3039 class ipa_node_params
*info
;
3041 ipa_check_create_node_params ();
3042 ipa_check_create_edge_args ();
3043 info
= ipa_node_params_sum
->get_create (node
);
3045 if (info
->analysis_done
)
3047 info
->analysis_done
= 1;
3049 if (ipa_func_spec_opts_forbid_analysis_p (node
))
3051 for (int i
= 0; i
< ipa_get_param_count (info
); i
++)
3053 ipa_set_param_used (info
, i
, true);
3054 ipa_set_controlled_uses (info
, i
, IPA_UNDESCRIBED_USE
);
3059 struct function
*func
= DECL_STRUCT_FUNCTION (node
->decl
);
3061 calculate_dominance_info (CDI_DOMINATORS
);
3062 ipa_initialize_node_params (node
);
3063 ipa_analyze_controlled_uses (node
);
3067 fbi
.bb_infos
= vNULL
;
3068 fbi
.bb_infos
.safe_grow_cleared (last_basic_block_for_fn (cfun
), true);
3069 fbi
.param_count
= ipa_get_param_count (info
);
3070 fbi
.aa_walk_budget
= opt_for_fn (node
->decl
, param_ipa_max_aa_steps
);
3072 for (struct cgraph_edge
*cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
3074 ipa_bb_info
*bi
= ipa_get_bb_info (&fbi
, gimple_bb (cs
->call_stmt
));
3075 bi
->cg_edges
.safe_push (cs
);
3078 for (struct cgraph_edge
*cs
= node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
3080 ipa_bb_info
*bi
= ipa_get_bb_info (&fbi
, gimple_bb (cs
->call_stmt
));
3081 bi
->cg_edges
.safe_push (cs
);
3084 analysis_dom_walker (&fbi
).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
3086 ipa_release_body_info (&fbi
);
3087 free_dominance_info (CDI_DOMINATORS
);
3091 /* Update the jump functions associated with call graph edge E when the call
3092 graph edge CS is being inlined, assuming that E->caller is already (possibly
3093 indirectly) inlined into CS->callee and that E has not been inlined. */
3096 update_jump_functions_after_inlining (struct cgraph_edge
*cs
,
3097 struct cgraph_edge
*e
)
3099 ipa_edge_args
*top
= ipa_edge_args_sum
->get (cs
);
3100 ipa_edge_args
*args
= ipa_edge_args_sum
->get (e
);
3103 int count
= ipa_get_cs_argument_count (args
);
3106 for (i
= 0; i
< count
; i
++)
3108 struct ipa_jump_func
*dst
= ipa_get_ith_jump_func (args
, i
);
3109 class ipa_polymorphic_call_context
*dst_ctx
3110 = ipa_get_ith_polymorhic_call_context (args
, i
);
3114 struct ipa_agg_jf_item
*item
;
3117 FOR_EACH_VEC_ELT (*dst
->agg
.items
, j
, item
)
3120 struct ipa_jump_func
*src
;
3122 if (item
->jftype
!= IPA_JF_PASS_THROUGH
3123 && item
->jftype
!= IPA_JF_LOAD_AGG
)
3126 dst_fid
= item
->value
.pass_through
.formal_id
;
3127 if (!top
|| dst_fid
>= ipa_get_cs_argument_count (top
))
3129 item
->jftype
= IPA_JF_UNKNOWN
;
3133 item
->value
.pass_through
.formal_id
= -1;
3134 src
= ipa_get_ith_jump_func (top
, dst_fid
);
3135 if (src
->type
== IPA_JF_CONST
)
3137 if (item
->jftype
== IPA_JF_PASS_THROUGH
3138 && item
->value
.pass_through
.operation
== NOP_EXPR
)
3140 item
->jftype
= IPA_JF_CONST
;
3141 item
->value
.constant
= src
->value
.constant
.value
;
3145 else if (src
->type
== IPA_JF_PASS_THROUGH
3146 && src
->value
.pass_through
.operation
== NOP_EXPR
)
3148 if (item
->jftype
== IPA_JF_PASS_THROUGH
3149 || !item
->value
.load_agg
.by_ref
3150 || src
->value
.pass_through
.agg_preserved
)
3151 item
->value
.pass_through
.formal_id
3152 = src
->value
.pass_through
.formal_id
;
3154 else if (src
->type
== IPA_JF_ANCESTOR
)
3156 if (item
->jftype
== IPA_JF_PASS_THROUGH
)
3158 if (!src
->value
.ancestor
.offset
)
3159 item
->value
.pass_through
.formal_id
3160 = src
->value
.ancestor
.formal_id
;
3162 else if (src
->value
.ancestor
.agg_preserved
)
3164 gcc_checking_assert (item
->value
.load_agg
.by_ref
);
3166 item
->value
.pass_through
.formal_id
3167 = src
->value
.ancestor
.formal_id
;
3168 item
->value
.load_agg
.offset
3169 += src
->value
.ancestor
.offset
;
3173 if (item
->value
.pass_through
.formal_id
< 0)
3174 item
->jftype
= IPA_JF_UNKNOWN
;
3180 ipa_set_jf_unknown (dst
);
3184 if (dst
->type
== IPA_JF_ANCESTOR
)
3186 struct ipa_jump_func
*src
;
3187 int dst_fid
= dst
->value
.ancestor
.formal_id
;
3188 class ipa_polymorphic_call_context
*src_ctx
3189 = ipa_get_ith_polymorhic_call_context (top
, dst_fid
);
3191 /* Variable number of arguments can cause havoc if we try to access
3192 one that does not exist in the inlined edge. So make sure we
3194 if (dst_fid
>= ipa_get_cs_argument_count (top
))
3196 ipa_set_jf_unknown (dst
);
3200 src
= ipa_get_ith_jump_func (top
, dst_fid
);
3202 if (src_ctx
&& !src_ctx
->useless_p ())
3204 class ipa_polymorphic_call_context ctx
= *src_ctx
;
3206 /* TODO: Make type preserved safe WRT contexts. */
3207 if (!ipa_get_jf_ancestor_type_preserved (dst
))
3208 ctx
.possible_dynamic_type_change (e
->in_polymorphic_cdtor
);
3209 ctx
.offset_by (dst
->value
.ancestor
.offset
);
3210 if (!ctx
.useless_p ())
3214 vec_safe_grow_cleared (args
->polymorphic_call_contexts
,
3216 dst_ctx
= ipa_get_ith_polymorhic_call_context (args
, i
);
3219 dst_ctx
->combine_with (ctx
);
3223 /* Parameter and argument in ancestor jump function must be pointer
3224 type, which means access to aggregate must be by-reference. */
3225 gcc_assert (!src
->agg
.items
|| src
->agg
.by_ref
);
3227 if (src
->agg
.items
&& dst
->value
.ancestor
.agg_preserved
)
3229 struct ipa_agg_jf_item
*item
;
3232 /* Currently we do not produce clobber aggregate jump functions,
3233 replace with merging when we do. */
3234 gcc_assert (!dst
->agg
.items
);
3236 dst
->agg
.items
= vec_safe_copy (src
->agg
.items
);
3237 dst
->agg
.by_ref
= src
->agg
.by_ref
;
3238 FOR_EACH_VEC_SAFE_ELT (dst
->agg
.items
, j
, item
)
3239 item
->offset
-= dst
->value
.ancestor
.offset
;
3242 if (src
->type
== IPA_JF_PASS_THROUGH
3243 && src
->value
.pass_through
.operation
== NOP_EXPR
)
3245 dst
->value
.ancestor
.formal_id
= src
->value
.pass_through
.formal_id
;
3246 dst
->value
.ancestor
.agg_preserved
&=
3247 src
->value
.pass_through
.agg_preserved
;
3249 else if (src
->type
== IPA_JF_ANCESTOR
)
3251 dst
->value
.ancestor
.formal_id
= src
->value
.ancestor
.formal_id
;
3252 dst
->value
.ancestor
.offset
+= src
->value
.ancestor
.offset
;
3253 dst
->value
.ancestor
.agg_preserved
&=
3254 src
->value
.ancestor
.agg_preserved
;
3257 ipa_set_jf_unknown (dst
);
3259 else if (dst
->type
== IPA_JF_PASS_THROUGH
)
3261 struct ipa_jump_func
*src
;
3262 /* We must check range due to calls with variable number of arguments
3263 and we cannot combine jump functions with operations. */
3264 if (dst
->value
.pass_through
.operation
== NOP_EXPR
3265 && (top
&& dst
->value
.pass_through
.formal_id
3266 < ipa_get_cs_argument_count (top
)))
3268 int dst_fid
= dst
->value
.pass_through
.formal_id
;
3269 src
= ipa_get_ith_jump_func (top
, dst_fid
);
3270 bool dst_agg_p
= ipa_get_jf_pass_through_agg_preserved (dst
);
3271 class ipa_polymorphic_call_context
*src_ctx
3272 = ipa_get_ith_polymorhic_call_context (top
, dst_fid
);
3274 if (src_ctx
&& !src_ctx
->useless_p ())
3276 class ipa_polymorphic_call_context ctx
= *src_ctx
;
3278 /* TODO: Make type preserved safe WRT contexts. */
3279 if (!ipa_get_jf_pass_through_type_preserved (dst
))
3280 ctx
.possible_dynamic_type_change (e
->in_polymorphic_cdtor
);
3281 if (!ctx
.useless_p ())
3285 vec_safe_grow_cleared (args
->polymorphic_call_contexts
,
3287 dst_ctx
= ipa_get_ith_polymorhic_call_context (args
, i
);
3289 dst_ctx
->combine_with (ctx
);
3294 case IPA_JF_UNKNOWN
:
3295 ipa_set_jf_unknown (dst
);
3298 ipa_set_jf_cst_copy (dst
, src
);
3301 case IPA_JF_PASS_THROUGH
:
3303 int formal_id
= ipa_get_jf_pass_through_formal_id (src
);
3304 enum tree_code operation
;
3305 operation
= ipa_get_jf_pass_through_operation (src
);
3307 if (operation
== NOP_EXPR
)
3311 && ipa_get_jf_pass_through_agg_preserved (src
);
3312 ipa_set_jf_simple_pass_through (dst
, formal_id
, agg_p
);
3314 else if (TREE_CODE_CLASS (operation
) == tcc_unary
)
3315 ipa_set_jf_unary_pass_through (dst
, formal_id
, operation
);
3318 tree operand
= ipa_get_jf_pass_through_operand (src
);
3319 ipa_set_jf_arith_pass_through (dst
, formal_id
, operand
,
3324 case IPA_JF_ANCESTOR
:
3328 && ipa_get_jf_ancestor_agg_preserved (src
);
3329 ipa_set_ancestor_jf (dst
,
3330 ipa_get_jf_ancestor_offset (src
),
3331 ipa_get_jf_ancestor_formal_id (src
),
3340 && (dst_agg_p
|| !src
->agg
.by_ref
))
3342 /* Currently we do not produce clobber aggregate jump
3343 functions, replace with merging when we do. */
3344 gcc_assert (!dst
->agg
.items
);
3346 dst
->agg
.by_ref
= src
->agg
.by_ref
;
3347 dst
->agg
.items
= vec_safe_copy (src
->agg
.items
);
3351 ipa_set_jf_unknown (dst
);
3356 /* If TARGET is an addr_expr of a function declaration, make it the
3357 (SPECULATIVE)destination of an indirect edge IE and return the edge.
3358 Otherwise, return NULL. */
3360 struct cgraph_edge
*
3361 ipa_make_edge_direct_to_target (struct cgraph_edge
*ie
, tree target
,
3364 struct cgraph_node
*callee
;
3365 bool unreachable
= false;
3367 if (TREE_CODE (target
) == ADDR_EXPR
)
3368 target
= TREE_OPERAND (target
, 0);
3369 if (TREE_CODE (target
) != FUNCTION_DECL
)
3371 target
= canonicalize_constructor_val (target
, NULL
);
3372 if (!target
|| TREE_CODE (target
) != FUNCTION_DECL
)
3374 /* Member pointer call that goes through a VMT lookup. */
3375 if (ie
->indirect_info
->member_ptr
3376 /* Or if target is not an invariant expression and we do not
3377 know if it will evaulate to function at runtime.
3378 This can happen when folding through &VAR, where &VAR
3379 is IP invariant, but VAR itself is not.
3381 TODO: Revisit this when GCC 5 is branched. It seems that
3382 member_ptr check is not needed and that we may try to fold
3383 the expression and see if VAR is readonly. */
3384 || !is_gimple_ip_invariant (target
))
3386 if (dump_enabled_p ())
3388 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, ie
->call_stmt
,
3389 "discovered direct call non-invariant %s\n",
3390 ie
->caller
->dump_name ());
3396 if (dump_enabled_p ())
3398 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, ie
->call_stmt
,
3399 "discovered direct call to non-function in %s, "
3400 "making it __builtin_unreachable\n",
3401 ie
->caller
->dump_name ());
3404 target
= builtin_decl_implicit (BUILT_IN_UNREACHABLE
);
3405 callee
= cgraph_node::get_create (target
);
3409 callee
= cgraph_node::get (target
);
3412 callee
= cgraph_node::get (target
);
3414 /* Because may-edges are not explicitely represented and vtable may be external,
3415 we may create the first reference to the object in the unit. */
3416 if (!callee
|| callee
->inlined_to
)
3419 /* We are better to ensure we can refer to it.
3420 In the case of static functions we are out of luck, since we already
3421 removed its body. In the case of public functions we may or may
3422 not introduce the reference. */
3423 if (!canonicalize_constructor_val (target
, NULL
)
3424 || !TREE_PUBLIC (target
))
3427 fprintf (dump_file
, "ipa-prop: Discovered call to a known target "
3428 "(%s -> %s) but cannot refer to it. Giving up.\n",
3429 ie
->caller
->dump_name (),
3430 ie
->callee
->dump_name ());
3433 callee
= cgraph_node::get_create (target
);
3436 /* If the edge is already speculated. */
3437 if (speculative
&& ie
->speculative
)
3441 cgraph_edge
*e2
= ie
->speculative_call_for_target (callee
);
3445 fprintf (dump_file
, "ipa-prop: Discovered call to a "
3446 "speculative target (%s -> %s) but the call is "
3447 "already speculated to different target. "
3449 ie
->caller
->dump_name (), callee
->dump_name ());
3455 "ipa-prop: Discovered call to a speculative target "
3456 "(%s -> %s) this agree with previous speculation.\n",
3457 ie
->caller
->dump_name (), callee
->dump_name ());
3463 if (!dbg_cnt (devirt
))
3466 ipa_check_create_node_params ();
3468 /* We cannot make edges to inline clones. It is bug that someone removed
3469 the cgraph node too early. */
3470 gcc_assert (!callee
->inlined_to
);
3472 if (dump_file
&& !unreachable
)
3474 fprintf (dump_file
, "ipa-prop: Discovered %s call to a %s target "
3475 "(%s -> %s), for stmt ",
3476 ie
->indirect_info
->polymorphic
? "a virtual" : "an indirect",
3477 speculative
? "speculative" : "known",
3478 ie
->caller
->dump_name (),
3479 callee
->dump_name ());
3481 print_gimple_stmt (dump_file
, ie
->call_stmt
, 2, TDF_SLIM
);
3483 fprintf (dump_file
, "with uid %i\n", ie
->lto_stmt_uid
);
3485 if (dump_enabled_p ())
3487 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, ie
->call_stmt
,
3488 "converting indirect call in %s to direct call to %s\n",
3489 ie
->caller
->dump_name (), callee
->dump_name ());
3493 struct cgraph_edge
*orig
= ie
;
3494 ie
= cgraph_edge::make_direct (ie
, callee
);
3495 /* If we resolved speculative edge the cost is already up to date
3496 for direct call (adjusted by inline_edge_duplication_hook). */
3499 ipa_call_summary
*es
= ipa_call_summaries
->get (ie
);
3500 es
->call_stmt_size
-= (eni_size_weights
.indirect_call_cost
3501 - eni_size_weights
.call_cost
);
3502 es
->call_stmt_time
-= (eni_time_weights
.indirect_call_cost
3503 - eni_time_weights
.call_cost
);
3508 if (!callee
->can_be_discarded_p ())
3511 alias
= dyn_cast
<cgraph_node
*> (callee
->noninterposable_alias ());
3515 /* make_speculative will update ie's cost to direct call cost. */
3516 ie
= ie
->make_speculative
3517 (callee
, ie
->count
.apply_scale (8, 10));
3523 /* Attempt to locate an interprocedural constant at a given REQ_OFFSET in
3524 CONSTRUCTOR and return it. Return NULL if the search fails for some
3528 find_constructor_constant_at_offset (tree constructor
, HOST_WIDE_INT req_offset
)
3530 tree type
= TREE_TYPE (constructor
);
3531 if (TREE_CODE (type
) != ARRAY_TYPE
3532 && TREE_CODE (type
) != RECORD_TYPE
)
3537 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (constructor
), ix
, index
, val
)
3539 HOST_WIDE_INT elt_offset
;
3540 if (TREE_CODE (type
) == ARRAY_TYPE
)
3543 tree unit_size
= TYPE_SIZE_UNIT (TREE_TYPE (type
));
3544 gcc_assert (TREE_CODE (unit_size
) == INTEGER_CST
);
3548 if (TREE_CODE (index
) == RANGE_EXPR
)
3549 off
= wi::to_offset (TREE_OPERAND (index
, 0));
3551 off
= wi::to_offset (index
);
3552 if (TYPE_DOMAIN (type
) && TYPE_MIN_VALUE (TYPE_DOMAIN (type
)))
3554 tree low_bound
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
3555 gcc_assert (TREE_CODE (unit_size
) == INTEGER_CST
);
3556 off
= wi::sext (off
- wi::to_offset (low_bound
),
3557 TYPE_PRECISION (TREE_TYPE (index
)));
3559 off
*= wi::to_offset (unit_size
);
3560 /* ??? Handle more than just the first index of a
3564 off
= wi::to_offset (unit_size
) * ix
;
3566 off
= wi::lshift (off
, LOG2_BITS_PER_UNIT
);
3567 if (!wi::fits_shwi_p (off
) || wi::neg_p (off
))
3569 elt_offset
= off
.to_shwi ();
3571 else if (TREE_CODE (type
) == RECORD_TYPE
)
3573 gcc_checking_assert (index
&& TREE_CODE (index
) == FIELD_DECL
);
3574 if (DECL_BIT_FIELD (index
))
3576 elt_offset
= int_bit_position (index
);
3581 if (elt_offset
> req_offset
)
3584 if (TREE_CODE (val
) == CONSTRUCTOR
)
3585 return find_constructor_constant_at_offset (val
,
3586 req_offset
- elt_offset
);
3588 if (elt_offset
== req_offset
3589 && is_gimple_reg_type (TREE_TYPE (val
))
3590 && is_gimple_ip_invariant (val
))
3596 /* Check whether SCALAR could be used to look up an aggregate interprocedural
3597 invariant from a static constructor and if so, return it. Otherwise return
3601 ipa_find_agg_cst_from_init (tree scalar
, HOST_WIDE_INT offset
, bool by_ref
)
3605 if (TREE_CODE (scalar
) != ADDR_EXPR
)
3607 scalar
= TREE_OPERAND (scalar
, 0);
3611 || !is_global_var (scalar
)
3612 || !TREE_READONLY (scalar
)
3613 || !DECL_INITIAL (scalar
)
3614 || TREE_CODE (DECL_INITIAL (scalar
)) != CONSTRUCTOR
)
3617 return find_constructor_constant_at_offset (DECL_INITIAL (scalar
), offset
);
3620 /* Retrieve value from AGG, a set of known offset/value for an aggregate or
3621 static initializer of SCALAR (which can be NULL) for the given OFFSET or
3622 return NULL if there is none. BY_REF specifies whether the value has to be
3623 passed by reference or by value. If FROM_GLOBAL_CONSTANT is non-NULL, then
3624 the boolean it points to is set to true if the value comes from an
3625 initializer of a constant. */
3628 ipa_find_agg_cst_for_param (const ipa_agg_value_set
*agg
, tree scalar
,
3629 HOST_WIDE_INT offset
, bool by_ref
,
3630 bool *from_global_constant
)
3632 struct ipa_agg_value
*item
;
3637 tree res
= ipa_find_agg_cst_from_init (scalar
, offset
, by_ref
);
3640 if (from_global_constant
)
3641 *from_global_constant
= true;
3647 || by_ref
!= agg
->by_ref
)
3650 FOR_EACH_VEC_ELT (agg
->items
, i
, item
)
3651 if (item
->offset
== offset
)
3653 /* Currently we do not have clobber values, return NULL for them once
3655 gcc_checking_assert (is_gimple_ip_invariant (item
->value
));
3656 if (from_global_constant
)
3657 *from_global_constant
= false;
3663 /* Remove a reference to SYMBOL from the list of references of a node given by
3664 reference description RDESC. Return true if the reference has been
3665 successfully found and removed. */
3668 remove_described_reference (symtab_node
*symbol
, struct ipa_cst_ref_desc
*rdesc
)
3670 struct ipa_ref
*to_del
;
3671 struct cgraph_edge
*origin
;
3676 to_del
= origin
->caller
->find_reference (symbol
, origin
->call_stmt
,
3677 origin
->lto_stmt_uid
);
3681 to_del
->remove_reference ();
3683 fprintf (dump_file
, "ipa-prop: Removed a reference from %s to %s.\n",
3684 origin
->caller
->dump_name (), symbol
->dump_name ());
3688 /* If JFUNC has a reference description with refcount different from
3689 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
3690 NULL. JFUNC must be a constant jump function. */
3692 static struct ipa_cst_ref_desc
*
3693 jfunc_rdesc_usable (struct ipa_jump_func
*jfunc
)
3695 struct ipa_cst_ref_desc
*rdesc
= ipa_get_jf_constant_rdesc (jfunc
);
3696 if (rdesc
&& rdesc
->refcount
!= IPA_UNDESCRIBED_USE
)
3702 /* If the value of constant jump function JFUNC is an address of a function
3703 declaration, return the associated call graph node. Otherwise return
3706 static symtab_node
*
3707 symtab_node_for_jfunc (struct ipa_jump_func
*jfunc
)
3709 gcc_checking_assert (jfunc
->type
== IPA_JF_CONST
);
3710 tree cst
= ipa_get_jf_constant (jfunc
);
3711 if (TREE_CODE (cst
) != ADDR_EXPR
3712 || (TREE_CODE (TREE_OPERAND (cst
, 0)) != FUNCTION_DECL
3713 && TREE_CODE (TREE_OPERAND (cst
, 0)) != VAR_DECL
))
3716 return symtab_node::get (TREE_OPERAND (cst
, 0));
3720 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
3721 refcount and if it hits zero, remove reference to SYMBOL from the caller of
3722 the edge specified in the rdesc. Return false if either the symbol or the
3723 reference could not be found, otherwise return true. */
3726 try_decrement_rdesc_refcount (struct ipa_jump_func
*jfunc
)
3728 struct ipa_cst_ref_desc
*rdesc
;
3729 if (jfunc
->type
== IPA_JF_CONST
3730 && (rdesc
= jfunc_rdesc_usable (jfunc
))
3731 && --rdesc
->refcount
== 0)
3733 symtab_node
*symbol
= symtab_node_for_jfunc (jfunc
);
3737 return remove_described_reference (symbol
, rdesc
);
3742 /* Try to find a destination for indirect edge IE that corresponds to a simple
3743 call or a call of a member function pointer and where the destination is a
3744 pointer formal parameter described by jump function JFUNC. TARGET_TYPE is
3745 the type of the parameter to which the result of JFUNC is passed. If it can
3746 be determined, return the newly direct edge, otherwise return NULL.
3747 NEW_ROOT and NEW_ROOT_INFO is the node and its info that JFUNC lattices are
3750 static struct cgraph_edge
*
3751 try_make_edge_direct_simple_call (struct cgraph_edge
*ie
,
3752 struct ipa_jump_func
*jfunc
, tree target_type
,
3753 struct cgraph_node
*new_root
,
3754 class ipa_node_params
*new_root_info
)
3756 struct cgraph_edge
*cs
;
3758 bool agg_contents
= ie
->indirect_info
->agg_contents
;
3759 tree scalar
= ipa_value_from_jfunc (new_root_info
, jfunc
, target_type
);
3762 bool from_global_constant
;
3763 ipa_agg_value_set agg
= ipa_agg_value_set_from_jfunc (new_root_info
,
3766 target
= ipa_find_agg_cst_for_param (&agg
, scalar
,
3767 ie
->indirect_info
->offset
,
3768 ie
->indirect_info
->by_ref
,
3769 &from_global_constant
);
3772 && !from_global_constant
3773 && !ie
->indirect_info
->guaranteed_unmodified
)
3780 cs
= ipa_make_edge_direct_to_target (ie
, target
);
3782 if (cs
&& !agg_contents
)
3785 gcc_checking_assert (cs
->callee
3787 || jfunc
->type
!= IPA_JF_CONST
3788 || !symtab_node_for_jfunc (jfunc
)
3789 || cs
->callee
== symtab_node_for_jfunc (jfunc
)));
3790 ok
= try_decrement_rdesc_refcount (jfunc
);
3791 gcc_checking_assert (ok
);
3797 /* Return the target to be used in cases of impossible devirtualization. IE
3798 and target (the latter can be NULL) are dumped when dumping is enabled. */
3801 ipa_impossible_devirt_target (struct cgraph_edge
*ie
, tree target
)
3807 "Type inconsistent devirtualization: %s->%s\n",
3808 ie
->caller
->dump_name (),
3809 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target
)));
3812 "No devirtualization target in %s\n",
3813 ie
->caller
->dump_name ());
3815 tree new_target
= builtin_decl_implicit (BUILT_IN_UNREACHABLE
);
3816 cgraph_node::get_create (new_target
);
3820 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3821 call based on a formal parameter which is described by jump function JFUNC
3822 and if it can be determined, make it direct and return the direct edge.
3823 Otherwise, return NULL. CTX describes the polymorphic context that the
3824 parameter the call is based on brings along with it. NEW_ROOT and
3825 NEW_ROOT_INFO is the node and its info that JFUNC lattices are relative
3828 static struct cgraph_edge
*
3829 try_make_edge_direct_virtual_call (struct cgraph_edge
*ie
,
3830 struct ipa_jump_func
*jfunc
,
3831 class ipa_polymorphic_call_context ctx
,
3832 struct cgraph_node
*new_root
,
3833 class ipa_node_params
*new_root_info
)
3836 bool speculative
= false;
3838 if (!opt_for_fn (ie
->caller
->decl
, flag_devirtualize
))
3841 gcc_assert (!ie
->indirect_info
->by_ref
);
3843 /* Try to do lookup via known virtual table pointer value. */
3844 if (!ie
->indirect_info
->vptr_changed
3845 || opt_for_fn (ie
->caller
->decl
, flag_devirtualize_speculatively
))
3848 unsigned HOST_WIDE_INT offset
;
3849 tree scalar
= (jfunc
->type
== IPA_JF_CONST
) ? ipa_get_jf_constant (jfunc
)
3851 ipa_agg_value_set agg
= ipa_agg_value_set_from_jfunc (new_root_info
,
3854 tree t
= ipa_find_agg_cst_for_param (&agg
, scalar
,
3855 ie
->indirect_info
->offset
,
3858 if (t
&& vtable_pointer_value_to_vtable (t
, &vtable
, &offset
))
3861 t
= gimple_get_virt_method_for_vtable (ie
->indirect_info
->otr_token
,
3862 vtable
, offset
, &can_refer
);
3866 || fndecl_built_in_p (t
, BUILT_IN_UNREACHABLE
)
3867 || !possible_polymorphic_call_target_p
3868 (ie
, cgraph_node::get (t
)))
3870 /* Do not speculate builtin_unreachable, it is stupid! */
3871 if (!ie
->indirect_info
->vptr_changed
)
3872 target
= ipa_impossible_devirt_target (ie
, target
);
3879 speculative
= ie
->indirect_info
->vptr_changed
;
3885 ipa_polymorphic_call_context
ie_context (ie
);
3886 vec
<cgraph_node
*>targets
;
3889 ctx
.offset_by (ie
->indirect_info
->offset
);
3890 if (ie
->indirect_info
->vptr_changed
)
3891 ctx
.possible_dynamic_type_change (ie
->in_polymorphic_cdtor
,
3892 ie
->indirect_info
->otr_type
);
3893 ctx
.combine_with (ie_context
, ie
->indirect_info
->otr_type
);
3894 targets
= possible_polymorphic_call_targets
3895 (ie
->indirect_info
->otr_type
,
3896 ie
->indirect_info
->otr_token
,
3898 if (final
&& targets
.length () <= 1)
3900 speculative
= false;
3901 if (targets
.length () == 1)
3902 target
= targets
[0]->decl
;
3904 target
= ipa_impossible_devirt_target (ie
, NULL_TREE
);
3906 else if (!target
&& opt_for_fn (ie
->caller
->decl
, flag_devirtualize_speculatively
)
3907 && !ie
->speculative
&& ie
->maybe_hot_p ())
3910 n
= try_speculative_devirtualization (ie
->indirect_info
->otr_type
,
3911 ie
->indirect_info
->otr_token
,
3912 ie
->indirect_info
->context
);
3922 if (!possible_polymorphic_call_target_p
3923 (ie
, cgraph_node::get_create (target
)))
3927 target
= ipa_impossible_devirt_target (ie
, target
);
3929 return ipa_make_edge_direct_to_target (ie
, target
, speculative
);
3935 /* Update the param called notes associated with NODE when CS is being inlined,
3936 assuming NODE is (potentially indirectly) inlined into CS->callee.
3937 Moreover, if the callee is discovered to be constant, create a new cgraph
3938 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
3939 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
3942 update_indirect_edges_after_inlining (struct cgraph_edge
*cs
,
3943 struct cgraph_node
*node
,
3944 vec
<cgraph_edge
*> *new_edges
)
3946 class ipa_edge_args
*top
;
3947 struct cgraph_edge
*ie
, *next_ie
, *new_direct_edge
;
3948 struct cgraph_node
*new_root
;
3949 class ipa_node_params
*new_root_info
, *inlined_node_info
;
3952 ipa_check_create_edge_args ();
3953 top
= ipa_edge_args_sum
->get (cs
);
3954 new_root
= cs
->caller
->inlined_to
3955 ? cs
->caller
->inlined_to
: cs
->caller
;
3956 new_root_info
= ipa_node_params_sum
->get (new_root
);
3957 inlined_node_info
= ipa_node_params_sum
->get (cs
->callee
->function_symbol ());
3959 for (ie
= node
->indirect_calls
; ie
; ie
= next_ie
)
3961 class cgraph_indirect_call_info
*ici
= ie
->indirect_info
;
3962 struct ipa_jump_func
*jfunc
;
3965 next_ie
= ie
->next_callee
;
3967 if (ici
->param_index
== -1)
3970 /* We must check range due to calls with variable number of arguments: */
3971 if (!top
|| ici
->param_index
>= ipa_get_cs_argument_count (top
))
3973 ici
->param_index
= -1;
3977 param_index
= ici
->param_index
;
3978 jfunc
= ipa_get_ith_jump_func (top
, param_index
);
3980 auto_vec
<cgraph_node
*, 4> spec_targets
;
3981 if (ie
->speculative
)
3982 for (cgraph_edge
*direct
= ie
->first_speculative_call_target ();
3984 direct
= direct
->next_speculative_call_target ())
3985 spec_targets
.safe_push (direct
->callee
);
3987 if (!opt_for_fn (node
->decl
, flag_indirect_inlining
))
3988 new_direct_edge
= NULL
;
3989 else if (ici
->polymorphic
)
3991 ipa_polymorphic_call_context ctx
;
3992 ctx
= ipa_context_from_jfunc (new_root_info
, cs
, param_index
, jfunc
);
3993 new_direct_edge
= try_make_edge_direct_virtual_call (ie
, jfunc
, ctx
,
3999 tree target_type
= ipa_get_type (inlined_node_info
, param_index
);
4000 new_direct_edge
= try_make_edge_direct_simple_call (ie
, jfunc
,
4006 /* If speculation was removed, then we need to do nothing. */
4007 if (new_direct_edge
&& new_direct_edge
!= ie
4008 && spec_targets
.contains (new_direct_edge
->callee
))
4010 new_direct_edge
->indirect_inlining_edge
= 1;
4012 if (!new_direct_edge
->speculative
)
4015 else if (new_direct_edge
)
4017 new_direct_edge
->indirect_inlining_edge
= 1;
4020 new_edges
->safe_push (new_direct_edge
);
4023 /* If speculative edge was introduced we still need to update
4024 call info of the indirect edge. */
4025 if (!new_direct_edge
->speculative
)
4028 if (jfunc
->type
== IPA_JF_PASS_THROUGH
4029 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
4031 if (ici
->agg_contents
4032 && !ipa_get_jf_pass_through_agg_preserved (jfunc
)
4033 && !ici
->polymorphic
)
4034 ici
->param_index
= -1;
4037 ici
->param_index
= ipa_get_jf_pass_through_formal_id (jfunc
);
4038 if (ici
->polymorphic
4039 && !ipa_get_jf_pass_through_type_preserved (jfunc
))
4040 ici
->vptr_changed
= true;
4041 ipa_set_param_used_by_indirect_call (new_root_info
,
4042 ici
->param_index
, true);
4043 if (ici
->polymorphic
)
4044 ipa_set_param_used_by_polymorphic_call (new_root_info
,
4045 ici
->param_index
, true);
4048 else if (jfunc
->type
== IPA_JF_ANCESTOR
)
4050 if (ici
->agg_contents
4051 && !ipa_get_jf_ancestor_agg_preserved (jfunc
)
4052 && !ici
->polymorphic
)
4053 ici
->param_index
= -1;
4056 ici
->param_index
= ipa_get_jf_ancestor_formal_id (jfunc
);
4057 ici
->offset
+= ipa_get_jf_ancestor_offset (jfunc
);
4058 if (ici
->polymorphic
4059 && !ipa_get_jf_ancestor_type_preserved (jfunc
))
4060 ici
->vptr_changed
= true;
4061 ipa_set_param_used_by_indirect_call (new_root_info
,
4062 ici
->param_index
, true);
4063 if (ici
->polymorphic
)
4064 ipa_set_param_used_by_polymorphic_call (new_root_info
,
4065 ici
->param_index
, true);
4069 /* Either we can find a destination for this edge now or never. */
4070 ici
->param_index
= -1;
4076 /* Recursively traverse subtree of NODE (including node) made of inlined
4077 cgraph_edges when CS has been inlined and invoke
4078 update_indirect_edges_after_inlining on all nodes and
4079 update_jump_functions_after_inlining on all non-inlined edges that lead out
4080 of this subtree. Newly discovered indirect edges will be added to
4081 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
4085 propagate_info_to_inlined_callees (struct cgraph_edge
*cs
,
4086 struct cgraph_node
*node
,
4087 vec
<cgraph_edge
*> *new_edges
)
4089 struct cgraph_edge
*e
;
4092 res
= update_indirect_edges_after_inlining (cs
, node
, new_edges
);
4094 for (e
= node
->callees
; e
; e
= e
->next_callee
)
4095 if (!e
->inline_failed
)
4096 res
|= propagate_info_to_inlined_callees (cs
, e
->callee
, new_edges
);
4098 update_jump_functions_after_inlining (cs
, e
);
4099 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
4100 update_jump_functions_after_inlining (cs
, e
);
4105 /* Combine two controlled uses counts as done during inlining. */
4108 combine_controlled_uses_counters (int c
, int d
)
4110 if (c
== IPA_UNDESCRIBED_USE
|| d
== IPA_UNDESCRIBED_USE
)
4111 return IPA_UNDESCRIBED_USE
;
4116 /* Propagate number of controlled users from CS->caleee to the new root of the
4117 tree of inlined nodes. */
4120 propagate_controlled_uses (struct cgraph_edge
*cs
)
4122 ipa_edge_args
*args
= ipa_edge_args_sum
->get (cs
);
4125 struct cgraph_node
*new_root
= cs
->caller
->inlined_to
4126 ? cs
->caller
->inlined_to
: cs
->caller
;
4127 ipa_node_params
*new_root_info
= ipa_node_params_sum
->get (new_root
);
4128 ipa_node_params
*old_root_info
= ipa_node_params_sum
->get (cs
->callee
);
4134 count
= MIN (ipa_get_cs_argument_count (args
),
4135 ipa_get_param_count (old_root_info
));
4136 for (i
= 0; i
< count
; i
++)
4138 struct ipa_jump_func
*jf
= ipa_get_ith_jump_func (args
, i
);
4139 struct ipa_cst_ref_desc
*rdesc
;
4141 if (jf
->type
== IPA_JF_PASS_THROUGH
)
4144 src_idx
= ipa_get_jf_pass_through_formal_id (jf
);
4145 c
= ipa_get_controlled_uses (new_root_info
, src_idx
);
4146 d
= ipa_get_controlled_uses (old_root_info
, i
);
4148 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf
)
4149 == NOP_EXPR
|| c
== IPA_UNDESCRIBED_USE
);
4150 c
= combine_controlled_uses_counters (c
, d
);
4151 ipa_set_controlled_uses (new_root_info
, src_idx
, c
);
4153 if (c
!= IPA_UNDESCRIBED_USE
)
4155 lderef
= (ipa_get_param_load_dereferenced (new_root_info
, src_idx
)
4156 || ipa_get_param_load_dereferenced (old_root_info
, i
));
4157 ipa_set_param_load_dereferenced (new_root_info
, src_idx
, lderef
);
4160 if (c
== 0 && !lderef
&& new_root_info
->ipcp_orig_node
)
4162 struct cgraph_node
*n
;
4163 struct ipa_ref
*ref
;
4164 tree t
= new_root_info
->known_csts
[src_idx
];
4166 if (t
&& TREE_CODE (t
) == ADDR_EXPR
4167 && TREE_CODE (TREE_OPERAND (t
, 0)) == FUNCTION_DECL
4168 && (n
= cgraph_node::get (TREE_OPERAND (t
, 0)))
4169 && (ref
= new_root
->find_reference (n
, NULL
, 0)))
4172 fprintf (dump_file
, "ipa-prop: Removing cloning-created "
4173 "reference from %s to %s.\n",
4174 new_root
->dump_name (),
4176 ref
->remove_reference ();
4180 else if (jf
->type
== IPA_JF_CONST
4181 && (rdesc
= jfunc_rdesc_usable (jf
)))
4183 int d
= ipa_get_controlled_uses (old_root_info
, i
);
4184 int c
= rdesc
->refcount
;
4185 rdesc
->refcount
= combine_controlled_uses_counters (c
, d
);
4186 if (rdesc
->refcount
== 0)
4188 tree cst
= ipa_get_jf_constant (jf
);
4189 gcc_checking_assert (TREE_CODE (cst
) == ADDR_EXPR
4190 && ((TREE_CODE (TREE_OPERAND (cst
, 0))
4192 || (TREE_CODE (TREE_OPERAND (cst
, 0))
4195 symtab_node
*n
= symtab_node::get (TREE_OPERAND (cst
, 0));
4198 struct cgraph_node
*clone
;
4199 bool removed
= remove_described_reference (n
, rdesc
);
4200 /* The reference might have been removed by IPA-CP. */
4202 && ipa_get_param_load_dereferenced (old_root_info
, i
))
4204 new_root
->create_reference (n
, IPA_REF_LOAD
, NULL
);
4206 fprintf (dump_file
, "ipa-prop: ...replaced it with "
4207 "LOAD one from %s to %s.\n",
4208 new_root
->dump_name (), n
->dump_name ());
4212 while (clone
->inlined_to
4213 && clone
->ipcp_clone
4214 && clone
!= rdesc
->cs
->caller
)
4216 struct ipa_ref
*ref
;
4217 ref
= clone
->find_reference (n
, NULL
, 0);
4221 fprintf (dump_file
, "ipa-prop: Removing "
4222 "cloning-created reference "
4224 clone
->dump_name (),
4226 ref
->remove_reference ();
4228 clone
= clone
->callers
->caller
;
4235 for (i
= ipa_get_param_count (old_root_info
);
4236 i
< ipa_get_cs_argument_count (args
);
4239 struct ipa_jump_func
*jf
= ipa_get_ith_jump_func (args
, i
);
4241 if (jf
->type
== IPA_JF_CONST
)
4243 struct ipa_cst_ref_desc
*rdesc
= jfunc_rdesc_usable (jf
);
4245 rdesc
->refcount
= IPA_UNDESCRIBED_USE
;
4247 else if (jf
->type
== IPA_JF_PASS_THROUGH
)
4248 ipa_set_controlled_uses (new_root_info
,
4249 jf
->value
.pass_through
.formal_id
,
4250 IPA_UNDESCRIBED_USE
);
4254 /* Update jump functions and call note functions on inlining the call site CS.
4255 CS is expected to lead to a node already cloned by
4256 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
4257 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
4261 ipa_propagate_indirect_call_infos (struct cgraph_edge
*cs
,
4262 vec
<cgraph_edge
*> *new_edges
)
4265 /* Do nothing if the preparation phase has not been carried out yet
4266 (i.e. during early inlining). */
4267 if (!ipa_node_params_sum
)
4269 gcc_assert (ipa_edge_args_sum
);
4271 propagate_controlled_uses (cs
);
4272 changed
= propagate_info_to_inlined_callees (cs
, cs
->callee
, new_edges
);
4273 ipa_node_params_sum
->remove (cs
->callee
);
4275 ipa_edge_args
*args
= ipa_edge_args_sum
->get (cs
);
4279 if (args
->jump_functions
)
4281 struct ipa_jump_func
*jf
;
4283 FOR_EACH_VEC_ELT (*args
->jump_functions
, i
, jf
)
4284 if (jf
->type
== IPA_JF_CONST
4285 && ipa_get_jf_constant_rdesc (jf
))
4292 ipa_edge_args_sum
->remove (cs
);
4294 if (ipcp_transformation_sum
)
4295 ipcp_transformation_sum
->remove (cs
->callee
);
4300 /* Ensure that array of edge arguments infos is big enough to accommodate a
4301 structure for all edges and reallocates it if not. Also, allocate
4302 associated hash tables is they do not already exist. */
4305 ipa_check_create_edge_args (void)
4307 if (!ipa_edge_args_sum
)
4309 = (new (ggc_alloc_no_dtor
<ipa_edge_args_sum_t
> ())
4310 ipa_edge_args_sum_t (symtab
, true));
4311 if (!ipa_bits_hash_table
)
4312 ipa_bits_hash_table
= hash_table
<ipa_bit_ggc_hash_traits
>::create_ggc (37);
4313 if (!ipa_vr_hash_table
)
4314 ipa_vr_hash_table
= hash_table
<ipa_vr_ggc_hash_traits
>::create_ggc (37);
4317 /* Free all ipa_edge structures. */
4320 ipa_free_all_edge_args (void)
4322 if (!ipa_edge_args_sum
)
4325 ggc_delete (ipa_edge_args_sum
);
4326 ipa_edge_args_sum
= NULL
;
4329 /* Free all ipa_node_params structures. */
4332 ipa_free_all_node_params (void)
4334 if (ipa_node_params_sum
)
4335 ggc_delete (ipa_node_params_sum
);
4336 ipa_node_params_sum
= NULL
;
4339 /* Initialize IPA CP transformation summary and also allocate any necessary hash
4340 tables if they do not already exist. */
4343 ipcp_transformation_initialize (void)
4345 if (!ipa_bits_hash_table
)
4346 ipa_bits_hash_table
= hash_table
<ipa_bit_ggc_hash_traits
>::create_ggc (37);
4347 if (!ipa_vr_hash_table
)
4348 ipa_vr_hash_table
= hash_table
<ipa_vr_ggc_hash_traits
>::create_ggc (37);
4349 if (ipcp_transformation_sum
== NULL
)
4351 ipcp_transformation_sum
= ipcp_transformation_t::create_ggc (symtab
);
4352 ipcp_transformation_sum
->disable_insertion_hook ();
4356 /* Release the IPA CP transformation summary. */
4359 ipcp_free_transformation_sum (void)
4361 if (!ipcp_transformation_sum
)
4364 ipcp_transformation_sum
->~function_summary
<ipcp_transformation
*> ();
4365 ggc_free (ipcp_transformation_sum
);
4366 ipcp_transformation_sum
= NULL
;
4369 /* Set the aggregate replacements of NODE to be AGGVALS. */
4372 ipa_set_node_agg_value_chain (struct cgraph_node
*node
,
4373 struct ipa_agg_replacement_value
*aggvals
)
4375 ipcp_transformation_initialize ();
4376 ipcp_transformation
*s
= ipcp_transformation_sum
->get_create (node
);
4377 s
->agg_values
= aggvals
;
4380 /* Hook that is called by cgraph.c when an edge is removed. Adjust reference
4381 count data structures accordingly. */
4384 ipa_edge_args_sum_t::remove (cgraph_edge
*cs
, ipa_edge_args
*args
)
4386 if (args
->jump_functions
)
4388 struct ipa_jump_func
*jf
;
4390 FOR_EACH_VEC_ELT (*args
->jump_functions
, i
, jf
)
4392 struct ipa_cst_ref_desc
*rdesc
;
4393 try_decrement_rdesc_refcount (jf
);
4394 if (jf
->type
== IPA_JF_CONST
4395 && (rdesc
= ipa_get_jf_constant_rdesc (jf
))
4402 /* Method invoked when an edge is duplicated. Copy ipa_edge_args and adjust
4403 reference count data strucutres accordingly. */
4406 ipa_edge_args_sum_t::duplicate (cgraph_edge
*src
, cgraph_edge
*dst
,
4407 ipa_edge_args
*old_args
, ipa_edge_args
*new_args
)
4411 new_args
->jump_functions
= vec_safe_copy (old_args
->jump_functions
);
4412 if (old_args
->polymorphic_call_contexts
)
4413 new_args
->polymorphic_call_contexts
4414 = vec_safe_copy (old_args
->polymorphic_call_contexts
);
4416 for (i
= 0; i
< vec_safe_length (old_args
->jump_functions
); i
++)
4418 struct ipa_jump_func
*src_jf
= ipa_get_ith_jump_func (old_args
, i
);
4419 struct ipa_jump_func
*dst_jf
= ipa_get_ith_jump_func (new_args
, i
);
4421 dst_jf
->agg
.items
= vec_safe_copy (dst_jf
->agg
.items
);
4423 if (src_jf
->type
== IPA_JF_CONST
)
4425 struct ipa_cst_ref_desc
*src_rdesc
= jfunc_rdesc_usable (src_jf
);
4428 dst_jf
->value
.constant
.rdesc
= NULL
;
4429 else if (src
->caller
== dst
->caller
)
4431 /* Creation of a speculative edge. If the source edge is the one
4432 grabbing a reference, we must create a new (duplicate)
4433 reference description. Otherwise they refer to the same
4434 description corresponding to a reference taken in a function
4435 src->caller is inlined to. In that case we just must
4436 increment the refcount. */
4437 if (src_rdesc
->cs
== src
)
4439 symtab_node
*n
= symtab_node_for_jfunc (src_jf
);
4440 gcc_checking_assert (n
);
4442 = src
->caller
->find_reference (n
, src
->call_stmt
,
4444 gcc_checking_assert (ref
);
4445 dst
->caller
->clone_reference (ref
, ref
->stmt
);
4447 ipa_cst_ref_desc
*dst_rdesc
= ipa_refdesc_pool
.allocate ();
4448 dst_rdesc
->cs
= dst
;
4449 dst_rdesc
->refcount
= src_rdesc
->refcount
;
4450 dst_rdesc
->next_duplicate
= NULL
;
4451 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
4455 src_rdesc
->refcount
++;
4456 dst_jf
->value
.constant
.rdesc
= src_rdesc
;
4459 else if (src_rdesc
->cs
== src
)
4461 struct ipa_cst_ref_desc
*dst_rdesc
= ipa_refdesc_pool
.allocate ();
4462 dst_rdesc
->cs
= dst
;
4463 dst_rdesc
->refcount
= src_rdesc
->refcount
;
4464 dst_rdesc
->next_duplicate
= src_rdesc
->next_duplicate
;
4465 src_rdesc
->next_duplicate
= dst_rdesc
;
4466 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
4470 struct ipa_cst_ref_desc
*dst_rdesc
;
4471 /* This can happen during inlining, when a JFUNC can refer to a
4472 reference taken in a function up in the tree of inline clones.
4473 We need to find the duplicate that refers to our tree of
4476 gcc_assert (dst
->caller
->inlined_to
);
4477 for (dst_rdesc
= src_rdesc
->next_duplicate
;
4479 dst_rdesc
= dst_rdesc
->next_duplicate
)
4481 struct cgraph_node
*top
;
4482 top
= dst_rdesc
->cs
->caller
->inlined_to
4483 ? dst_rdesc
->cs
->caller
->inlined_to
4484 : dst_rdesc
->cs
->caller
;
4485 if (dst
->caller
->inlined_to
== top
)
4488 gcc_assert (dst_rdesc
);
4489 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
4492 else if (dst_jf
->type
== IPA_JF_PASS_THROUGH
4493 && src
->caller
== dst
->caller
)
4495 struct cgraph_node
*inline_root
= dst
->caller
->inlined_to
4496 ? dst
->caller
->inlined_to
: dst
->caller
;
4497 ipa_node_params
*root_info
= ipa_node_params_sum
->get (inline_root
);
4498 int idx
= ipa_get_jf_pass_through_formal_id (dst_jf
);
4500 int c
= ipa_get_controlled_uses (root_info
, idx
);
4501 if (c
!= IPA_UNDESCRIBED_USE
)
4504 ipa_set_controlled_uses (root_info
, idx
, c
);
4510 /* Analyze newly added function into callgraph. */
4513 ipa_add_new_function (cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
4515 if (node
->has_gimple_body_p ())
4516 ipa_analyze_node (node
);
4519 /* Hook that is called by summary when a node is duplicated. */
4522 ipa_node_params_t::duplicate(cgraph_node
*src
, cgraph_node
*dst
,
4523 ipa_node_params
*old_info
,
4524 ipa_node_params
*new_info
)
4526 ipa_agg_replacement_value
*old_av
, *new_av
;
4528 new_info
->descriptors
= vec_safe_copy (old_info
->descriptors
);
4529 new_info
->lattices
= NULL
;
4530 new_info
->ipcp_orig_node
= old_info
->ipcp_orig_node
;
4531 new_info
->known_csts
= old_info
->known_csts
.copy ();
4532 new_info
->known_contexts
= old_info
->known_contexts
.copy ();
4534 new_info
->analysis_done
= old_info
->analysis_done
;
4535 new_info
->node_enqueued
= old_info
->node_enqueued
;
4536 new_info
->versionable
= old_info
->versionable
;
4538 old_av
= ipa_get_agg_replacements_for_node (src
);
4544 struct ipa_agg_replacement_value
*v
;
4546 v
= ggc_alloc
<ipa_agg_replacement_value
> ();
4547 memcpy (v
, old_av
, sizeof (*v
));
4550 old_av
= old_av
->next
;
4552 ipa_set_node_agg_value_chain (dst
, new_av
);
4556 /* Duplication of ipcp transformation summaries. */
4559 ipcp_transformation_t::duplicate(cgraph_node
*, cgraph_node
*dst
,
4560 ipcp_transformation
*src_trans
,
4561 ipcp_transformation
*dst_trans
)
4563 /* Avoid redundant work of duplicating vectors we will never use. */
4564 if (dst
->inlined_to
)
4566 dst_trans
->bits
= vec_safe_copy (src_trans
->bits
);
4567 dst_trans
->m_vr
= vec_safe_copy (src_trans
->m_vr
);
4568 ipa_agg_replacement_value
*agg
= src_trans
->agg_values
,
4569 **aggptr
= &dst_trans
->agg_values
;
4572 *aggptr
= ggc_alloc
<ipa_agg_replacement_value
> ();
4575 aggptr
= &(*aggptr
)->next
;
4579 /* Register our cgraph hooks if they are not already there. */
4582 ipa_register_cgraph_hooks (void)
4584 ipa_check_create_node_params ();
4585 ipa_check_create_edge_args ();
4587 function_insertion_hook_holder
=
4588 symtab
->add_cgraph_insertion_hook (&ipa_add_new_function
, NULL
);
4591 /* Unregister our cgraph hooks if they are not already there. */
4594 ipa_unregister_cgraph_hooks (void)
4596 if (function_insertion_hook_holder
)
4597 symtab
->remove_cgraph_insertion_hook (function_insertion_hook_holder
);
4598 function_insertion_hook_holder
= NULL
;
4601 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4602 longer needed after ipa-cp. */
4605 ipa_free_all_structures_after_ipa_cp (void)
4607 if (!optimize
&& !in_lto_p
)
4609 ipa_free_all_edge_args ();
4610 ipa_free_all_node_params ();
4611 ipcp_sources_pool
.release ();
4612 ipcp_cst_values_pool
.release ();
4613 ipcp_poly_ctx_values_pool
.release ();
4614 ipcp_agg_lattice_pool
.release ();
4615 ipa_unregister_cgraph_hooks ();
4616 ipa_refdesc_pool
.release ();
4620 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4621 longer needed after indirect inlining. */
4624 ipa_free_all_structures_after_iinln (void)
4626 ipa_free_all_edge_args ();
4627 ipa_free_all_node_params ();
4628 ipa_unregister_cgraph_hooks ();
4629 ipcp_sources_pool
.release ();
4630 ipcp_cst_values_pool
.release ();
4631 ipcp_poly_ctx_values_pool
.release ();
4632 ipcp_agg_lattice_pool
.release ();
4633 ipa_refdesc_pool
.release ();
4636 /* Print ipa_tree_map data structures of all functions in the
4640 ipa_print_node_params (FILE *f
, struct cgraph_node
*node
)
4643 class ipa_node_params
*info
;
4645 if (!node
->definition
)
4647 info
= ipa_node_params_sum
->get (node
);
4648 fprintf (f
, " function %s parameter descriptors:\n", node
->dump_name ());
4651 fprintf (f
, " no params return\n");
4654 count
= ipa_get_param_count (info
);
4655 for (i
= 0; i
< count
; i
++)
4660 ipa_dump_param (f
, info
, i
);
4661 if (ipa_is_param_used (info
, i
))
4662 fprintf (f
, " used");
4663 if (ipa_is_param_used_by_ipa_predicates (info
, i
))
4664 fprintf (f
, " used_by_ipa_predicates");
4665 if (ipa_is_param_used_by_indirect_call (info
, i
))
4666 fprintf (f
, " used_by_indirect_call");
4667 if (ipa_is_param_used_by_polymorphic_call (info
, i
))
4668 fprintf (f
, " used_by_polymorphic_call");
4669 c
= ipa_get_controlled_uses (info
, i
);
4670 if (c
== IPA_UNDESCRIBED_USE
)
4671 fprintf (f
, " undescribed_use");
4673 fprintf (f
, " controlled_uses=%i %s", c
,
4674 ipa_get_param_load_dereferenced (info
, i
)
4675 ? "(load_dereferenced)" : "");
4680 /* Print ipa_tree_map data structures of all functions in the
4684 ipa_print_all_params (FILE * f
)
4686 struct cgraph_node
*node
;
4688 fprintf (f
, "\nFunction parameters:\n");
4689 FOR_EACH_FUNCTION (node
)
4690 ipa_print_node_params (f
, node
);
4693 /* Dump the AV linked list. */
4696 ipa_dump_agg_replacement_values (FILE *f
, struct ipa_agg_replacement_value
*av
)
4699 fprintf (f
, " Aggregate replacements:");
4700 for (; av
; av
= av
->next
)
4702 fprintf (f
, "%s %i[" HOST_WIDE_INT_PRINT_DEC
"]=", comma
? "," : "",
4703 av
->index
, av
->offset
);
4704 print_generic_expr (f
, av
->value
);
4710 /* Stream out jump function JUMP_FUNC to OB. */
4713 ipa_write_jump_function (struct output_block
*ob
,
4714 struct ipa_jump_func
*jump_func
)
4716 struct ipa_agg_jf_item
*item
;
4717 struct bitpack_d bp
;
4721 /* ADDR_EXPRs are very comon IP invariants; save some streamer data
4722 as well as WPA memory by handling them specially. */
4723 if (jump_func
->type
== IPA_JF_CONST
4724 && TREE_CODE (jump_func
->value
.constant
.value
) == ADDR_EXPR
)
4727 streamer_write_uhwi (ob
, jump_func
->type
* 2 + flag
);
4728 switch (jump_func
->type
)
4730 case IPA_JF_UNKNOWN
:
4734 EXPR_LOCATION (jump_func
->value
.constant
.value
) == UNKNOWN_LOCATION
);
4735 stream_write_tree (ob
,
4737 ? TREE_OPERAND (jump_func
->value
.constant
.value
, 0)
4738 : jump_func
->value
.constant
.value
, true);
4740 case IPA_JF_PASS_THROUGH
:
4741 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.operation
);
4742 if (jump_func
->value
.pass_through
.operation
== NOP_EXPR
)
4744 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4745 bp
= bitpack_create (ob
->main_stream
);
4746 bp_pack_value (&bp
, jump_func
->value
.pass_through
.agg_preserved
, 1);
4747 streamer_write_bitpack (&bp
);
4749 else if (TREE_CODE_CLASS (jump_func
->value
.pass_through
.operation
)
4751 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4754 stream_write_tree (ob
, jump_func
->value
.pass_through
.operand
, true);
4755 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4758 case IPA_JF_ANCESTOR
:
4759 streamer_write_uhwi (ob
, jump_func
->value
.ancestor
.offset
);
4760 streamer_write_uhwi (ob
, jump_func
->value
.ancestor
.formal_id
);
4761 bp
= bitpack_create (ob
->main_stream
);
4762 bp_pack_value (&bp
, jump_func
->value
.ancestor
.agg_preserved
, 1);
4763 streamer_write_bitpack (&bp
);
4766 fatal_error (UNKNOWN_LOCATION
, "invalid jump function in LTO stream");
4769 count
= vec_safe_length (jump_func
->agg
.items
);
4770 streamer_write_uhwi (ob
, count
);
4773 bp
= bitpack_create (ob
->main_stream
);
4774 bp_pack_value (&bp
, jump_func
->agg
.by_ref
, 1);
4775 streamer_write_bitpack (&bp
);
4778 FOR_EACH_VEC_SAFE_ELT (jump_func
->agg
.items
, i
, item
)
4780 stream_write_tree (ob
, item
->type
, true);
4781 streamer_write_uhwi (ob
, item
->offset
);
4782 streamer_write_uhwi (ob
, item
->jftype
);
4783 switch (item
->jftype
)
4785 case IPA_JF_UNKNOWN
:
4788 stream_write_tree (ob
, item
->value
.constant
, true);
4790 case IPA_JF_PASS_THROUGH
:
4791 case IPA_JF_LOAD_AGG
:
4792 streamer_write_uhwi (ob
, item
->value
.pass_through
.operation
);
4793 streamer_write_uhwi (ob
, item
->value
.pass_through
.formal_id
);
4794 if (TREE_CODE_CLASS (item
->value
.pass_through
.operation
)
4796 stream_write_tree (ob
, item
->value
.pass_through
.operand
, true);
4797 if (item
->jftype
== IPA_JF_LOAD_AGG
)
4799 stream_write_tree (ob
, item
->value
.load_agg
.type
, true);
4800 streamer_write_uhwi (ob
, item
->value
.load_agg
.offset
);
4801 bp
= bitpack_create (ob
->main_stream
);
4802 bp_pack_value (&bp
, item
->value
.load_agg
.by_ref
, 1);
4803 streamer_write_bitpack (&bp
);
4807 fatal_error (UNKNOWN_LOCATION
,
4808 "invalid jump function in LTO stream");
4812 bp
= bitpack_create (ob
->main_stream
);
4813 bp_pack_value (&bp
, !!jump_func
->bits
, 1);
4814 streamer_write_bitpack (&bp
);
4815 if (jump_func
->bits
)
4817 streamer_write_widest_int (ob
, jump_func
->bits
->value
);
4818 streamer_write_widest_int (ob
, jump_func
->bits
->mask
);
4820 bp_pack_value (&bp
, !!jump_func
->m_vr
, 1);
4821 streamer_write_bitpack (&bp
);
4822 if (jump_func
->m_vr
)
4824 streamer_write_enum (ob
->main_stream
, value_rang_type
,
4825 VR_LAST
, jump_func
->m_vr
->kind ());
4826 stream_write_tree (ob
, jump_func
->m_vr
->min (), true);
4827 stream_write_tree (ob
, jump_func
->m_vr
->max (), true);
4831 /* Read in jump function JUMP_FUNC from IB. */
4834 ipa_read_jump_function (class lto_input_block
*ib
,
4835 struct ipa_jump_func
*jump_func
,
4836 struct cgraph_edge
*cs
,
4837 class data_in
*data_in
,
4840 enum jump_func_type jftype
;
4841 enum tree_code operation
;
4843 int val
= streamer_read_uhwi (ib
);
4844 bool flag
= val
& 1;
4846 jftype
= (enum jump_func_type
) (val
/ 2);
4849 case IPA_JF_UNKNOWN
:
4850 ipa_set_jf_unknown (jump_func
);
4854 tree t
= stream_read_tree (ib
, data_in
);
4855 if (flag
&& prevails
)
4856 t
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
4857 ipa_set_jf_constant (jump_func
, t
, cs
);
4860 case IPA_JF_PASS_THROUGH
:
4861 operation
= (enum tree_code
) streamer_read_uhwi (ib
);
4862 if (operation
== NOP_EXPR
)
4864 int formal_id
= streamer_read_uhwi (ib
);
4865 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4866 bool agg_preserved
= bp_unpack_value (&bp
, 1);
4867 ipa_set_jf_simple_pass_through (jump_func
, formal_id
, agg_preserved
);
4869 else if (TREE_CODE_CLASS (operation
) == tcc_unary
)
4871 int formal_id
= streamer_read_uhwi (ib
);
4872 ipa_set_jf_unary_pass_through (jump_func
, formal_id
, operation
);
4876 tree operand
= stream_read_tree (ib
, data_in
);
4877 int formal_id
= streamer_read_uhwi (ib
);
4878 ipa_set_jf_arith_pass_through (jump_func
, formal_id
, operand
,
4882 case IPA_JF_ANCESTOR
:
4884 HOST_WIDE_INT offset
= streamer_read_uhwi (ib
);
4885 int formal_id
= streamer_read_uhwi (ib
);
4886 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4887 bool agg_preserved
= bp_unpack_value (&bp
, 1);
4888 ipa_set_ancestor_jf (jump_func
, offset
, formal_id
, agg_preserved
);
4892 fatal_error (UNKNOWN_LOCATION
, "invalid jump function in LTO stream");
4895 count
= streamer_read_uhwi (ib
);
4898 jump_func
->agg
.items
= NULL
;
4899 vec_safe_reserve (jump_func
->agg
.items
, count
, true);
4903 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4904 jump_func
->agg
.by_ref
= bp_unpack_value (&bp
, 1);
4906 for (i
= 0; i
< count
; i
++)
4908 struct ipa_agg_jf_item item
;
4909 item
.type
= stream_read_tree (ib
, data_in
);
4910 item
.offset
= streamer_read_uhwi (ib
);
4911 item
.jftype
= (enum jump_func_type
) streamer_read_uhwi (ib
);
4913 switch (item
.jftype
)
4915 case IPA_JF_UNKNOWN
:
4918 item
.value
.constant
= stream_read_tree (ib
, data_in
);
4920 case IPA_JF_PASS_THROUGH
:
4921 case IPA_JF_LOAD_AGG
:
4922 operation
= (enum tree_code
) streamer_read_uhwi (ib
);
4923 item
.value
.pass_through
.operation
= operation
;
4924 item
.value
.pass_through
.formal_id
= streamer_read_uhwi (ib
);
4925 if (TREE_CODE_CLASS (operation
) == tcc_unary
)
4926 item
.value
.pass_through
.operand
= NULL_TREE
;
4928 item
.value
.pass_through
.operand
= stream_read_tree (ib
, data_in
);
4929 if (item
.jftype
== IPA_JF_LOAD_AGG
)
4931 struct bitpack_d bp
;
4932 item
.value
.load_agg
.type
= stream_read_tree (ib
, data_in
);
4933 item
.value
.load_agg
.offset
= streamer_read_uhwi (ib
);
4934 bp
= streamer_read_bitpack (ib
);
4935 item
.value
.load_agg
.by_ref
= bp_unpack_value (&bp
, 1);
4939 fatal_error (UNKNOWN_LOCATION
,
4940 "invalid jump function in LTO stream");
4943 jump_func
->agg
.items
->quick_push (item
);
4946 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4947 bool bits_known
= bp_unpack_value (&bp
, 1);
4950 widest_int value
= streamer_read_widest_int (ib
);
4951 widest_int mask
= streamer_read_widest_int (ib
);
4953 ipa_set_jfunc_bits (jump_func
, value
, mask
);
4956 jump_func
->bits
= NULL
;
4958 struct bitpack_d vr_bp
= streamer_read_bitpack (ib
);
4959 bool vr_known
= bp_unpack_value (&vr_bp
, 1);
4962 enum value_range_kind type
= streamer_read_enum (ib
, value_range_kind
,
4964 tree min
= stream_read_tree (ib
, data_in
);
4965 tree max
= stream_read_tree (ib
, data_in
);
4967 ipa_set_jfunc_vr (jump_func
, type
, min
, max
);
4970 jump_func
->m_vr
= NULL
;
4973 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
4974 relevant to indirect inlining to OB. */
4977 ipa_write_indirect_edge_info (struct output_block
*ob
,
4978 struct cgraph_edge
*cs
)
4980 class cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
4981 struct bitpack_d bp
;
4983 streamer_write_hwi (ob
, ii
->param_index
);
4984 bp
= bitpack_create (ob
->main_stream
);
4985 bp_pack_value (&bp
, ii
->polymorphic
, 1);
4986 bp_pack_value (&bp
, ii
->agg_contents
, 1);
4987 bp_pack_value (&bp
, ii
->member_ptr
, 1);
4988 bp_pack_value (&bp
, ii
->by_ref
, 1);
4989 bp_pack_value (&bp
, ii
->guaranteed_unmodified
, 1);
4990 bp_pack_value (&bp
, ii
->vptr_changed
, 1);
4991 streamer_write_bitpack (&bp
);
4992 if (ii
->agg_contents
|| ii
->polymorphic
)
4993 streamer_write_hwi (ob
, ii
->offset
);
4995 gcc_assert (ii
->offset
== 0);
4997 if (ii
->polymorphic
)
4999 streamer_write_hwi (ob
, ii
->otr_token
);
5000 stream_write_tree (ob
, ii
->otr_type
, true);
5001 ii
->context
.stream_out (ob
);
5005 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
5006 relevant to indirect inlining from IB. */
5009 ipa_read_indirect_edge_info (class lto_input_block
*ib
,
5010 class data_in
*data_in
,
5011 struct cgraph_edge
*cs
,
5012 class ipa_node_params
*info
)
5014 class cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
5015 struct bitpack_d bp
;
5017 ii
->param_index
= (int) streamer_read_hwi (ib
);
5018 bp
= streamer_read_bitpack (ib
);
5019 ii
->polymorphic
= bp_unpack_value (&bp
, 1);
5020 ii
->agg_contents
= bp_unpack_value (&bp
, 1);
5021 ii
->member_ptr
= bp_unpack_value (&bp
, 1);
5022 ii
->by_ref
= bp_unpack_value (&bp
, 1);
5023 ii
->guaranteed_unmodified
= bp_unpack_value (&bp
, 1);
5024 ii
->vptr_changed
= bp_unpack_value (&bp
, 1);
5025 if (ii
->agg_contents
|| ii
->polymorphic
)
5026 ii
->offset
= (HOST_WIDE_INT
) streamer_read_hwi (ib
);
5029 if (ii
->polymorphic
)
5031 ii
->otr_token
= (HOST_WIDE_INT
) streamer_read_hwi (ib
);
5032 ii
->otr_type
= stream_read_tree (ib
, data_in
);
5033 ii
->context
.stream_in (ib
, data_in
);
5035 if (info
&& ii
->param_index
>= 0)
5037 if (ii
->polymorphic
)
5038 ipa_set_param_used_by_polymorphic_call (info
,
5039 ii
->param_index
, true);
5040 ipa_set_param_used_by_indirect_call (info
,
5041 ii
->param_index
, true);
5045 /* Stream out NODE info to OB. */
5048 ipa_write_node_info (struct output_block
*ob
, struct cgraph_node
*node
)
5051 lto_symtab_encoder_t encoder
;
5052 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
5054 struct cgraph_edge
*e
;
5055 struct bitpack_d bp
;
5057 encoder
= ob
->decl_state
->symtab_node_encoder
;
5058 node_ref
= lto_symtab_encoder_encode (encoder
, node
);
5059 streamer_write_uhwi (ob
, node_ref
);
5061 streamer_write_uhwi (ob
, ipa_get_param_count (info
));
5062 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
5063 streamer_write_uhwi (ob
, ipa_get_param_move_cost (info
, j
));
5064 bp
= bitpack_create (ob
->main_stream
);
5065 gcc_assert (info
->analysis_done
5066 || ipa_get_param_count (info
) == 0);
5067 gcc_assert (!info
->node_enqueued
);
5068 gcc_assert (!info
->ipcp_orig_node
);
5069 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
5071 /* TODO: We could just not stream the bit in the undescribed case. */
5072 bool d
= (ipa_get_controlled_uses (info
, j
) != IPA_UNDESCRIBED_USE
)
5073 ? ipa_get_param_load_dereferenced (info
, j
) : true;
5074 bp_pack_value (&bp
, d
, 1);
5075 bp_pack_value (&bp
, ipa_is_param_used (info
, j
), 1);
5077 streamer_write_bitpack (&bp
);
5078 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
5080 streamer_write_hwi (ob
, ipa_get_controlled_uses (info
, j
));
5081 stream_write_tree (ob
, ipa_get_type (info
, j
), true);
5083 for (e
= node
->callees
; e
; e
= e
->next_callee
)
5085 ipa_edge_args
*args
= ipa_edge_args_sum
->get (e
);
5089 streamer_write_uhwi (ob
, 0);
5093 streamer_write_uhwi (ob
,
5094 ipa_get_cs_argument_count (args
) * 2
5095 + (args
->polymorphic_call_contexts
!= NULL
));
5096 for (j
= 0; j
< ipa_get_cs_argument_count (args
); j
++)
5098 ipa_write_jump_function (ob
, ipa_get_ith_jump_func (args
, j
));
5099 if (args
->polymorphic_call_contexts
!= NULL
)
5100 ipa_get_ith_polymorhic_call_context (args
, j
)->stream_out (ob
);
5103 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
5105 ipa_edge_args
*args
= ipa_edge_args_sum
->get (e
);
5107 streamer_write_uhwi (ob
, 0);
5110 streamer_write_uhwi (ob
,
5111 ipa_get_cs_argument_count (args
) * 2
5112 + (args
->polymorphic_call_contexts
!= NULL
));
5113 for (j
= 0; j
< ipa_get_cs_argument_count (args
); j
++)
5115 ipa_write_jump_function (ob
, ipa_get_ith_jump_func (args
, j
));
5116 if (args
->polymorphic_call_contexts
!= NULL
)
5117 ipa_get_ith_polymorhic_call_context (args
, j
)->stream_out (ob
);
5120 ipa_write_indirect_edge_info (ob
, e
);
5124 /* Stream in edge E from IB. */
5127 ipa_read_edge_info (class lto_input_block
*ib
,
5128 class data_in
*data_in
,
5129 struct cgraph_edge
*e
, bool prevails
)
5131 int count
= streamer_read_uhwi (ib
);
5132 bool contexts_computed
= count
& 1;
5138 && (e
->possibly_call_in_translation_unit_p ()
5139 /* Also stream in jump functions to builtins in hope that they
5140 will get fnspecs. */
5141 || fndecl_built_in_p (e
->callee
->decl
, BUILT_IN_NORMAL
)))
5143 ipa_edge_args
*args
= ipa_edge_args_sum
->get_create (e
);
5144 vec_safe_grow_cleared (args
->jump_functions
, count
, true);
5145 if (contexts_computed
)
5146 vec_safe_grow_cleared (args
->polymorphic_call_contexts
, count
, true);
5147 for (int k
= 0; k
< count
; k
++)
5149 ipa_read_jump_function (ib
, ipa_get_ith_jump_func (args
, k
), e
,
5151 if (contexts_computed
)
5152 ipa_get_ith_polymorhic_call_context (args
, k
)->stream_in
5158 for (int k
= 0; k
< count
; k
++)
5160 struct ipa_jump_func dummy
;
5161 ipa_read_jump_function (ib
, &dummy
, e
,
5163 if (contexts_computed
)
5165 class ipa_polymorphic_call_context ctx
;
5166 ctx
.stream_in (ib
, data_in
);
5172 /* Stream in NODE info from IB. */
5175 ipa_read_node_info (class lto_input_block
*ib
, struct cgraph_node
*node
,
5176 class data_in
*data_in
)
5179 struct cgraph_edge
*e
;
5180 struct bitpack_d bp
;
5181 bool prevails
= node
->prevailing_p ();
5182 ipa_node_params
*info
5183 = prevails
? ipa_node_params_sum
->get_create (node
) : NULL
;
5185 int param_count
= streamer_read_uhwi (ib
);
5188 ipa_alloc_node_params (node
, param_count
);
5189 for (k
= 0; k
< param_count
; k
++)
5190 (*info
->descriptors
)[k
].move_cost
= streamer_read_uhwi (ib
);
5191 if (ipa_get_param_count (info
) != 0)
5192 info
->analysis_done
= true;
5193 info
->node_enqueued
= false;
5196 for (k
= 0; k
< param_count
; k
++)
5197 streamer_read_uhwi (ib
);
5199 bp
= streamer_read_bitpack (ib
);
5200 for (k
= 0; k
< param_count
; k
++)
5202 bool load_dereferenced
= bp_unpack_value (&bp
, 1);
5203 bool used
= bp_unpack_value (&bp
, 1);
5207 ipa_set_param_load_dereferenced (info
, k
, load_dereferenced
);
5208 ipa_set_param_used (info
, k
, used
);
5211 for (k
= 0; k
< param_count
; k
++)
5213 int nuses
= streamer_read_hwi (ib
);
5214 tree type
= stream_read_tree (ib
, data_in
);
5218 ipa_set_controlled_uses (info
, k
, nuses
);
5219 (*info
->descriptors
)[k
].decl_or_type
= type
;
5222 for (e
= node
->callees
; e
; e
= e
->next_callee
)
5223 ipa_read_edge_info (ib
, data_in
, e
, prevails
);
5224 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
5226 ipa_read_edge_info (ib
, data_in
, e
, prevails
);
5227 ipa_read_indirect_edge_info (ib
, data_in
, e
, info
);
5231 /* Write jump functions for nodes in SET. */
5234 ipa_prop_write_jump_functions (void)
5236 struct output_block
*ob
;
5237 unsigned int count
= 0;
5238 lto_symtab_encoder_iterator lsei
;
5239 lto_symtab_encoder_t encoder
;
5241 if (!ipa_node_params_sum
|| !ipa_edge_args_sum
)
5244 ob
= create_output_block (LTO_section_jump_functions
);
5245 encoder
= ob
->decl_state
->symtab_node_encoder
;
5247 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5248 lsei_next_function_in_partition (&lsei
))
5250 cgraph_node
*node
= lsei_cgraph_node (lsei
);
5251 if (node
->has_gimple_body_p ()
5252 && ipa_node_params_sum
->get (node
) != NULL
)
5256 streamer_write_uhwi (ob
, count
);
5258 /* Process all of the functions. */
5259 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5260 lsei_next_function_in_partition (&lsei
))
5262 cgraph_node
*node
= lsei_cgraph_node (lsei
);
5263 if (node
->has_gimple_body_p ()
5264 && ipa_node_params_sum
->get (node
) != NULL
)
5265 ipa_write_node_info (ob
, node
);
5267 streamer_write_char_stream (ob
->main_stream
, 0);
5268 produce_asm (ob
, NULL
);
5269 destroy_output_block (ob
);
5272 /* Read section in file FILE_DATA of length LEN with data DATA. */
5275 ipa_prop_read_section (struct lto_file_decl_data
*file_data
, const char *data
,
5278 const struct lto_function_header
*header
=
5279 (const struct lto_function_header
*) data
;
5280 const int cfg_offset
= sizeof (struct lto_function_header
);
5281 const int main_offset
= cfg_offset
+ header
->cfg_size
;
5282 const int string_offset
= main_offset
+ header
->main_size
;
5283 class data_in
*data_in
;
5287 lto_input_block
ib_main ((const char *) data
+ main_offset
,
5288 header
->main_size
, file_data
->mode_table
);
5291 lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
5292 header
->string_size
, vNULL
);
5293 count
= streamer_read_uhwi (&ib_main
);
5295 for (i
= 0; i
< count
; i
++)
5298 struct cgraph_node
*node
;
5299 lto_symtab_encoder_t encoder
;
5301 index
= streamer_read_uhwi (&ib_main
);
5302 encoder
= file_data
->symtab_node_encoder
;
5303 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref (encoder
,
5305 gcc_assert (node
->definition
);
5306 ipa_read_node_info (&ib_main
, node
, data_in
);
5308 lto_free_section_data (file_data
, LTO_section_jump_functions
, NULL
, data
,
5310 lto_data_in_delete (data_in
);
5313 /* Read ipcp jump functions. */
5316 ipa_prop_read_jump_functions (void)
5318 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
5319 struct lto_file_decl_data
*file_data
;
5322 ipa_check_create_node_params ();
5323 ipa_check_create_edge_args ();
5324 ipa_register_cgraph_hooks ();
5326 while ((file_data
= file_data_vec
[j
++]))
5330 = lto_get_summary_section_data (file_data
, LTO_section_jump_functions
,
5333 ipa_prop_read_section (file_data
, data
, len
);
5338 write_ipcp_transformation_info (output_block
*ob
, cgraph_node
*node
)
5341 unsigned int count
= 0;
5342 lto_symtab_encoder_t encoder
;
5343 struct ipa_agg_replacement_value
*aggvals
, *av
;
5345 aggvals
= ipa_get_agg_replacements_for_node (node
);
5346 encoder
= ob
->decl_state
->symtab_node_encoder
;
5347 node_ref
= lto_symtab_encoder_encode (encoder
, node
);
5348 streamer_write_uhwi (ob
, node_ref
);
5350 for (av
= aggvals
; av
; av
= av
->next
)
5352 streamer_write_uhwi (ob
, count
);
5354 for (av
= aggvals
; av
; av
= av
->next
)
5356 struct bitpack_d bp
;
5358 streamer_write_uhwi (ob
, av
->offset
);
5359 streamer_write_uhwi (ob
, av
->index
);
5360 stream_write_tree (ob
, av
->value
, true);
5362 bp
= bitpack_create (ob
->main_stream
);
5363 bp_pack_value (&bp
, av
->by_ref
, 1);
5364 streamer_write_bitpack (&bp
);
5367 ipcp_transformation
*ts
= ipcp_get_transformation_summary (node
);
5368 if (ts
&& vec_safe_length (ts
->m_vr
) > 0)
5370 count
= ts
->m_vr
->length ();
5371 streamer_write_uhwi (ob
, count
);
5372 for (unsigned i
= 0; i
< count
; ++i
)
5374 struct bitpack_d bp
;
5375 ipa_vr
*parm_vr
= &(*ts
->m_vr
)[i
];
5376 bp
= bitpack_create (ob
->main_stream
);
5377 bp_pack_value (&bp
, parm_vr
->known
, 1);
5378 streamer_write_bitpack (&bp
);
5381 streamer_write_enum (ob
->main_stream
, value_rang_type
,
5382 VR_LAST
, parm_vr
->type
);
5383 streamer_write_wide_int (ob
, parm_vr
->min
);
5384 streamer_write_wide_int (ob
, parm_vr
->max
);
5389 streamer_write_uhwi (ob
, 0);
5391 if (ts
&& vec_safe_length (ts
->bits
) > 0)
5393 count
= ts
->bits
->length ();
5394 streamer_write_uhwi (ob
, count
);
5396 for (unsigned i
= 0; i
< count
; ++i
)
5398 const ipa_bits
*bits_jfunc
= (*ts
->bits
)[i
];
5399 struct bitpack_d bp
= bitpack_create (ob
->main_stream
);
5400 bp_pack_value (&bp
, !!bits_jfunc
, 1);
5401 streamer_write_bitpack (&bp
);
5404 streamer_write_widest_int (ob
, bits_jfunc
->value
);
5405 streamer_write_widest_int (ob
, bits_jfunc
->mask
);
5410 streamer_write_uhwi (ob
, 0);
5413 /* Stream in the aggregate value replacement chain for NODE from IB. */
5416 read_ipcp_transformation_info (lto_input_block
*ib
, cgraph_node
*node
,
5419 struct ipa_agg_replacement_value
*aggvals
= NULL
;
5420 unsigned int count
, i
;
5422 count
= streamer_read_uhwi (ib
);
5423 for (i
= 0; i
<count
; i
++)
5425 struct ipa_agg_replacement_value
*av
;
5426 struct bitpack_d bp
;
5428 av
= ggc_alloc
<ipa_agg_replacement_value
> ();
5429 av
->offset
= streamer_read_uhwi (ib
);
5430 av
->index
= streamer_read_uhwi (ib
);
5431 av
->value
= stream_read_tree (ib
, data_in
);
5432 bp
= streamer_read_bitpack (ib
);
5433 av
->by_ref
= bp_unpack_value (&bp
, 1);
5437 ipa_set_node_agg_value_chain (node
, aggvals
);
5439 count
= streamer_read_uhwi (ib
);
5442 ipcp_transformation_initialize ();
5443 ipcp_transformation
*ts
= ipcp_transformation_sum
->get_create (node
);
5444 vec_safe_grow_cleared (ts
->m_vr
, count
, true);
5445 for (i
= 0; i
< count
; i
++)
5448 parm_vr
= &(*ts
->m_vr
)[i
];
5449 struct bitpack_d bp
;
5450 bp
= streamer_read_bitpack (ib
);
5451 parm_vr
->known
= bp_unpack_value (&bp
, 1);
5454 parm_vr
->type
= streamer_read_enum (ib
, value_range_kind
,
5456 parm_vr
->min
= streamer_read_wide_int (ib
);
5457 parm_vr
->max
= streamer_read_wide_int (ib
);
5461 count
= streamer_read_uhwi (ib
);
5464 ipcp_transformation_initialize ();
5465 ipcp_transformation
*ts
= ipcp_transformation_sum
->get_create (node
);
5466 vec_safe_grow_cleared (ts
->bits
, count
, true);
5468 for (i
= 0; i
< count
; i
++)
5470 struct bitpack_d bp
= streamer_read_bitpack (ib
);
5471 bool known
= bp_unpack_value (&bp
, 1);
5474 const widest_int value
= streamer_read_widest_int (ib
);
5475 const widest_int mask
= streamer_read_widest_int (ib
);
5477 = ipa_get_ipa_bits_for_value (value
, mask
);
5478 (*ts
->bits
)[i
] = bits
;
5484 /* Write all aggregate replacement for nodes in set. */
5487 ipcp_write_transformation_summaries (void)
5489 struct cgraph_node
*node
;
5490 struct output_block
*ob
;
5491 unsigned int count
= 0;
5492 lto_symtab_encoder_iterator lsei
;
5493 lto_symtab_encoder_t encoder
;
5495 ob
= create_output_block (LTO_section_ipcp_transform
);
5496 encoder
= ob
->decl_state
->symtab_node_encoder
;
5498 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5499 lsei_next_function_in_partition (&lsei
))
5501 node
= lsei_cgraph_node (lsei
);
5502 if (node
->has_gimple_body_p ())
5506 streamer_write_uhwi (ob
, count
);
5508 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5509 lsei_next_function_in_partition (&lsei
))
5511 node
= lsei_cgraph_node (lsei
);
5512 if (node
->has_gimple_body_p ())
5513 write_ipcp_transformation_info (ob
, node
);
5515 streamer_write_char_stream (ob
->main_stream
, 0);
5516 produce_asm (ob
, NULL
);
5517 destroy_output_block (ob
);
5520 /* Read replacements section in file FILE_DATA of length LEN with data
5524 read_replacements_section (struct lto_file_decl_data
*file_data
,
5528 const struct lto_function_header
*header
=
5529 (const struct lto_function_header
*) data
;
5530 const int cfg_offset
= sizeof (struct lto_function_header
);
5531 const int main_offset
= cfg_offset
+ header
->cfg_size
;
5532 const int string_offset
= main_offset
+ header
->main_size
;
5533 class data_in
*data_in
;
5537 lto_input_block
ib_main ((const char *) data
+ main_offset
,
5538 header
->main_size
, file_data
->mode_table
);
5540 data_in
= lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
5541 header
->string_size
, vNULL
);
5542 count
= streamer_read_uhwi (&ib_main
);
5544 for (i
= 0; i
< count
; i
++)
5547 struct cgraph_node
*node
;
5548 lto_symtab_encoder_t encoder
;
5550 index
= streamer_read_uhwi (&ib_main
);
5551 encoder
= file_data
->symtab_node_encoder
;
5552 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref (encoder
,
5554 gcc_assert (node
->definition
);
5555 read_ipcp_transformation_info (&ib_main
, node
, data_in
);
5557 lto_free_section_data (file_data
, LTO_section_jump_functions
, NULL
, data
,
5559 lto_data_in_delete (data_in
);
5562 /* Read IPA-CP aggregate replacements. */
5565 ipcp_read_transformation_summaries (void)
5567 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
5568 struct lto_file_decl_data
*file_data
;
5571 while ((file_data
= file_data_vec
[j
++]))
5575 = lto_get_summary_section_data (file_data
, LTO_section_ipcp_transform
,
5578 read_replacements_section (file_data
, data
, len
);
5582 /* Adjust the aggregate replacements in AGGVAL to reflect parameters skipped in
5586 adjust_agg_replacement_values (struct cgraph_node
*node
,
5587 struct ipa_agg_replacement_value
*aggval
)
5589 struct ipa_agg_replacement_value
*v
;
5590 clone_info
*cinfo
= clone_info::get (node
);
5592 if (!cinfo
|| !cinfo
->param_adjustments
)
5595 auto_vec
<int, 16> new_indices
;
5596 cinfo
->param_adjustments
->get_updated_indices (&new_indices
);
5597 for (v
= aggval
; v
; v
= v
->next
)
5599 gcc_checking_assert (v
->index
>= 0);
5601 if ((unsigned) v
->index
< new_indices
.length ())
5602 v
->index
= new_indices
[v
->index
];
5604 /* This can happen if we know about a constant passed by reference by
5605 an argument which is never actually used for anything, let alone
5606 loading that constant. */
5611 /* Dominator walker driving the ipcp modification phase. */
5613 class ipcp_modif_dom_walker
: public dom_walker
5616 ipcp_modif_dom_walker (struct ipa_func_body_info
*fbi
,
5617 vec
<ipa_param_descriptor
, va_gc
> *descs
,
5618 struct ipa_agg_replacement_value
*av
,
5620 : dom_walker (CDI_DOMINATORS
), m_fbi (fbi
), m_descriptors (descs
),
5621 m_aggval (av
), m_something_changed (sc
) {}
5623 virtual edge
before_dom_children (basic_block
);
5625 { return gimple_purge_all_dead_eh_edges (m_need_eh_cleanup
); }
5628 struct ipa_func_body_info
*m_fbi
;
5629 vec
<ipa_param_descriptor
, va_gc
> *m_descriptors
;
5630 struct ipa_agg_replacement_value
*m_aggval
;
5631 bool *m_something_changed
;
5632 auto_bitmap m_need_eh_cleanup
;
5636 ipcp_modif_dom_walker::before_dom_children (basic_block bb
)
5638 gimple_stmt_iterator gsi
;
5639 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
5641 struct ipa_agg_replacement_value
*v
;
5642 gimple
*stmt
= gsi_stmt (gsi
);
5644 HOST_WIDE_INT offset
;
5649 if (!gimple_assign_load_p (stmt
))
5651 rhs
= gimple_assign_rhs1 (stmt
);
5652 if (!is_gimple_reg_type (TREE_TYPE (rhs
)))
5657 while (handled_component_p (t
))
5659 /* V_C_E can do things like convert an array of integers to one
5660 bigger integer and similar things we do not handle below. */
5661 if (TREE_CODE (t
) == VIEW_CONVERT_EXPR
)
5666 t
= TREE_OPERAND (t
, 0);
5671 if (!ipa_load_from_parm_agg (m_fbi
, m_descriptors
, stmt
, rhs
, &index
,
5672 &offset
, &size
, &by_ref
))
5674 for (v
= m_aggval
; v
; v
= v
->next
)
5675 if (v
->index
== index
5676 && v
->offset
== offset
)
5679 || v
->by_ref
!= by_ref
5680 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v
->value
))),
5684 gcc_checking_assert (is_gimple_ip_invariant (v
->value
));
5685 if (!useless_type_conversion_p (TREE_TYPE (rhs
), TREE_TYPE (v
->value
)))
5687 if (fold_convertible_p (TREE_TYPE (rhs
), v
->value
))
5688 val
= fold_build1 (NOP_EXPR
, TREE_TYPE (rhs
), v
->value
);
5689 else if (TYPE_SIZE (TREE_TYPE (rhs
))
5690 == TYPE_SIZE (TREE_TYPE (v
->value
)))
5691 val
= fold_build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (rhs
), v
->value
);
5696 fprintf (dump_file
, " const ");
5697 print_generic_expr (dump_file
, v
->value
);
5698 fprintf (dump_file
, " can't be converted to type of ");
5699 print_generic_expr (dump_file
, rhs
);
5700 fprintf (dump_file
, "\n");
5708 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5710 fprintf (dump_file
, "Modifying stmt:\n ");
5711 print_gimple_stmt (dump_file
, stmt
, 0);
5713 gimple_assign_set_rhs_from_tree (&gsi
, val
);
5716 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5718 fprintf (dump_file
, "into:\n ");
5719 print_gimple_stmt (dump_file
, stmt
, 0);
5720 fprintf (dump_file
, "\n");
5723 *m_something_changed
= true;
5724 if (maybe_clean_eh_stmt (stmt
))
5725 bitmap_set_bit (m_need_eh_cleanup
, bb
->index
);
5730 /* Return true if we have recorded VALUE and MASK about PARM.
5731 Set VALUE and MASk accordingly. */
5734 ipcp_get_parm_bits (tree parm
, tree
*value
, widest_int
*mask
)
5736 cgraph_node
*cnode
= cgraph_node::get (current_function_decl
);
5737 ipcp_transformation
*ts
= ipcp_get_transformation_summary (cnode
);
5738 if (!ts
|| vec_safe_length (ts
->bits
) == 0)
5742 for (tree p
= DECL_ARGUMENTS (current_function_decl
);
5743 p
!= parm
; p
= DECL_CHAIN (p
))
5746 /* Ignore static chain. */
5751 clone_info
*cinfo
= clone_info::get (cnode
);
5752 if (cinfo
&& cinfo
->param_adjustments
)
5754 i
= cinfo
->param_adjustments
->get_original_index (i
);
5759 vec
<ipa_bits
*, va_gc
> &bits
= *ts
->bits
;
5762 *mask
= bits
[i
]->mask
;
5763 *value
= wide_int_to_tree (TREE_TYPE (parm
), bits
[i
]->value
);
5768 /* Update bits info of formal parameters as described in
5769 ipcp_transformation. */
5772 ipcp_update_bits (struct cgraph_node
*node
)
5774 ipcp_transformation
*ts
= ipcp_get_transformation_summary (node
);
5776 if (!ts
|| vec_safe_length (ts
->bits
) == 0)
5778 vec
<ipa_bits
*, va_gc
> &bits
= *ts
->bits
;
5779 unsigned count
= bits
.length ();
5783 auto_vec
<int, 16> new_indices
;
5784 bool need_remapping
= false;
5785 clone_info
*cinfo
= clone_info::get (node
);
5786 if (cinfo
&& cinfo
->param_adjustments
)
5788 cinfo
->param_adjustments
->get_updated_indices (&new_indices
);
5789 need_remapping
= true;
5791 auto_vec
<tree
, 16> parm_decls
;
5792 push_function_arg_decls (&parm_decls
, node
->decl
);
5794 for (unsigned i
= 0; i
< count
; ++i
)
5799 if (i
>= new_indices
.length ())
5801 int idx
= new_indices
[i
];
5804 parm
= parm_decls
[idx
];
5807 parm
= parm_decls
[i
];
5808 gcc_checking_assert (parm
);
5812 || !(INTEGRAL_TYPE_P (TREE_TYPE (parm
))
5813 || POINTER_TYPE_P (TREE_TYPE (parm
)))
5814 || !is_gimple_reg (parm
))
5817 tree ddef
= ssa_default_def (DECL_STRUCT_FUNCTION (node
->decl
), parm
);
5823 fprintf (dump_file
, "Adjusting mask for param %u to ", i
);
5824 print_hex (bits
[i
]->mask
, dump_file
);
5825 fprintf (dump_file
, "\n");
5828 if (INTEGRAL_TYPE_P (TREE_TYPE (ddef
)))
5830 unsigned prec
= TYPE_PRECISION (TREE_TYPE (ddef
));
5831 signop sgn
= TYPE_SIGN (TREE_TYPE (ddef
));
5833 wide_int nonzero_bits
= wide_int::from (bits
[i
]->mask
, prec
, UNSIGNED
)
5834 | wide_int::from (bits
[i
]->value
, prec
, sgn
);
5835 set_nonzero_bits (ddef
, nonzero_bits
);
5839 unsigned tem
= bits
[i
]->mask
.to_uhwi ();
5840 unsigned HOST_WIDE_INT bitpos
= bits
[i
]->value
.to_uhwi ();
5841 unsigned align
= tem
& -tem
;
5842 unsigned misalign
= bitpos
& (align
- 1);
5847 fprintf (dump_file
, "Adjusting align: %u, misalign: %u\n", align
, misalign
);
5849 unsigned old_align
, old_misalign
;
5850 struct ptr_info_def
*pi
= get_ptr_info (ddef
);
5851 bool old_known
= get_ptr_info_alignment (pi
, &old_align
, &old_misalign
);
5854 && old_align
> align
)
5858 fprintf (dump_file
, "But alignment was already %u.\n", old_align
);
5859 if ((old_misalign
& (align
- 1)) != misalign
)
5860 fprintf (dump_file
, "old_misalign (%u) and misalign (%u) mismatch\n",
5861 old_misalign
, misalign
);
5867 && ((misalign
& (old_align
- 1)) != old_misalign
)
5869 fprintf (dump_file
, "old_misalign (%u) and misalign (%u) mismatch\n",
5870 old_misalign
, misalign
);
5872 set_ptr_info_alignment (pi
, align
, misalign
);
5879 ipa_vr::nonzero_p (tree expr_type
) const
5881 if (type
== VR_ANTI_RANGE
&& wi::eq_p (min
, 0) && wi::eq_p (max
, 0))
5884 unsigned prec
= TYPE_PRECISION (expr_type
);
5885 return (type
== VR_RANGE
5886 && TYPE_UNSIGNED (expr_type
)
5887 && wi::eq_p (min
, wi::one (prec
))
5888 && wi::eq_p (max
, wi::max_value (prec
, TYPE_SIGN (expr_type
))));
5891 /* Update value range of formal parameters as described in
5892 ipcp_transformation. */
5895 ipcp_update_vr (struct cgraph_node
*node
)
5897 ipcp_transformation
*ts
= ipcp_get_transformation_summary (node
);
5898 if (!ts
|| vec_safe_length (ts
->m_vr
) == 0)
5900 const vec
<ipa_vr
, va_gc
> &vr
= *ts
->m_vr
;
5901 unsigned count
= vr
.length ();
5905 auto_vec
<int, 16> new_indices
;
5906 bool need_remapping
= false;
5907 clone_info
*cinfo
= clone_info::get (node
);
5908 if (cinfo
&& cinfo
->param_adjustments
)
5910 cinfo
->param_adjustments
->get_updated_indices (&new_indices
);
5911 need_remapping
= true;
5913 auto_vec
<tree
, 16> parm_decls
;
5914 push_function_arg_decls (&parm_decls
, node
->decl
);
5916 for (unsigned i
= 0; i
< count
; ++i
)
5922 if (i
>= new_indices
.length ())
5924 remapped_idx
= new_indices
[i
];
5925 if (remapped_idx
< 0)
5931 parm
= parm_decls
[remapped_idx
];
5933 gcc_checking_assert (parm
);
5934 tree ddef
= ssa_default_def (DECL_STRUCT_FUNCTION (node
->decl
), parm
);
5936 if (!ddef
|| !is_gimple_reg (parm
))
5940 && (vr
[i
].type
== VR_RANGE
|| vr
[i
].type
== VR_ANTI_RANGE
))
5942 tree type
= TREE_TYPE (ddef
);
5943 unsigned prec
= TYPE_PRECISION (type
);
5944 if (INTEGRAL_TYPE_P (TREE_TYPE (ddef
)))
5948 fprintf (dump_file
, "Setting value range of param %u "
5949 "(now %i) ", i
, remapped_idx
);
5950 fprintf (dump_file
, "%s[",
5951 (vr
[i
].type
== VR_ANTI_RANGE
) ? "~" : "");
5952 print_decs (vr
[i
].min
, dump_file
);
5953 fprintf (dump_file
, ", ");
5954 print_decs (vr
[i
].max
, dump_file
);
5955 fprintf (dump_file
, "]\n");
5957 set_range_info (ddef
, vr
[i
].type
,
5958 wide_int_storage::from (vr
[i
].min
, prec
,
5960 wide_int_storage::from (vr
[i
].max
, prec
,
5963 else if (POINTER_TYPE_P (TREE_TYPE (ddef
))
5964 && vr
[i
].nonzero_p (TREE_TYPE (ddef
)))
5967 fprintf (dump_file
, "Setting nonnull for %u\n", i
);
5968 set_ptr_nonnull (ddef
);
5974 /* IPCP transformation phase doing propagation of aggregate values. */
5977 ipcp_transform_function (struct cgraph_node
*node
)
5979 vec
<ipa_param_descriptor
, va_gc
> *descriptors
= NULL
;
5980 struct ipa_func_body_info fbi
;
5981 struct ipa_agg_replacement_value
*aggval
;
5983 bool something_changed
= false;
5985 gcc_checking_assert (cfun
);
5986 gcc_checking_assert (current_function_decl
);
5989 fprintf (dump_file
, "Modification phase of node %s\n",
5990 node
->dump_name ());
5992 ipcp_update_bits (node
);
5993 ipcp_update_vr (node
);
5994 aggval
= ipa_get_agg_replacements_for_node (node
);
5997 param_count
= count_formal_params (node
->decl
);
5998 if (param_count
== 0)
6000 adjust_agg_replacement_values (node
, aggval
);
6002 ipa_dump_agg_replacement_values (dump_file
, aggval
);
6006 fbi
.bb_infos
= vNULL
;
6007 fbi
.bb_infos
.safe_grow_cleared (last_basic_block_for_fn (cfun
), true);
6008 fbi
.param_count
= param_count
;
6009 fbi
.aa_walk_budget
= opt_for_fn (node
->decl
, param_ipa_max_aa_steps
);
6011 vec_safe_grow_cleared (descriptors
, param_count
, true);
6012 ipa_populate_param_decls (node
, *descriptors
);
6013 calculate_dominance_info (CDI_DOMINATORS
);
6014 ipcp_modif_dom_walker
walker (&fbi
, descriptors
, aggval
, &something_changed
);
6015 walker
.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
6016 free_dominance_info (CDI_DOMINATORS
);
6017 bool cfg_changed
= walker
.cleanup_eh ();
6020 struct ipa_bb_info
*bi
;
6021 FOR_EACH_VEC_ELT (fbi
.bb_infos
, i
, bi
)
6022 free_ipa_bb_info (bi
);
6023 fbi
.bb_infos
.release ();
6025 ipcp_transformation
*s
= ipcp_transformation_sum
->get (node
);
6026 s
->agg_values
= NULL
;
6030 vec_free (descriptors
);
6032 if (!something_changed
)
6036 delete_unreachable_blocks_update_callgraph (node
, false);
6038 return TODO_update_ssa_only_virtuals
;
6042 /* Return true if OTHER describes same agg value. */
6044 ipa_agg_value::equal_to (const ipa_agg_value
&other
)
6046 return offset
== other
.offset
6047 && operand_equal_p (value
, other
.value
, 0);
6050 /* Destructor also removing individual aggregate values. */
6052 ipa_auto_call_arg_values::~ipa_auto_call_arg_values ()
6054 ipa_release_agg_values (m_known_aggs
, false);
6059 #include "gt-ipa-prop.h"