1 /* Interprocedural analyses.
2 Copyright (C) 2005-2024 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-iterator.h"
35 #include "gimple-fold.h"
38 #include "stor-layout.h"
39 #include "print-tree.h"
41 #include "gimplify-me.h"
42 #include "gimple-walk.h"
43 #include "symbol-summary.h"
49 #include "tree-inline.h"
50 #include "ipa-fnsummary.h"
51 #include "gimple-pretty-print.h"
52 #include "ipa-utils.h"
56 #include "tree-cfgcleanup.h"
58 #include "symtab-clones.h"
59 #include "attr-fnspec.h"
60 #include "gimple-range.h"
61 #include "value-range-storage.h"
63 /* Function summary where the parameter infos are actually stored. */
64 ipa_node_params_t
*ipa_node_params_sum
= NULL
;
66 function_summary
<ipcp_transformation
*> *ipcp_transformation_sum
= NULL
;
68 /* Edge summary for IPA-CP edge information. */
69 ipa_edge_args_sum_t
*ipa_edge_args_sum
;
71 /* Traits for a hash table for reusing ranges. */
73 struct ipa_vr_ggc_hash_traits
: public ggc_cache_remove
<ipa_vr
*>
75 typedef ipa_vr
*value_type
;
76 typedef const vrange
*compare_type
;
78 hash (const ipa_vr
*p
)
80 // This never get called, except in the verification code, as
81 // ipa_get_value_range() calculates the hash itself. This
82 // function is mostly here for completness' sake.
86 add_vrange (vr
, hstate
);
90 equal (const ipa_vr
*a
, const vrange
*b
)
92 return a
->equal_p (*b
);
94 static const bool empty_zero_p
= true;
96 mark_empty (ipa_vr
*&p
)
101 is_empty (const ipa_vr
*p
)
106 is_deleted (const ipa_vr
*p
)
108 return p
== reinterpret_cast<const ipa_vr
*> (1);
111 mark_deleted (ipa_vr
*&p
)
113 p
= reinterpret_cast<ipa_vr
*> (1);
117 /* Hash table for avoid repeated allocations of equal ranges. */
118 static GTY ((cache
)) hash_table
<ipa_vr_ggc_hash_traits
> *ipa_vr_hash_table
;
120 /* Holders of ipa cgraph hooks: */
121 static struct cgraph_node_hook_list
*function_insertion_hook_holder
;
123 /* Description of a reference to an IPA constant. */
124 struct ipa_cst_ref_desc
126 /* Edge that corresponds to the statement which took the reference. */
127 struct cgraph_edge
*cs
;
128 /* Linked list of duplicates created when call graph edges are cloned. */
129 struct ipa_cst_ref_desc
*next_duplicate
;
130 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
131 if out of control. */
135 /* Allocation pool for reference descriptions. */
137 static object_allocator
<ipa_cst_ref_desc
> ipa_refdesc_pool
138 ("IPA-PROP ref descriptions");
146 ipa_vr::ipa_vr (const vrange
&r
)
147 : m_storage (ggc_alloc_vrange_storage (r
)),
153 ipa_vr::equal_p (const vrange
&r
) const
155 gcc_checking_assert (!r
.undefined_p ());
156 return (types_compatible_p (m_type
, r
.type ()) && m_storage
->equal_p (r
));
160 ipa_vr::get_vrange (Value_Range
&r
) const
163 m_storage
->get_vrange (r
, m_type
);
167 ipa_vr::set_unknown ()
170 ggc_free (m_storage
);
176 ipa_vr::streamer_read (lto_input_block
*ib
, data_in
*data_in
)
178 struct bitpack_d bp
= streamer_read_bitpack (ib
);
179 bool known
= bp_unpack_value (&bp
, 1);
183 streamer_read_value_range (ib
, data_in
, vr
);
184 if (!m_storage
|| !m_storage
->fits_p (vr
))
187 ggc_free (m_storage
);
188 m_storage
= ggc_alloc_vrange_storage (vr
);
190 m_storage
->set_vrange (vr
);
201 ipa_vr::streamer_write (output_block
*ob
) const
203 struct bitpack_d bp
= bitpack_create (ob
->main_stream
);
204 bp_pack_value (&bp
, !!m_storage
, 1);
205 streamer_write_bitpack (&bp
);
208 Value_Range
vr (m_type
);
209 m_storage
->get_vrange (vr
, m_type
);
210 streamer_write_vrange (ob
, vr
);
215 ipa_vr::dump (FILE *out
) const
219 Value_Range
vr (m_type
);
220 m_storage
->get_vrange (vr
, m_type
);
224 fprintf (out
, "NO RANGE");
227 // These stubs are because we use an ipa_vr in a hash_traits and
228 // hash-traits.h defines an extern of gt_ggc_mx (T &) instead of
229 // picking up the gt_ggc_mx (T *) version.
231 gt_pch_nx (ipa_vr
*&x
)
233 return gt_pch_nx ((ipa_vr
*) x
);
237 gt_ggc_mx (ipa_vr
*&x
)
239 return gt_ggc_mx ((ipa_vr
*) x
);
242 /* Analysis summery of function call return value. */
243 struct GTY(()) ipa_return_value_summary
245 /* Known value range.
246 This needs to be wrapped in struccture due to specific way
247 we allocate ipa_vr. */
251 /* Function summary for return values. */
252 class ipa_return_value_sum_t
: public function_summary
<ipa_return_value_summary
*>
255 ipa_return_value_sum_t (symbol_table
*table
, bool ggc
):
256 function_summary
<ipa_return_value_summary
*> (table
, ggc
) { }
258 /* Hook that is called by summary when a node is duplicated. */
259 void duplicate (cgraph_node
*,
261 ipa_return_value_summary
*data
,
262 ipa_return_value_summary
*data2
) final override
268 /* Variable hoding the return value summary. */
269 static GTY(()) function_summary
<ipa_return_value_summary
*> *ipa_return_value_sum
;
272 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
273 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
276 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node
*node
)
278 tree fs_opts
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node
->decl
);
282 return !opt_for_fn (node
->decl
, optimize
) || !opt_for_fn (node
->decl
, flag_ipa_cp
);
285 /* Return index of the formal whose tree is PTREE in function which corresponds
289 ipa_get_param_decl_index_1 (vec
<ipa_param_descriptor
, va_gc
> *descriptors
,
294 count
= vec_safe_length (descriptors
);
295 for (i
= 0; i
< count
; i
++)
296 if ((*descriptors
)[i
].decl_or_type
== ptree
)
302 /* Return index of the formal whose tree is PTREE in function which corresponds
306 ipa_get_param_decl_index (class ipa_node_params
*info
, tree ptree
)
308 return ipa_get_param_decl_index_1 (info
->descriptors
, ptree
);
311 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
315 ipa_populate_param_decls (struct cgraph_node
*node
,
316 vec
<ipa_param_descriptor
, va_gc
> &descriptors
)
324 gcc_assert (gimple_has_body_p (fndecl
));
325 fnargs
= DECL_ARGUMENTS (fndecl
);
327 for (parm
= fnargs
; parm
; parm
= DECL_CHAIN (parm
))
329 descriptors
[param_num
].decl_or_type
= parm
;
330 unsigned int cost
= estimate_move_cost (TREE_TYPE (parm
), true);
331 descriptors
[param_num
].move_cost
= cost
;
332 /* Watch overflow, move_cost is a bitfield. */
333 gcc_checking_assert (cost
== descriptors
[param_num
].move_cost
);
338 /* Return how many formal parameters FNDECL has. */
341 count_formal_params (tree fndecl
)
345 gcc_assert (gimple_has_body_p (fndecl
));
347 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
353 /* Return the declaration of Ith formal parameter of the function corresponding
354 to INFO. Note there is no setter function as this array is built just once
355 using ipa_initialize_node_params. */
358 ipa_dump_param (FILE *file
, class ipa_node_params
*info
, int i
)
360 fprintf (file
, "param #%i", i
);
361 if ((*info
->descriptors
)[i
].decl_or_type
)
364 print_generic_expr (file
, (*info
->descriptors
)[i
].decl_or_type
);
368 /* If necessary, allocate vector of parameter descriptors in info of NODE.
369 Return true if they were allocated, false if not. */
372 ipa_alloc_node_params (struct cgraph_node
*node
, int param_count
)
374 ipa_node_params
*info
= ipa_node_params_sum
->get_create (node
);
376 if (!info
->descriptors
&& param_count
)
378 vec_safe_grow_cleared (info
->descriptors
, param_count
, true);
385 /* Initialize the ipa_node_params structure associated with NODE by counting
386 the function parameters, creating the descriptors and populating their
390 ipa_initialize_node_params (struct cgraph_node
*node
)
392 ipa_node_params
*info
= ipa_node_params_sum
->get_create (node
);
394 if (!info
->descriptors
395 && ipa_alloc_node_params (node
, count_formal_params (node
->decl
)))
396 ipa_populate_param_decls (node
, *info
->descriptors
);
399 /* Print VAL which is extracted from a jump function to F. */
402 ipa_print_constant_value (FILE *f
, tree val
)
404 print_generic_expr (f
, val
);
406 /* This is in keeping with values_equal_for_ipcp_p. */
407 if (TREE_CODE (val
) == ADDR_EXPR
408 && (TREE_CODE (TREE_OPERAND (val
, 0)) == CONST_DECL
409 || (TREE_CODE (TREE_OPERAND (val
, 0)) == VAR_DECL
410 && DECL_IN_CONSTANT_POOL (TREE_OPERAND (val
, 0)))))
413 print_generic_expr (f
, DECL_INITIAL (TREE_OPERAND (val
, 0)));
417 /* Print the jump functions associated with call graph edge CS to file F. */
420 ipa_print_node_jump_functions_for_edge (FILE *f
, struct cgraph_edge
*cs
)
422 ipa_edge_args
*args
= ipa_edge_args_sum
->get (cs
);
423 int count
= ipa_get_cs_argument_count (args
);
425 for (int i
= 0; i
< count
; i
++)
427 struct ipa_jump_func
*jump_func
;
428 enum jump_func_type type
;
430 jump_func
= ipa_get_ith_jump_func (args
, i
);
431 type
= jump_func
->type
;
433 fprintf (f
, " param %d: ", i
);
434 if (type
== IPA_JF_UNKNOWN
)
435 fprintf (f
, "UNKNOWN\n");
436 else if (type
== IPA_JF_CONST
)
438 fprintf (f
, "CONST: ");
439 ipa_print_constant_value (f
, jump_func
->value
.constant
.value
);
442 else if (type
== IPA_JF_PASS_THROUGH
)
444 fprintf (f
, "PASS THROUGH: ");
445 fprintf (f
, "%d, op %s",
446 jump_func
->value
.pass_through
.formal_id
,
447 get_tree_code_name(jump_func
->value
.pass_through
.operation
));
448 if (jump_func
->value
.pass_through
.operation
!= NOP_EXPR
)
451 print_generic_expr (f
, jump_func
->value
.pass_through
.operand
);
453 if (jump_func
->value
.pass_through
.agg_preserved
)
454 fprintf (f
, ", agg_preserved");
455 if (jump_func
->value
.pass_through
.refdesc_decremented
)
456 fprintf (f
, ", refdesc_decremented");
459 else if (type
== IPA_JF_ANCESTOR
)
461 fprintf (f
, "ANCESTOR: ");
462 fprintf (f
, "%d, offset " HOST_WIDE_INT_PRINT_DEC
,
463 jump_func
->value
.ancestor
.formal_id
,
464 jump_func
->value
.ancestor
.offset
);
465 if (jump_func
->value
.ancestor
.agg_preserved
)
466 fprintf (f
, ", agg_preserved");
467 if (jump_func
->value
.ancestor
.keep_null
)
468 fprintf (f
, ", keep_null");
472 if (jump_func
->agg
.items
)
474 struct ipa_agg_jf_item
*item
;
477 fprintf (f
, " Aggregate passed by %s:\n",
478 jump_func
->agg
.by_ref
? "reference" : "value");
479 FOR_EACH_VEC_ELT (*jump_func
->agg
.items
, j
, item
)
481 fprintf (f
, " offset: " HOST_WIDE_INT_PRINT_DEC
", ",
483 fprintf (f
, "type: ");
484 print_generic_expr (f
, item
->type
);
486 if (item
->jftype
== IPA_JF_PASS_THROUGH
)
487 fprintf (f
, "PASS THROUGH: %d,",
488 item
->value
.pass_through
.formal_id
);
489 else if (item
->jftype
== IPA_JF_LOAD_AGG
)
491 fprintf (f
, "LOAD AGG: %d",
492 item
->value
.pass_through
.formal_id
);
493 fprintf (f
, " [offset: " HOST_WIDE_INT_PRINT_DEC
", by %s],",
494 item
->value
.load_agg
.offset
,
495 item
->value
.load_agg
.by_ref
? "reference"
499 if (item
->jftype
== IPA_JF_PASS_THROUGH
500 || item
->jftype
== IPA_JF_LOAD_AGG
)
502 fprintf (f
, " op %s",
503 get_tree_code_name (item
->value
.pass_through
.operation
));
504 if (item
->value
.pass_through
.operation
!= NOP_EXPR
)
507 print_generic_expr (f
, item
->value
.pass_through
.operand
);
510 else if (item
->jftype
== IPA_JF_CONST
)
512 fprintf (f
, "CONST: ");
513 ipa_print_constant_value (f
, item
->value
.constant
);
515 else if (item
->jftype
== IPA_JF_UNKNOWN
)
516 fprintf (f
, "UNKNOWN: " HOST_WIDE_INT_PRINT_DEC
" bits",
517 tree_to_uhwi (TYPE_SIZE (item
->type
)));
522 class ipa_polymorphic_call_context
*ctx
523 = ipa_get_ith_polymorhic_call_context (args
, i
);
524 if (ctx
&& !ctx
->useless_p ())
526 fprintf (f
, " Context: ");
527 ctx
->dump (dump_file
);
532 jump_func
->m_vr
->dump (f
);
536 fprintf (f
, " Unknown VR\n");
541 /* Print the jump functions of all arguments on all call graph edges going from
545 ipa_print_node_jump_functions (FILE *f
, struct cgraph_node
*node
)
547 struct cgraph_edge
*cs
;
549 fprintf (f
, " Jump functions of caller %s:\n", node
->dump_name ());
550 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
553 fprintf (f
, " callsite %s -> %s : \n",
555 cs
->callee
->dump_name ());
556 if (!ipa_edge_args_info_available_for_edge_p (cs
))
557 fprintf (f
, " no arg info\n");
559 ipa_print_node_jump_functions_for_edge (f
, cs
);
562 for (cs
= node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
564 class cgraph_indirect_call_info
*ii
;
566 ii
= cs
->indirect_info
;
567 if (ii
->agg_contents
)
568 fprintf (f
, " indirect %s callsite, calling param %i, "
569 "offset " HOST_WIDE_INT_PRINT_DEC
", %s",
570 ii
->member_ptr
? "member ptr" : "aggregate",
571 ii
->param_index
, ii
->offset
,
572 ii
->by_ref
? "by reference" : "by_value");
574 fprintf (f
, " indirect %s callsite, calling param %i, "
575 "offset " HOST_WIDE_INT_PRINT_DEC
,
576 ii
->polymorphic
? "polymorphic" : "simple", ii
->param_index
,
581 fprintf (f
, ", for stmt ");
582 print_gimple_stmt (f
, cs
->call_stmt
, 0, TDF_SLIM
);
587 ii
->context
.dump (f
);
588 if (!ipa_edge_args_info_available_for_edge_p (cs
))
589 fprintf (f
, " no arg info\n");
591 ipa_print_node_jump_functions_for_edge (f
, cs
);
595 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
598 ipa_print_all_jump_functions (FILE *f
)
600 struct cgraph_node
*node
;
602 fprintf (f
, "\nJump functions:\n");
603 FOR_EACH_FUNCTION (node
)
605 ipa_print_node_jump_functions (f
, node
);
609 /* Set jfunc to be a know-really nothing jump function. */
612 ipa_set_jf_unknown (struct ipa_jump_func
*jfunc
)
614 jfunc
->type
= IPA_JF_UNKNOWN
;
617 /* Set JFUNC to be a copy of another jmp (to be used by jump function
618 combination code). The two functions will share their rdesc. */
621 ipa_set_jf_cst_copy (struct ipa_jump_func
*dst
,
622 struct ipa_jump_func
*src
)
625 gcc_checking_assert (src
->type
== IPA_JF_CONST
);
626 dst
->type
= IPA_JF_CONST
;
627 dst
->value
.constant
= src
->value
.constant
;
630 /* Set JFUNC to be a constant jmp function. */
633 ipa_set_jf_constant (struct ipa_jump_func
*jfunc
, tree constant
,
634 struct cgraph_edge
*cs
)
636 jfunc
->type
= IPA_JF_CONST
;
637 jfunc
->value
.constant
.value
= unshare_expr_without_location (constant
);
639 if (TREE_CODE (constant
) == ADDR_EXPR
640 && (TREE_CODE (TREE_OPERAND (constant
, 0)) == FUNCTION_DECL
641 || (VAR_P (TREE_OPERAND (constant
, 0))
642 && TREE_STATIC (TREE_OPERAND (constant
, 0)))))
644 struct ipa_cst_ref_desc
*rdesc
;
646 rdesc
= ipa_refdesc_pool
.allocate ();
648 rdesc
->next_duplicate
= NULL
;
650 jfunc
->value
.constant
.rdesc
= rdesc
;
653 jfunc
->value
.constant
.rdesc
= NULL
;
656 /* Set JFUNC to be a simple pass-through jump function. */
658 ipa_set_jf_simple_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
661 jfunc
->type
= IPA_JF_PASS_THROUGH
;
662 jfunc
->value
.pass_through
.operand
= NULL_TREE
;
663 jfunc
->value
.pass_through
.formal_id
= formal_id
;
664 jfunc
->value
.pass_through
.operation
= NOP_EXPR
;
665 jfunc
->value
.pass_through
.agg_preserved
= agg_preserved
;
666 jfunc
->value
.pass_through
.refdesc_decremented
= false;
669 /* Set JFUNC to be an unary pass through jump function. */
672 ipa_set_jf_unary_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
673 enum tree_code operation
)
675 jfunc
->type
= IPA_JF_PASS_THROUGH
;
676 jfunc
->value
.pass_through
.operand
= NULL_TREE
;
677 jfunc
->value
.pass_through
.formal_id
= formal_id
;
678 jfunc
->value
.pass_through
.operation
= operation
;
679 jfunc
->value
.pass_through
.agg_preserved
= false;
680 jfunc
->value
.pass_through
.refdesc_decremented
= false;
682 /* Set JFUNC to be an arithmetic pass through jump function. */
685 ipa_set_jf_arith_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
686 tree operand
, enum tree_code operation
)
688 jfunc
->type
= IPA_JF_PASS_THROUGH
;
689 jfunc
->value
.pass_through
.operand
= unshare_expr_without_location (operand
);
690 jfunc
->value
.pass_through
.formal_id
= formal_id
;
691 jfunc
->value
.pass_through
.operation
= operation
;
692 jfunc
->value
.pass_through
.agg_preserved
= false;
693 jfunc
->value
.pass_through
.refdesc_decremented
= false;
696 /* Set JFUNC to be an ancestor jump function. */
699 ipa_set_ancestor_jf (struct ipa_jump_func
*jfunc
, HOST_WIDE_INT offset
,
700 int formal_id
, bool agg_preserved
, bool keep_null
)
702 jfunc
->type
= IPA_JF_ANCESTOR
;
703 jfunc
->value
.ancestor
.formal_id
= formal_id
;
704 jfunc
->value
.ancestor
.offset
= offset
;
705 jfunc
->value
.ancestor
.agg_preserved
= agg_preserved
;
706 jfunc
->value
.ancestor
.keep_null
= keep_null
;
709 /* Get IPA BB information about the given BB. FBI is the context of analyzis
710 of this function body. */
712 static struct ipa_bb_info
*
713 ipa_get_bb_info (struct ipa_func_body_info
*fbi
, basic_block bb
)
715 gcc_checking_assert (fbi
);
716 return &fbi
->bb_infos
[bb
->index
];
719 /* Structure to be passed in between detect_type_change and
720 check_stmt_for_type_change. */
722 struct prop_type_change_info
724 /* Offset into the object where there is the virtual method pointer we are
726 HOST_WIDE_INT offset
;
727 /* The declaration or SSA_NAME pointer of the base that we are checking for
730 /* Set to true if dynamic type change has been detected. */
731 bool type_maybe_changed
;
734 /* Return true if STMT can modify a virtual method table pointer.
736 This function makes special assumptions about both constructors and
737 destructors which are all the functions that are allowed to alter the VMT
738 pointers. It assumes that destructors begin with assignment into all VMT
739 pointers and that constructors essentially look in the following way:
741 1) The very first thing they do is that they call constructors of ancestor
742 sub-objects that have them.
744 2) Then VMT pointers of this and all its ancestors is set to new values
745 corresponding to the type corresponding to the constructor.
747 3) Only afterwards, other stuff such as constructor of member sub-objects
748 and the code written by the user is run. Only this may include calling
749 virtual functions, directly or indirectly.
751 There is no way to call a constructor of an ancestor sub-object in any
754 This means that we do not have to care whether constructors get the correct
755 type information because they will always change it (in fact, if we define
756 the type to be given by the VMT pointer, it is undefined).
758 The most important fact to derive from the above is that if, for some
759 statement in the section 3, we try to detect whether the dynamic type has
760 changed, we can safely ignore all calls as we examine the function body
761 backwards until we reach statements in section 2 because these calls cannot
762 be ancestor constructors or destructors (if the input is not bogus) and so
763 do not change the dynamic type (this holds true only for automatically
764 allocated objects but at the moment we devirtualize only these). We then
765 must detect that statements in section 2 change the dynamic type and can try
766 to derive the new type. That is enough and we can stop, we will never see
767 the calls into constructors of sub-objects in this code. Therefore we can
768 safely ignore all call statements that we traverse.
772 stmt_may_be_vtbl_ptr_store (gimple
*stmt
)
774 if (is_gimple_call (stmt
))
776 if (gimple_clobber_p (stmt
))
778 else if (is_gimple_assign (stmt
))
780 tree lhs
= gimple_assign_lhs (stmt
);
782 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs
)))
784 if (flag_strict_aliasing
785 && !POINTER_TYPE_P (TREE_TYPE (lhs
)))
788 if (TREE_CODE (lhs
) == COMPONENT_REF
789 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs
, 1)))
791 /* In the future we might want to use get_ref_base_and_extent to find
792 if there is a field corresponding to the offset and if so, proceed
793 almost like if it was a component ref. */
799 /* Callback of walk_aliased_vdefs and a helper function for detect_type_change
800 to check whether a particular statement may modify the virtual table
801 pointerIt stores its result into DATA, which points to a
802 prop_type_change_info structure. */
805 check_stmt_for_type_change (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef
, void *data
)
807 gimple
*stmt
= SSA_NAME_DEF_STMT (vdef
);
808 struct prop_type_change_info
*tci
= (struct prop_type_change_info
*) data
;
810 if (stmt_may_be_vtbl_ptr_store (stmt
))
812 tci
->type_maybe_changed
= true;
819 /* See if ARG is PARAM_DECl describing instance passed by pointer
820 or reference in FUNCTION. Return false if the dynamic type may change
821 in between beggining of the function until CALL is invoked.
823 Generally functions are not allowed to change type of such instances,
824 but they call destructors. We assume that methods cannot destroy the THIS
825 pointer. Also as a special cases, constructor and destructors may change
826 type of the THIS pointer. */
829 param_type_may_change_p (tree function
, tree arg
, gimple
*call
)
831 /* Pure functions cannot do any changes on the dynamic type;
832 that require writting to memory. */
833 if (flags_from_decl_or_type (function
) & (ECF_PURE
| ECF_CONST
))
835 /* We need to check if we are within inlined consturctor
836 or destructor (ideally we would have way to check that the
837 inline cdtor is actually working on ARG, but we don't have
838 easy tie on this, so punt on all non-pure cdtors.
839 We may also record the types of cdtors and once we know type
840 of the instance match them.
842 Also code unification optimizations may merge calls from
843 different blocks making return values unreliable. So
844 do nothing during late optimization. */
845 if (DECL_STRUCT_FUNCTION (function
)->after_inlining
)
847 if (TREE_CODE (arg
) == SSA_NAME
848 && SSA_NAME_IS_DEFAULT_DEF (arg
)
849 && TREE_CODE (SSA_NAME_VAR (arg
)) == PARM_DECL
)
851 /* Normal (non-THIS) argument. */
852 if ((SSA_NAME_VAR (arg
) != DECL_ARGUMENTS (function
)
853 || TREE_CODE (TREE_TYPE (function
)) != METHOD_TYPE
)
854 /* THIS pointer of an method - here we want to watch constructors
855 and destructors as those definitely may change the dynamic
857 || (TREE_CODE (TREE_TYPE (function
)) == METHOD_TYPE
858 && !DECL_CXX_CONSTRUCTOR_P (function
)
859 && !DECL_CXX_DESTRUCTOR_P (function
)
860 && (SSA_NAME_VAR (arg
) == DECL_ARGUMENTS (function
))))
862 /* Walk the inline stack and watch out for ctors/dtors. */
863 for (tree block
= gimple_block (call
); block
&& TREE_CODE (block
) == BLOCK
;
864 block
= BLOCK_SUPERCONTEXT (block
))
865 if (inlined_polymorphic_ctor_dtor_block_p (block
, false))
873 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
874 callsite CALL) by looking for assignments to its virtual table pointer. If
875 it is, return true. ARG is the object itself (not a pointer
876 to it, unless dereferenced). BASE is the base of the memory access as
877 returned by get_ref_base_and_extent, as is the offset.
879 This is helper function for detect_type_change and detect_type_change_ssa
880 that does the heavy work which is usually unnecesary. */
883 detect_type_change_from_memory_writes (ipa_func_body_info
*fbi
, tree arg
,
884 tree base
, tree comp_type
, gcall
*call
,
885 HOST_WIDE_INT offset
)
887 struct prop_type_change_info tci
;
890 gcc_checking_assert (DECL_P (arg
)
891 || TREE_CODE (arg
) == MEM_REF
892 || handled_component_p (arg
));
894 comp_type
= TYPE_MAIN_VARIANT (comp_type
);
896 /* Const calls cannot call virtual methods through VMT and so type changes do
898 if (!flag_devirtualize
|| !gimple_vuse (call
)
899 /* Be sure expected_type is polymorphic. */
901 || TREE_CODE (comp_type
) != RECORD_TYPE
902 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type
))
903 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type
))))
906 if (fbi
->aa_walk_budget
== 0)
909 ao_ref_init (&ao
, arg
);
912 ao
.size
= POINTER_SIZE
;
913 ao
.max_size
= ao
.size
;
916 tci
.object
= get_base_address (arg
);
917 tci
.type_maybe_changed
= false;
920 = walk_aliased_vdefs (&ao
, gimple_vuse (call
), check_stmt_for_type_change
,
921 &tci
, NULL
, NULL
, fbi
->aa_walk_budget
);
923 fbi
->aa_walk_budget
-= walked
;
925 fbi
->aa_walk_budget
= 0;
927 if (walked
>= 0 && !tci
.type_maybe_changed
)
933 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
934 If it is, return true. ARG is the object itself (not a pointer
935 to it, unless dereferenced). BASE is the base of the memory access as
936 returned by get_ref_base_and_extent, as is the offset. */
939 detect_type_change (ipa_func_body_info
*fbi
, tree arg
, tree base
,
940 tree comp_type
, gcall
*call
,
941 HOST_WIDE_INT offset
)
943 if (!flag_devirtualize
)
946 if (TREE_CODE (base
) == MEM_REF
947 && !param_type_may_change_p (current_function_decl
,
948 TREE_OPERAND (base
, 0),
951 return detect_type_change_from_memory_writes (fbi
, arg
, base
, comp_type
,
955 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
956 SSA name (its dereference will become the base and the offset is assumed to
960 detect_type_change_ssa (ipa_func_body_info
*fbi
, tree arg
, tree comp_type
,
963 gcc_checking_assert (TREE_CODE (arg
) == SSA_NAME
);
964 if (!flag_devirtualize
965 || !POINTER_TYPE_P (TREE_TYPE (arg
)))
968 if (!param_type_may_change_p (current_function_decl
, arg
, call
))
971 arg
= build2 (MEM_REF
, ptr_type_node
, arg
,
972 build_int_cst (ptr_type_node
, 0));
974 return detect_type_change_from_memory_writes (fbi
, arg
, arg
, comp_type
,
978 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
979 boolean variable pointed to by DATA. */
982 mark_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
985 bool *b
= (bool *) data
;
990 /* Find the nearest valid aa status for parameter specified by INDEX that
993 static struct ipa_param_aa_status
*
994 find_dominating_aa_status (struct ipa_func_body_info
*fbi
, basic_block bb
,
999 bb
= get_immediate_dominator (CDI_DOMINATORS
, bb
);
1002 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
1003 if (!bi
->param_aa_statuses
.is_empty ()
1004 && bi
->param_aa_statuses
[index
].valid
)
1005 return &bi
->param_aa_statuses
[index
];
1009 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
1010 structures and/or intialize the result with a dominating description as
1013 static struct ipa_param_aa_status
*
1014 parm_bb_aa_status_for_bb (struct ipa_func_body_info
*fbi
, basic_block bb
,
1017 gcc_checking_assert (fbi
);
1018 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
1019 if (bi
->param_aa_statuses
.is_empty ())
1020 bi
->param_aa_statuses
.safe_grow_cleared (fbi
->param_count
, true);
1021 struct ipa_param_aa_status
*paa
= &bi
->param_aa_statuses
[index
];
1024 gcc_checking_assert (!paa
->parm_modified
1025 && !paa
->ref_modified
1026 && !paa
->pt_modified
);
1027 struct ipa_param_aa_status
*dom_paa
;
1028 dom_paa
= find_dominating_aa_status (fbi
, bb
, index
);
1038 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
1039 a value known not to be modified in this function before reaching the
1040 statement STMT. FBI holds information about the function we have so far
1041 gathered but do not survive the summary building stage. */
1044 parm_preserved_before_stmt_p (struct ipa_func_body_info
*fbi
, int index
,
1045 gimple
*stmt
, tree parm_load
)
1047 struct ipa_param_aa_status
*paa
;
1048 bool modified
= false;
1051 tree base
= get_base_address (parm_load
);
1052 gcc_assert (TREE_CODE (base
) == PARM_DECL
);
1053 if (TREE_READONLY (base
))
1056 gcc_checking_assert (fbi
);
1057 paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (stmt
), index
);
1058 if (paa
->parm_modified
|| fbi
->aa_walk_budget
== 0)
1061 gcc_checking_assert (gimple_vuse (stmt
) != NULL_TREE
);
1062 ao_ref_init (&refd
, parm_load
);
1063 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), mark_modified
,
1064 &modified
, NULL
, NULL
,
1065 fbi
->aa_walk_budget
);
1069 fbi
->aa_walk_budget
= 0;
1072 fbi
->aa_walk_budget
-= walked
;
1073 if (paa
&& modified
)
1074 paa
->parm_modified
= true;
1078 /* If STMT is an assignment that loads a value from an parameter declaration,
1079 return the index of the parameter in ipa_node_params which has not been
1080 modified. Otherwise return -1. */
1083 load_from_unmodified_param (struct ipa_func_body_info
*fbi
,
1084 vec
<ipa_param_descriptor
, va_gc
> *descriptors
,
1090 if (!gimple_assign_single_p (stmt
))
1093 op1
= gimple_assign_rhs1 (stmt
);
1094 if (TREE_CODE (op1
) != PARM_DECL
)
1097 index
= ipa_get_param_decl_index_1 (descriptors
, op1
);
1099 || !parm_preserved_before_stmt_p (fbi
, index
, stmt
, op1
))
1105 /* Return true if memory reference REF (which must be a load through parameter
1106 with INDEX) loads data that are known to be unmodified in this function
1107 before reaching statement STMT. */
1110 parm_ref_data_preserved_p (struct ipa_func_body_info
*fbi
,
1111 int index
, gimple
*stmt
, tree ref
)
1113 struct ipa_param_aa_status
*paa
;
1114 bool modified
= false;
1117 gcc_checking_assert (fbi
);
1118 paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (stmt
), index
);
1119 if (paa
->ref_modified
|| fbi
->aa_walk_budget
== 0)
1122 gcc_checking_assert (gimple_vuse (stmt
));
1123 ao_ref_init (&refd
, ref
);
1124 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), mark_modified
,
1125 &modified
, NULL
, NULL
,
1126 fbi
->aa_walk_budget
);
1130 fbi
->aa_walk_budget
= 0;
1133 fbi
->aa_walk_budget
-= walked
;
1135 paa
->ref_modified
= true;
1139 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
1140 is known to be unmodified in this function before reaching call statement
1141 CALL into which it is passed. FBI describes the function body. */
1144 parm_ref_data_pass_through_p (struct ipa_func_body_info
*fbi
, int index
,
1145 gimple
*call
, tree parm
)
1147 bool modified
= false;
1150 /* It's unnecessary to calculate anything about memory contnets for a const
1151 function because it is not goin to use it. But do not cache the result
1152 either. Also, no such calculations for non-pointers. */
1153 if (!gimple_vuse (call
)
1154 || !POINTER_TYPE_P (TREE_TYPE (parm
)))
1157 struct ipa_param_aa_status
*paa
= parm_bb_aa_status_for_bb (fbi
,
1160 if (paa
->pt_modified
|| fbi
->aa_walk_budget
== 0)
1163 ao_ref_init_from_ptr_and_size (&refd
, parm
, NULL_TREE
);
1164 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (call
), mark_modified
,
1165 &modified
, NULL
, NULL
,
1166 fbi
->aa_walk_budget
);
1169 fbi
->aa_walk_budget
= 0;
1173 fbi
->aa_walk_budget
-= walked
;
1175 paa
->pt_modified
= true;
1179 /* Return true if we can prove that OP is a memory reference loading
1180 data from an aggregate passed as a parameter.
1182 The function works in two modes. If GUARANTEED_UNMODIFIED is NULL, it return
1183 false if it cannot prove that the value has not been modified before the
1184 load in STMT. If GUARANTEED_UNMODIFIED is not NULL, it will return true even
1185 if it cannot prove the value has not been modified, in that case it will
1186 store false to *GUARANTEED_UNMODIFIED, otherwise it will store true there.
1188 INFO and PARMS_AINFO describe parameters of the current function (but the
1189 latter can be NULL), STMT is the load statement. If function returns true,
1190 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1191 within the aggregate and whether it is a load from a value passed by
1192 reference respectively.
1194 Return false if the offset divided by BITS_PER_UNIT would not fit into an
1198 ipa_load_from_parm_agg (struct ipa_func_body_info
*fbi
,
1199 vec
<ipa_param_descriptor
, va_gc
> *descriptors
,
1200 gimple
*stmt
, tree op
, int *index_p
,
1201 HOST_WIDE_INT
*offset_p
, poly_int64
*size_p
,
1202 bool *by_ref_p
, bool *guaranteed_unmodified
)
1207 tree base
= get_ref_base_and_extent_hwi (op
, offset_p
, &size
, &reverse
);
1210 || (*offset_p
/ BITS_PER_UNIT
) > UINT_MAX
)
1213 /* We can not propagate across volatile loads. */
1214 if (TREE_THIS_VOLATILE (op
))
1219 int index
= ipa_get_param_decl_index_1 (descriptors
, base
);
1221 && parm_preserved_before_stmt_p (fbi
, index
, stmt
, op
))
1227 if (guaranteed_unmodified
)
1228 *guaranteed_unmodified
= true;
1234 if (TREE_CODE (base
) != MEM_REF
1235 || TREE_CODE (TREE_OPERAND (base
, 0)) != SSA_NAME
1236 || !integer_zerop (TREE_OPERAND (base
, 1)))
1239 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base
, 0)))
1241 tree parm
= SSA_NAME_VAR (TREE_OPERAND (base
, 0));
1242 index
= ipa_get_param_decl_index_1 (descriptors
, parm
);
1246 /* This branch catches situations where a pointer parameter is not a
1247 gimple register, for example:
1249 void hip7(S*) (struct S * p)
1251 void (*<T2e4>) (struct S *) D.1867;
1256 D.1867_2 = p.1_1->f;
1261 gimple
*def
= SSA_NAME_DEF_STMT (TREE_OPERAND (base
, 0));
1262 index
= load_from_unmodified_param (fbi
, descriptors
, def
);
1267 bool data_preserved
= parm_ref_data_preserved_p (fbi
, index
, stmt
, op
);
1268 if (!data_preserved
&& !guaranteed_unmodified
)
1275 if (guaranteed_unmodified
)
1276 *guaranteed_unmodified
= data_preserved
;
1282 /* If STMT is an assignment that loads a value from a parameter declaration,
1283 or from an aggregate passed as the parameter either by value or reference,
1284 return the index of the parameter in ipa_node_params. Otherwise return -1.
1286 FBI holds gathered information about the function. INFO describes
1287 parameters of the function, STMT is the assignment statement. If it is a
1288 memory load from an aggregate, *OFFSET_P is filled with offset within the
1289 aggregate, and *BY_REF_P specifies whether the aggregate is passed by
1293 load_from_unmodified_param_or_agg (struct ipa_func_body_info
*fbi
,
1294 class ipa_node_params
*info
,
1296 HOST_WIDE_INT
*offset_p
,
1299 int index
= load_from_unmodified_param (fbi
, info
->descriptors
, stmt
);
1302 /* Load value from a parameter declaration. */
1309 if (!gimple_assign_load_p (stmt
))
1312 tree rhs
= gimple_assign_rhs1 (stmt
);
1314 /* Skip memory reference containing VIEW_CONVERT_EXPR. */
1315 for (tree t
= rhs
; handled_component_p (t
); t
= TREE_OPERAND (t
, 0))
1316 if (TREE_CODE (t
) == VIEW_CONVERT_EXPR
)
1319 /* Skip memory reference containing bit-field. */
1320 if (TREE_CODE (rhs
) == BIT_FIELD_REF
1321 || contains_bitfld_component_ref_p (rhs
))
1324 if (!ipa_load_from_parm_agg (fbi
, info
->descriptors
, stmt
, rhs
, &index
,
1325 offset_p
, &size
, by_ref_p
))
1328 gcc_assert (!maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (rhs
))),
1332 tree param_type
= ipa_get_type (info
, index
);
1334 if (!param_type
|| !AGGREGATE_TYPE_P (param_type
))
1337 else if (TREE_THIS_VOLATILE (rhs
))
1343 /* Walk pointer adjustemnts from OP (such as POINTER_PLUS and ADDR_EXPR)
1344 to find original pointer. Initialize RET to the pointer which results from
1346 If offset is known return true and initialize OFFSET_RET. */
1349 unadjusted_ptr_and_unit_offset (tree op
, tree
*ret
, poly_int64
*offset_ret
)
1351 poly_int64 offset
= 0;
1352 bool offset_known
= true;
1355 for (i
= 0; i
< param_ipa_jump_function_lookups
; i
++)
1357 if (TREE_CODE (op
) == ADDR_EXPR
)
1359 poly_int64 extra_offset
= 0;
1360 tree base
= get_addr_base_and_unit_offset (TREE_OPERAND (op
, 0),
1364 base
= get_base_address (TREE_OPERAND (op
, 0));
1365 if (TREE_CODE (base
) != MEM_REF
)
1367 offset_known
= false;
1371 if (TREE_CODE (base
) != MEM_REF
)
1373 offset
+= extra_offset
;
1375 op
= TREE_OPERAND (base
, 0);
1376 if (mem_ref_offset (base
).to_shwi (&extra_offset
))
1377 offset
+= extra_offset
;
1379 offset_known
= false;
1381 else if (TREE_CODE (op
) == SSA_NAME
1382 && !SSA_NAME_IS_DEFAULT_DEF (op
))
1384 gimple
*pstmt
= SSA_NAME_DEF_STMT (op
);
1386 if (gimple_assign_single_p (pstmt
))
1387 op
= gimple_assign_rhs1 (pstmt
);
1388 else if (is_gimple_assign (pstmt
)
1389 && gimple_assign_rhs_code (pstmt
) == POINTER_PLUS_EXPR
)
1391 poly_int64 extra_offset
= 0;
1392 if (ptrdiff_tree_p (gimple_assign_rhs2 (pstmt
),
1394 offset
+= extra_offset
;
1396 offset_known
= false;
1397 op
= gimple_assign_rhs1 (pstmt
);
1406 *offset_ret
= offset
;
1407 return offset_known
;
1410 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1411 of an assignment statement STMT, try to determine whether we are actually
1412 handling any of the following cases and construct an appropriate jump
1413 function into JFUNC if so:
1415 1) The passed value is loaded from a formal parameter which is not a gimple
1416 register (most probably because it is addressable, the value has to be
1417 scalar) and we can guarantee the value has not changed. This case can
1418 therefore be described by a simple pass-through jump function. For example:
1427 2) The passed value can be described by a simple arithmetic pass-through
1434 D.2064_4 = a.1(D) + 4;
1437 This case can also occur in combination of the previous one, e.g.:
1445 D.2064_4 = a.0_3 + 4;
1448 3) The passed value is an address of an object within another one (which
1449 also passed by reference). Such situations are described by an ancestor
1450 jump function and describe situations such as:
1452 B::foo() (struct B * const this)
1456 D.1845_2 = &this_1(D)->D.1748;
1459 INFO is the structure describing individual parameters access different
1460 stages of IPA optimizations. PARMS_AINFO contains the information that is
1461 only needed for intraprocedural analysis. */
1464 compute_complex_assign_jump_func (struct ipa_func_body_info
*fbi
,
1465 class ipa_node_params
*info
,
1466 struct ipa_jump_func
*jfunc
,
1467 gcall
*call
, gimple
*stmt
, tree name
,
1470 HOST_WIDE_INT offset
, size
;
1471 tree op1
, tc_ssa
, base
, ssa
;
1475 op1
= gimple_assign_rhs1 (stmt
);
1477 if (TREE_CODE (op1
) == SSA_NAME
)
1479 if (SSA_NAME_IS_DEFAULT_DEF (op1
))
1480 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (op1
));
1482 index
= load_from_unmodified_param (fbi
, info
->descriptors
,
1483 SSA_NAME_DEF_STMT (op1
));
1488 index
= load_from_unmodified_param (fbi
, info
->descriptors
, stmt
);
1489 tc_ssa
= gimple_assign_lhs (stmt
);
1494 switch (gimple_assign_rhs_class (stmt
))
1496 case GIMPLE_BINARY_RHS
:
1498 tree op2
= gimple_assign_rhs2 (stmt
);
1499 if (!is_gimple_ip_invariant (op2
)
1500 || ((TREE_CODE_CLASS (gimple_assign_rhs_code (stmt
))
1502 && !useless_type_conversion_p (TREE_TYPE (name
),
1506 ipa_set_jf_arith_pass_through (jfunc
, index
, op2
,
1507 gimple_assign_rhs_code (stmt
));
1510 case GIMPLE_SINGLE_RHS
:
1512 bool agg_p
= parm_ref_data_pass_through_p (fbi
, index
, call
,
1514 ipa_set_jf_simple_pass_through (jfunc
, index
, agg_p
);
1517 case GIMPLE_UNARY_RHS
:
1518 if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt
)))
1519 ipa_set_jf_unary_pass_through (jfunc
, index
,
1520 gimple_assign_rhs_code (stmt
));
1526 if (TREE_CODE (op1
) != ADDR_EXPR
)
1528 op1
= TREE_OPERAND (op1
, 0);
1529 base
= get_ref_base_and_extent_hwi (op1
, &offset
, &size
, &reverse
);
1530 offset_int mem_offset
;
1532 || TREE_CODE (base
) != MEM_REF
1533 || !mem_ref_offset (base
).is_constant (&mem_offset
))
1535 offset
+= mem_offset
.to_short_addr () * BITS_PER_UNIT
;
1536 ssa
= TREE_OPERAND (base
, 0);
1537 if (TREE_CODE (ssa
) != SSA_NAME
1538 || !SSA_NAME_IS_DEFAULT_DEF (ssa
)
1542 /* Dynamic types are changed in constructors and destructors. */
1543 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (ssa
));
1544 if (index
>= 0 && param_type
&& POINTER_TYPE_P (param_type
))
1545 ipa_set_ancestor_jf (jfunc
, offset
, index
,
1546 parm_ref_data_pass_through_p (fbi
, index
, call
, ssa
),
1550 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1553 iftmp.1_3 = &obj_2(D)->D.1762;
1555 The base of the MEM_REF must be a default definition SSA NAME of a
1556 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1557 whole MEM_REF expression is returned and the offset calculated from any
1558 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1559 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1562 get_ancestor_addr_info (gimple
*assign
, tree
*obj_p
, HOST_WIDE_INT
*offset
)
1565 tree expr
, parm
, obj
;
1568 if (!gimple_assign_single_p (assign
))
1570 expr
= gimple_assign_rhs1 (assign
);
1572 if (TREE_CODE (expr
) != ADDR_EXPR
)
1574 expr
= TREE_OPERAND (expr
, 0);
1576 expr
= get_ref_base_and_extent_hwi (expr
, offset
, &size
, &reverse
);
1578 offset_int mem_offset
;
1580 || TREE_CODE (expr
) != MEM_REF
1581 || !mem_ref_offset (expr
).is_constant (&mem_offset
))
1583 parm
= TREE_OPERAND (expr
, 0);
1584 if (TREE_CODE (parm
) != SSA_NAME
1585 || !SSA_NAME_IS_DEFAULT_DEF (parm
)
1586 || TREE_CODE (SSA_NAME_VAR (parm
)) != PARM_DECL
)
1589 *offset
+= mem_offset
.to_short_addr () * BITS_PER_UNIT
;
1595 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1596 statement PHI, try to find out whether NAME is in fact a
1597 multiple-inheritance typecast from a descendant into an ancestor of a formal
1598 parameter and thus can be described by an ancestor jump function and if so,
1599 write the appropriate function into JFUNC.
1601 Essentially we want to match the following pattern:
1609 iftmp.1_3 = &obj_2(D)->D.1762;
1612 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1613 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1617 compute_complex_ancestor_jump_func (struct ipa_func_body_info
*fbi
,
1618 class ipa_node_params
*info
,
1619 struct ipa_jump_func
*jfunc
,
1620 gcall
*call
, gphi
*phi
)
1622 HOST_WIDE_INT offset
;
1624 basic_block phi_bb
, assign_bb
, cond_bb
;
1625 tree tmp
, parm
, expr
, obj
;
1628 if (gimple_phi_num_args (phi
) != 2)
1631 if (integer_zerop (PHI_ARG_DEF (phi
, 1)))
1632 tmp
= PHI_ARG_DEF (phi
, 0);
1633 else if (integer_zerop (PHI_ARG_DEF (phi
, 0)))
1634 tmp
= PHI_ARG_DEF (phi
, 1);
1637 if (TREE_CODE (tmp
) != SSA_NAME
1638 || SSA_NAME_IS_DEFAULT_DEF (tmp
)
1639 || !POINTER_TYPE_P (TREE_TYPE (tmp
))
1640 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp
))) != RECORD_TYPE
)
1643 assign
= SSA_NAME_DEF_STMT (tmp
);
1644 assign_bb
= gimple_bb (assign
);
1645 if (!single_pred_p (assign_bb
))
1647 expr
= get_ancestor_addr_info (assign
, &obj
, &offset
);
1650 parm
= TREE_OPERAND (expr
, 0);
1651 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (parm
));
1655 cond_bb
= single_pred (assign_bb
);
1656 gcond
*cond
= safe_dyn_cast
<gcond
*> (*gsi_last_bb (cond_bb
));
1658 || gimple_cond_code (cond
) != NE_EXPR
1659 || gimple_cond_lhs (cond
) != parm
1660 || !integer_zerop (gimple_cond_rhs (cond
)))
1663 phi_bb
= gimple_bb (phi
);
1664 for (i
= 0; i
< 2; i
++)
1666 basic_block pred
= EDGE_PRED (phi_bb
, i
)->src
;
1667 if (pred
!= assign_bb
&& pred
!= cond_bb
)
1671 ipa_set_ancestor_jf (jfunc
, offset
, index
,
1672 parm_ref_data_pass_through_p (fbi
, index
, call
, parm
),
1676 /* Inspect the given TYPE and return true iff it has the same structure (the
1677 same number of fields of the same types) as a C++ member pointer. If
1678 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1679 corresponding fields there. */
1682 type_like_member_ptr_p (tree type
, tree
*method_ptr
, tree
*delta
)
1686 if (TREE_CODE (type
) != RECORD_TYPE
)
1689 fld
= TYPE_FIELDS (type
);
1690 if (!fld
|| !POINTER_TYPE_P (TREE_TYPE (fld
))
1691 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld
))) != METHOD_TYPE
1692 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
1698 fld
= DECL_CHAIN (fld
);
1699 if (!fld
|| INTEGRAL_TYPE_P (fld
)
1700 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
1705 if (DECL_CHAIN (fld
))
1711 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1712 return the rhs of its defining statement, and this statement is stored in
1713 *RHS_STMT. Otherwise return RHS as it is. */
1716 get_ssa_def_if_simple_copy (tree rhs
, gimple
**rhs_stmt
)
1718 while (TREE_CODE (rhs
) == SSA_NAME
&& !SSA_NAME_IS_DEFAULT_DEF (rhs
))
1720 gimple
*def_stmt
= SSA_NAME_DEF_STMT (rhs
);
1722 if (gimple_assign_single_p (def_stmt
))
1723 rhs
= gimple_assign_rhs1 (def_stmt
);
1726 *rhs_stmt
= def_stmt
;
1731 /* Simple linked list, describing contents of an aggregate before call. */
1733 struct ipa_known_agg_contents_list
1735 /* Offset and size of the described part of the aggregate. */
1736 HOST_WIDE_INT offset
, size
;
1738 /* Type of the described part of the aggregate. */
1741 /* Known constant value or jump function data describing contents. */
1742 struct ipa_load_agg_data value
;
1744 /* Pointer to the next structure in the list. */
1745 struct ipa_known_agg_contents_list
*next
;
1748 /* Add an aggregate content item into a linked list of
1749 ipa_known_agg_contents_list structure, in which all elements
1750 are sorted ascendingly by offset. */
1753 add_to_agg_contents_list (struct ipa_known_agg_contents_list
**plist
,
1754 struct ipa_known_agg_contents_list
*item
)
1756 struct ipa_known_agg_contents_list
*list
= *plist
;
1758 for (; list
; list
= list
->next
)
1760 if (list
->offset
>= item
->offset
)
1763 plist
= &list
->next
;
1770 /* Check whether a given aggregate content is clobbered by certain element in
1771 a linked list of ipa_known_agg_contents_list. */
1774 clobber_by_agg_contents_list_p (struct ipa_known_agg_contents_list
*list
,
1775 struct ipa_known_agg_contents_list
*item
)
1777 for (; list
; list
= list
->next
)
1779 if (list
->offset
>= item
->offset
)
1780 return list
->offset
< item
->offset
+ item
->size
;
1782 if (list
->offset
+ list
->size
> item
->offset
)
1789 /* Build aggregate jump function from LIST, assuming there are exactly
1790 VALUE_COUNT entries there and that offset of the passed argument
1791 is ARG_OFFSET and store it into JFUNC. */
1794 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list
*list
,
1795 int value_count
, HOST_WIDE_INT arg_offset
,
1796 struct ipa_jump_func
*jfunc
)
1798 vec_safe_reserve (jfunc
->agg
.items
, value_count
, true);
1799 for (; list
; list
= list
->next
)
1801 struct ipa_agg_jf_item item
;
1802 tree operand
= list
->value
.pass_through
.operand
;
1804 if (list
->value
.pass_through
.formal_id
>= 0)
1806 /* Content value is derived from some formal paramerter. */
1807 if (list
->value
.offset
>= 0)
1808 item
.jftype
= IPA_JF_LOAD_AGG
;
1810 item
.jftype
= IPA_JF_PASS_THROUGH
;
1812 item
.value
.load_agg
= list
->value
;
1814 item
.value
.pass_through
.operand
1815 = unshare_expr_without_location (operand
);
1819 /* Content value is known constant. */
1820 item
.jftype
= IPA_JF_CONST
;
1821 item
.value
.constant
= unshare_expr_without_location (operand
);
1826 item
.type
= list
->type
;
1827 gcc_assert (tree_to_shwi (TYPE_SIZE (list
->type
)) == list
->size
);
1829 item
.offset
= list
->offset
- arg_offset
;
1830 gcc_assert ((item
.offset
% BITS_PER_UNIT
) == 0);
1832 jfunc
->agg
.items
->quick_push (item
);
1836 /* Given an assignment statement STMT, try to collect information into
1837 AGG_VALUE that will be used to construct jump function for RHS of the
1838 assignment, from which content value of an aggregate part comes.
1840 Besides constant and simple pass-through jump functions, also try to
1841 identify whether it matches the following pattern that can be described by
1842 a load-value-from-aggregate jump function, which is a derivative of simple
1843 pass-through jump function.
1849 *(q_5 + 4) = *(p_3(D) + 28) op 1;
1853 Here IPA_LOAD_AGG_DATA data structure is informative enough to describe
1854 constant, simple pass-through and load-vale-from-aggregate. If value
1855 is constant, it will be kept in field OPERAND, and field FORMAL_ID is
1856 set to -1. For simple pass-through and load-value-from-aggregate, field
1857 FORMAL_ID specifies the related formal parameter index, and field
1858 OFFSET can be used to distinguish them, -1 means simple pass-through,
1859 otherwise means load-value-from-aggregate. */
1862 analyze_agg_content_value (struct ipa_func_body_info
*fbi
,
1863 struct ipa_load_agg_data
*agg_value
,
1866 tree lhs
= gimple_assign_lhs (stmt
);
1867 tree rhs1
= gimple_assign_rhs1 (stmt
);
1868 enum tree_code code
;
1871 /* Initialize jump function data for the aggregate part. */
1872 memset (agg_value
, 0, sizeof (*agg_value
));
1873 agg_value
->pass_through
.operation
= NOP_EXPR
;
1874 agg_value
->pass_through
.formal_id
= -1;
1875 agg_value
->offset
= -1;
1877 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs
)) /* TODO: Support aggregate type. */
1878 || TREE_THIS_VOLATILE (lhs
)
1879 || TREE_CODE (lhs
) == BIT_FIELD_REF
1880 || contains_bitfld_component_ref_p (lhs
))
1883 /* Skip SSA copies. */
1884 while (gimple_assign_rhs_class (stmt
) == GIMPLE_SINGLE_RHS
)
1886 if (TREE_CODE (rhs1
) != SSA_NAME
|| SSA_NAME_IS_DEFAULT_DEF (rhs1
))
1889 stmt
= SSA_NAME_DEF_STMT (rhs1
);
1890 if (!is_gimple_assign (stmt
))
1893 rhs1
= gimple_assign_rhs1 (stmt
);
1896 if (gphi
*phi
= dyn_cast
<gphi
*> (stmt
))
1898 /* Also special case like the following (a is a formal parameter):
1900 _12 = *a_11(D).dim[0].stride;
1902 # iftmp.22_9 = PHI <_12(2), 1(3)>
1904 parm.6.dim[0].stride = iftmp.22_9;
1906 __x_MOD_foo (&parm.6, b_31(D));
1908 The aggregate function describing parm.6.dim[0].stride is encoded as a
1909 PASS-THROUGH jump function with ASSERT_EXPR operation whith operand 1
1910 (the constant from the PHI node). */
1912 if (gimple_phi_num_args (phi
) != 2)
1914 tree arg0
= gimple_phi_arg_def (phi
, 0);
1915 tree arg1
= gimple_phi_arg_def (phi
, 1);
1918 if (is_gimple_ip_invariant (arg1
))
1923 else if (is_gimple_ip_invariant (arg0
))
1931 rhs1
= get_ssa_def_if_simple_copy (rhs1
, &stmt
);
1932 if (!is_gimple_assign (stmt
))
1936 agg_value
->pass_through
.operand
= operand
;
1938 else if (is_gimple_assign (stmt
))
1940 code
= gimple_assign_rhs_code (stmt
);
1941 switch (gimple_assign_rhs_class (stmt
))
1943 case GIMPLE_SINGLE_RHS
:
1944 if (is_gimple_ip_invariant (rhs1
))
1946 agg_value
->pass_through
.operand
= rhs1
;
1952 case GIMPLE_UNARY_RHS
:
1953 /* NOTE: A GIMPLE_UNARY_RHS operation might not be tcc_unary
1954 (truth_not_expr is example), GIMPLE_BINARY_RHS does not imply
1955 tcc_binary, this subtleness is somewhat misleading.
1957 Since tcc_unary is widely used in IPA-CP code to check an operation
1958 with one operand, here we only allow tc_unary operation to avoid
1959 possible problem. Then we can use (opclass == tc_unary) or not to
1960 distinguish unary and binary. */
1961 if (TREE_CODE_CLASS (code
) != tcc_unary
|| CONVERT_EXPR_CODE_P (code
))
1964 rhs1
= get_ssa_def_if_simple_copy (rhs1
, &stmt
);
1967 case GIMPLE_BINARY_RHS
:
1969 gimple
*rhs1_stmt
= stmt
;
1970 gimple
*rhs2_stmt
= stmt
;
1971 tree rhs2
= gimple_assign_rhs2 (stmt
);
1973 rhs1
= get_ssa_def_if_simple_copy (rhs1
, &rhs1_stmt
);
1974 rhs2
= get_ssa_def_if_simple_copy (rhs2
, &rhs2_stmt
);
1976 if (is_gimple_ip_invariant (rhs2
))
1978 agg_value
->pass_through
.operand
= rhs2
;
1981 else if (is_gimple_ip_invariant (rhs1
))
1983 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
1984 code
= swap_tree_comparison (code
);
1985 else if (!commutative_tree_code (code
))
1988 agg_value
->pass_through
.operand
= rhs1
;
1995 if (TREE_CODE_CLASS (code
) != tcc_comparison
1996 && !useless_type_conversion_p (TREE_TYPE (lhs
),
2009 if (TREE_CODE (rhs1
) != SSA_NAME
)
2010 index
= load_from_unmodified_param_or_agg (fbi
, fbi
->info
, stmt
,
2012 &agg_value
->by_ref
);
2013 else if (SSA_NAME_IS_DEFAULT_DEF (rhs1
))
2014 index
= ipa_get_param_decl_index (fbi
->info
, SSA_NAME_VAR (rhs1
));
2018 if (agg_value
->offset
>= 0)
2019 agg_value
->type
= TREE_TYPE (rhs1
);
2020 agg_value
->pass_through
.formal_id
= index
;
2021 agg_value
->pass_through
.operation
= code
;
2024 agg_value
->pass_through
.operand
= NULL_TREE
;
2027 /* If STMT is a memory store to the object whose address is BASE, extract
2028 information (offset, size, and value) into CONTENT, and return true,
2029 otherwise we conservatively assume the whole object is modified with
2030 unknown content, and return false. CHECK_REF means that access to object
2031 is expected to be in form of MEM_REF expression. */
2034 extract_mem_content (struct ipa_func_body_info
*fbi
,
2035 gimple
*stmt
, tree base
, bool check_ref
,
2036 struct ipa_known_agg_contents_list
*content
)
2038 HOST_WIDE_INT lhs_offset
, lhs_size
;
2041 if (!is_gimple_assign (stmt
))
2044 tree lhs
= gimple_assign_lhs (stmt
);
2045 tree lhs_base
= get_ref_base_and_extent_hwi (lhs
, &lhs_offset
, &lhs_size
,
2052 if (TREE_CODE (lhs_base
) != MEM_REF
2053 || TREE_OPERAND (lhs_base
, 0) != base
2054 || !integer_zerop (TREE_OPERAND (lhs_base
, 1)))
2057 else if (lhs_base
!= base
)
2060 content
->offset
= lhs_offset
;
2061 content
->size
= lhs_size
;
2062 content
->type
= TREE_TYPE (lhs
);
2063 content
->next
= NULL
;
2065 analyze_agg_content_value (fbi
, &content
->value
, stmt
);
2069 /* Traverse statements from CALL backwards, scanning whether an aggregate given
2070 in ARG is filled in constants or values that are derived from caller's
2071 formal parameter in the way described by some kinds of jump functions. FBI
2072 is the context of the caller function for interprocedural analysis. ARG can
2073 either be an aggregate expression or a pointer to an aggregate. ARG_TYPE is
2074 the type of the aggregate, JFUNC is the jump function for the aggregate. */
2077 determine_known_aggregate_parts (struct ipa_func_body_info
*fbi
,
2078 gcall
*call
, tree arg
,
2080 struct ipa_jump_func
*jfunc
)
2082 struct ipa_known_agg_contents_list
*list
= NULL
, *all_list
= NULL
;
2083 bitmap visited
= NULL
;
2084 int item_count
= 0, value_count
= 0;
2085 HOST_WIDE_INT arg_offset
, arg_size
;
2087 bool check_ref
, by_ref
;
2089 int max_agg_items
= opt_for_fn (fbi
->node
->decl
, param_ipa_max_agg_items
);
2091 if (max_agg_items
== 0)
2094 /* The function operates in three stages. First, we prepare check_ref, r,
2095 arg_base and arg_offset based on what is actually passed as an actual
2098 if (POINTER_TYPE_P (arg_type
))
2101 if (TREE_CODE (arg
) == SSA_NAME
)
2104 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type
)))
2105 || !POINTER_TYPE_P (TREE_TYPE (arg
)))
2110 type_size
= TYPE_SIZE (TREE_TYPE (arg_type
));
2111 arg_size
= tree_to_uhwi (type_size
);
2112 ao_ref_init_from_ptr_and_size (&r
, arg_base
, NULL_TREE
);
2114 else if (TREE_CODE (arg
) == ADDR_EXPR
)
2118 arg
= TREE_OPERAND (arg
, 0);
2119 arg_base
= get_ref_base_and_extent_hwi (arg
, &arg_offset
,
2120 &arg_size
, &reverse
);
2123 if (DECL_P (arg_base
))
2126 ao_ref_init (&r
, arg_base
);
2138 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg
)));
2142 arg_base
= get_ref_base_and_extent_hwi (arg
, &arg_offset
,
2143 &arg_size
, &reverse
);
2147 ao_ref_init (&r
, arg
);
2150 /* Second stage traverses virtual SSA web backwards starting from the call
2151 statement, only looks at individual dominating virtual operand (its
2152 definition dominates the call), as long as it is confident that content
2153 of the aggregate is affected by definition of the virtual operand, it
2154 builds a sorted linked list of ipa_agg_jf_list describing that. */
2156 for (tree dom_vuse
= gimple_vuse (call
);
2157 dom_vuse
&& fbi
->aa_walk_budget
> 0;)
2159 gimple
*stmt
= SSA_NAME_DEF_STMT (dom_vuse
);
2161 if (gimple_code (stmt
) == GIMPLE_PHI
)
2163 dom_vuse
= get_continuation_for_phi (stmt
, &r
, true,
2164 fbi
->aa_walk_budget
,
2165 &visited
, false, NULL
, NULL
);
2169 fbi
->aa_walk_budget
--;
2170 if (stmt_may_clobber_ref_p_1 (stmt
, &r
))
2172 struct ipa_known_agg_contents_list
*content
2173 = XALLOCA (struct ipa_known_agg_contents_list
);
2175 if (!extract_mem_content (fbi
, stmt
, arg_base
, check_ref
, content
))
2178 /* Now we get a dominating virtual operand, and need to check
2179 whether its value is clobbered any other dominating one. */
2180 if ((content
->value
.pass_through
.formal_id
>= 0
2181 || content
->value
.pass_through
.operand
)
2182 && !clobber_by_agg_contents_list_p (all_list
, content
)
2183 /* Since IPA-CP stores results with unsigned int offsets, we can
2184 discard those which would not fit now before we stream them to
2186 && (content
->offset
+ content
->size
- arg_offset
2187 <= (HOST_WIDE_INT
) UINT_MAX
* BITS_PER_UNIT
))
2189 struct ipa_known_agg_contents_list
*copy
2190 = XALLOCA (struct ipa_known_agg_contents_list
);
2192 /* Add to the list consisting of only dominating virtual
2193 operands, whose definitions can finally reach the call. */
2194 add_to_agg_contents_list (&list
, (*copy
= *content
, copy
));
2196 if (++value_count
== max_agg_items
)
2200 /* Add to the list consisting of all dominating virtual operands. */
2201 add_to_agg_contents_list (&all_list
, content
);
2203 if (++item_count
== 2 * max_agg_items
)
2206 dom_vuse
= gimple_vuse (stmt
);
2210 BITMAP_FREE (visited
);
2212 /* Third stage just goes over the list and creates an appropriate vector of
2213 ipa_agg_jf_item structures out of it, of course only if there are
2214 any meaningful items to begin with. */
2218 jfunc
->agg
.by_ref
= by_ref
;
2219 build_agg_jump_func_from_list (list
, value_count
, arg_offset
, jfunc
);
2224 /* Return the Ith param type of callee associated with call graph
2228 ipa_get_callee_param_type (struct cgraph_edge
*e
, int i
)
2231 tree type
= (e
->callee
2232 ? TREE_TYPE (e
->callee
->decl
)
2233 : gimple_call_fntype (e
->call_stmt
));
2234 tree t
= TYPE_ARG_TYPES (type
);
2236 for (n
= 0; n
< i
; n
++)
2242 if (t
&& t
!= void_list_node
)
2243 return TREE_VALUE (t
);
2246 t
= DECL_ARGUMENTS (e
->callee
->decl
);
2247 for (n
= 0; n
< i
; n
++)
2254 return TREE_TYPE (t
);
2258 /* Return a pointer to an ipa_vr just like TMP, but either find it in
2259 ipa_vr_hash_table or allocate it in GC memory. */
2262 ipa_get_value_range (const vrange
&tmp
)
2264 inchash::hash hstate
;
2265 inchash::add_vrange (tmp
, hstate
);
2266 hashval_t hash
= hstate
.end ();
2267 ipa_vr
**slot
= ipa_vr_hash_table
->find_slot_with_hash (&tmp
, hash
, INSERT
);
2271 ipa_vr
*vr
= new (ggc_alloc
<ipa_vr
> ()) ipa_vr (tmp
);
2276 /* Assign to JF a pointer to a range just like TMP but either fetch a
2277 copy from ipa_vr_hash_table or allocate a new on in GC memory. */
2280 ipa_set_jfunc_vr (ipa_jump_func
*jf
, const vrange
&tmp
)
2282 jf
->m_vr
= ipa_get_value_range (tmp
);
2286 ipa_set_jfunc_vr (ipa_jump_func
*jf
, const ipa_vr
&vr
)
2289 vr
.get_vrange (tmp
);
2290 ipa_set_jfunc_vr (jf
, tmp
);
2293 /* Compute jump function for all arguments of callsite CS and insert the
2294 information in the jump_functions array in the ipa_edge_args corresponding
2295 to this callsite. */
2298 ipa_compute_jump_functions_for_edge (struct ipa_func_body_info
*fbi
,
2299 struct cgraph_edge
*cs
)
2301 ipa_node_params
*info
= ipa_node_params_sum
->get (cs
->caller
);
2302 ipa_edge_args
*args
= ipa_edge_args_sum
->get_create (cs
);
2303 gcall
*call
= cs
->call_stmt
;
2304 int n
, arg_num
= gimple_call_num_args (call
);
2305 bool useful_context
= false;
2307 if (arg_num
== 0 || args
->jump_functions
)
2309 vec_safe_grow_cleared (args
->jump_functions
, arg_num
, true);
2310 if (flag_devirtualize
)
2311 vec_safe_grow_cleared (args
->polymorphic_call_contexts
, arg_num
, true);
2313 if (gimple_call_internal_p (call
))
2315 if (ipa_func_spec_opts_forbid_analysis_p (cs
->caller
))
2318 for (n
= 0; n
< arg_num
; n
++)
2320 struct ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (args
, n
);
2321 tree arg
= gimple_call_arg (call
, n
);
2322 tree param_type
= ipa_get_callee_param_type (cs
, n
);
2323 if (flag_devirtualize
&& POINTER_TYPE_P (TREE_TYPE (arg
)))
2326 class ipa_polymorphic_call_context
context (cs
->caller
->decl
,
2329 context
.get_dynamic_type (instance
, arg
, NULL
, cs
->call_stmt
,
2330 &fbi
->aa_walk_budget
);
2331 *ipa_get_ith_polymorhic_call_context (args
, n
) = context
;
2332 if (!context
.useless_p ())
2333 useful_context
= true;
2336 Value_Range
vr (TREE_TYPE (arg
));
2337 if (POINTER_TYPE_P (TREE_TYPE (arg
)))
2339 bool addr_nonzero
= false;
2340 bool strict_overflow
= false;
2342 if (TREE_CODE (arg
) == SSA_NAME
2344 && get_range_query (cfun
)->range_of_expr (vr
, arg
, cs
->call_stmt
)
2346 addr_nonzero
= true;
2347 else if (tree_single_nonzero_warnv_p (arg
, &strict_overflow
))
2348 addr_nonzero
= true;
2351 vr
.set_nonzero (TREE_TYPE (arg
));
2353 unsigned HOST_WIDE_INT bitpos
;
2354 unsigned align
, prec
= TYPE_PRECISION (TREE_TYPE (arg
));
2356 get_pointer_alignment_1 (arg
, &align
, &bitpos
);
2358 if (align
> BITS_PER_UNIT
2359 && opt_for_fn (cs
->caller
->decl
, flag_ipa_bit_cp
))
2362 = wi::bit_and_not (wi::mask (prec
, false, prec
),
2363 wide_int::from (align
/ BITS_PER_UNIT
- 1,
2365 wide_int value
= wide_int::from (bitpos
/ BITS_PER_UNIT
, prec
,
2367 irange_bitmask
bm (value
, mask
);
2369 vr
.set_varying (TREE_TYPE (arg
));
2370 irange
&r
= as_a
<irange
> (vr
);
2371 r
.update_bitmask (bm
);
2372 ipa_set_jfunc_vr (jfunc
, vr
);
2374 else if (addr_nonzero
)
2375 ipa_set_jfunc_vr (jfunc
, vr
);
2377 gcc_assert (!jfunc
->m_vr
);
2382 && Value_Range::supports_type_p (TREE_TYPE (arg
))
2383 && Value_Range::supports_type_p (param_type
)
2384 && irange::supports_p (TREE_TYPE (arg
))
2385 && irange::supports_p (param_type
)
2386 && get_range_query (cfun
)->range_of_expr (vr
, arg
, cs
->call_stmt
)
2387 && !vr
.undefined_p ())
2389 Value_Range
resvr (vr
);
2390 range_cast (resvr
, param_type
);
2391 if (!resvr
.undefined_p () && !resvr
.varying_p ())
2392 ipa_set_jfunc_vr (jfunc
, resvr
);
2394 gcc_assert (!jfunc
->m_vr
);
2397 gcc_assert (!jfunc
->m_vr
);
2400 if (is_gimple_ip_invariant (arg
)
2402 && is_global_var (arg
)
2403 && TREE_READONLY (arg
)))
2404 ipa_set_jf_constant (jfunc
, arg
, cs
);
2405 else if (!is_gimple_reg_type (TREE_TYPE (arg
))
2406 && TREE_CODE (arg
) == PARM_DECL
)
2408 int index
= ipa_get_param_decl_index (info
, arg
);
2410 gcc_assert (index
>=0);
2411 /* Aggregate passed by value, check for pass-through, otherwise we
2412 will attempt to fill in aggregate contents later in this
2414 if (parm_preserved_before_stmt_p (fbi
, index
, call
, arg
))
2416 ipa_set_jf_simple_pass_through (jfunc
, index
, false);
2420 else if (TREE_CODE (arg
) == SSA_NAME
)
2422 if (SSA_NAME_IS_DEFAULT_DEF (arg
))
2424 int index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (arg
));
2428 agg_p
= parm_ref_data_pass_through_p (fbi
, index
, call
, arg
);
2429 ipa_set_jf_simple_pass_through (jfunc
, index
, agg_p
);
2434 gimple
*stmt
= SSA_NAME_DEF_STMT (arg
);
2435 if (is_gimple_assign (stmt
))
2436 compute_complex_assign_jump_func (fbi
, info
, jfunc
,
2437 call
, stmt
, arg
, param_type
);
2438 else if (gimple_code (stmt
) == GIMPLE_PHI
)
2439 compute_complex_ancestor_jump_func (fbi
, info
, jfunc
,
2441 as_a
<gphi
*> (stmt
));
2445 /* If ARG is pointer, we cannot use its type to determine the type of aggregate
2446 passed (because type conversions are ignored in gimple). Usually we can
2447 safely get type from function declaration, but in case of K&R prototypes or
2448 variadic functions we can try our luck with type of the pointer passed.
2449 TODO: Since we look for actual initialization of the memory object, we may better
2450 work out the type based on the memory stores we find. */
2452 param_type
= TREE_TYPE (arg
);
2454 if ((jfunc
->type
!= IPA_JF_PASS_THROUGH
2455 || !ipa_get_jf_pass_through_agg_preserved (jfunc
))
2456 && (jfunc
->type
!= IPA_JF_ANCESTOR
2457 || !ipa_get_jf_ancestor_agg_preserved (jfunc
))
2458 && (AGGREGATE_TYPE_P (TREE_TYPE (arg
))
2459 || POINTER_TYPE_P (param_type
)))
2460 determine_known_aggregate_parts (fbi
, call
, arg
, param_type
, jfunc
);
2462 if (!useful_context
)
2463 vec_free (args
->polymorphic_call_contexts
);
2466 /* Compute jump functions for all edges - both direct and indirect - outgoing
2470 ipa_compute_jump_functions_for_bb (struct ipa_func_body_info
*fbi
, basic_block bb
)
2472 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
2474 struct cgraph_edge
*cs
;
2476 FOR_EACH_VEC_ELT_REVERSE (bi
->cg_edges
, i
, cs
)
2478 struct cgraph_node
*callee
= cs
->callee
;
2482 callee
= callee
->ultimate_alias_target ();
2483 /* We do not need to bother analyzing calls to unknown functions
2484 unless they may become known during lto/whopr. */
2485 if (!callee
->definition
&& !flag_lto
2486 && !gimple_call_fnspec (cs
->call_stmt
).known_p ())
2489 ipa_compute_jump_functions_for_edge (fbi
, cs
);
2493 /* If STMT looks like a statement loading a value from a member pointer formal
2494 parameter, return that parameter and store the offset of the field to
2495 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
2496 might be clobbered). If USE_DELTA, then we look for a use of the delta
2497 field rather than the pfn. */
2500 ipa_get_stmt_member_ptr_load_param (gimple
*stmt
, bool use_delta
,
2501 HOST_WIDE_INT
*offset_p
)
2503 tree rhs
, fld
, ptr_field
, delta_field
;
2504 tree ref_field
= NULL_TREE
;
2505 tree ref_offset
= NULL_TREE
;
2507 if (!gimple_assign_single_p (stmt
))
2510 rhs
= gimple_assign_rhs1 (stmt
);
2511 if (TREE_CODE (rhs
) == COMPONENT_REF
)
2513 ref_field
= TREE_OPERAND (rhs
, 1);
2514 rhs
= TREE_OPERAND (rhs
, 0);
2517 if (TREE_CODE (rhs
) == MEM_REF
)
2519 ref_offset
= TREE_OPERAND (rhs
, 1);
2520 if (ref_field
&& integer_nonzerop (ref_offset
))
2523 else if (!ref_field
)
2526 if (TREE_CODE (rhs
) == MEM_REF
2527 && TREE_CODE (TREE_OPERAND (rhs
, 0)) == SSA_NAME
2528 && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (rhs
, 0)))
2530 rhs
= TREE_OPERAND (rhs
, 0);
2531 if (TREE_CODE (SSA_NAME_VAR (rhs
)) != PARM_DECL
2532 || !type_like_member_ptr_p (TREE_TYPE (TREE_TYPE (rhs
)), &ptr_field
,
2538 if (TREE_CODE (rhs
) == MEM_REF
2539 && TREE_CODE (TREE_OPERAND (rhs
, 0)) == ADDR_EXPR
)
2540 rhs
= TREE_OPERAND (TREE_OPERAND (rhs
, 0), 0);
2541 if (TREE_CODE (rhs
) != PARM_DECL
2542 || !type_like_member_ptr_p (TREE_TYPE (rhs
), &ptr_field
,
2554 if (ref_field
!= fld
)
2557 else if (!tree_int_cst_equal (byte_position (fld
), ref_offset
))
2561 *offset_p
= int_bit_position (fld
);
2565 /* Returns true iff T is an SSA_NAME defined by a statement. */
2568 ipa_is_ssa_with_stmt_def (tree t
)
2570 if (TREE_CODE (t
) == SSA_NAME
2571 && !SSA_NAME_IS_DEFAULT_DEF (t
))
2577 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2578 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2579 indirect call graph edge.
2580 If POLYMORPHIC is true record is as a destination of polymorphic call. */
2582 static struct cgraph_edge
*
2583 ipa_note_param_call (struct cgraph_node
*node
, int param_index
,
2584 gcall
*stmt
, bool polymorphic
)
2586 struct cgraph_edge
*cs
;
2588 cs
= node
->get_edge (stmt
);
2589 cs
->indirect_info
->param_index
= param_index
;
2590 cs
->indirect_info
->agg_contents
= 0;
2591 cs
->indirect_info
->member_ptr
= 0;
2592 cs
->indirect_info
->guaranteed_unmodified
= 0;
2593 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
2594 ipa_set_param_used_by_indirect_call (info
, param_index
, true);
2595 if (cs
->indirect_info
->polymorphic
|| polymorphic
)
2596 ipa_set_param_used_by_polymorphic_call (info
, param_index
, true);
2600 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2601 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2602 intermediate information about each formal parameter. Currently it checks
2603 whether the call calls a pointer that is a formal parameter and if so, the
2604 parameter is marked with the called flag and an indirect call graph edge
2605 describing the call is created. This is very simple for ordinary pointers
2606 represented in SSA but not-so-nice when it comes to member pointers. The
2607 ugly part of this function does nothing more than trying to match the
2608 pattern of such a call. Look up the documentation of macro
2609 TARGET_PTRMEMFUNC_VBIT_LOCATION for details. An example of such a pattern
2610 is the gimple dump below, the call is on the last line:
2613 f$__delta_5 = f.__delta;
2614 f$__pfn_24 = f.__pfn;
2618 f$__delta_5 = MEM[(struct *)&f];
2619 f$__pfn_24 = MEM[(struct *)&f + 4B];
2621 and a few lines below:
2624 D.2496_3 = (int) f$__pfn_24;
2625 D.2497_4 = D.2496_3 & 1;
2632 D.2500_7 = (unsigned int) f$__delta_5;
2633 D.2501_8 = &S + D.2500_7;
2634 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2635 D.2503_10 = *D.2502_9;
2636 D.2504_12 = f$__pfn_24 + -1;
2637 D.2505_13 = (unsigned int) D.2504_12;
2638 D.2506_14 = D.2503_10 + D.2505_13;
2639 D.2507_15 = *D.2506_14;
2640 iftmp.11_16 = (String:: *) D.2507_15;
2643 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2644 D.2500_19 = (unsigned int) f$__delta_5;
2645 D.2508_20 = &S + D.2500_19;
2646 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2648 Such patterns are results of simple calls to a member pointer:
2650 int doprinting (int (MyString::* f)(int) const)
2652 MyString S ("somestring");
2657 Moreover, the function also looks for called pointers loaded from aggregates
2658 passed by value or reference. */
2661 ipa_analyze_indirect_call_uses (struct ipa_func_body_info
*fbi
, gcall
*call
,
2664 class ipa_node_params
*info
= fbi
->info
;
2665 HOST_WIDE_INT offset
;
2668 if (SSA_NAME_IS_DEFAULT_DEF (target
))
2670 tree var
= SSA_NAME_VAR (target
);
2671 int index
= ipa_get_param_decl_index (info
, var
);
2673 ipa_note_param_call (fbi
->node
, index
, call
, false);
2678 gimple
*def
= SSA_NAME_DEF_STMT (target
);
2679 bool guaranteed_unmodified
;
2680 if (gimple_assign_single_p (def
)
2681 && ipa_load_from_parm_agg (fbi
, info
->descriptors
, def
,
2682 gimple_assign_rhs1 (def
), &index
, &offset
,
2683 NULL
, &by_ref
, &guaranteed_unmodified
))
2685 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
,
2687 cs
->indirect_info
->offset
= offset
;
2688 cs
->indirect_info
->agg_contents
= 1;
2689 cs
->indirect_info
->by_ref
= by_ref
;
2690 cs
->indirect_info
->guaranteed_unmodified
= guaranteed_unmodified
;
2694 /* Now we need to try to match the complex pattern of calling a member
2696 if (gimple_code (def
) != GIMPLE_PHI
2697 || gimple_phi_num_args (def
) != 2
2698 || !POINTER_TYPE_P (TREE_TYPE (target
))
2699 || TREE_CODE (TREE_TYPE (TREE_TYPE (target
))) != METHOD_TYPE
)
2702 /* First, we need to check whether one of these is a load from a member
2703 pointer that is a parameter to this function. */
2704 tree n1
= PHI_ARG_DEF (def
, 0);
2705 tree n2
= PHI_ARG_DEF (def
, 1);
2706 if (!ipa_is_ssa_with_stmt_def (n1
) || !ipa_is_ssa_with_stmt_def (n2
))
2708 gimple
*d1
= SSA_NAME_DEF_STMT (n1
);
2709 gimple
*d2
= SSA_NAME_DEF_STMT (n2
);
2712 basic_block bb
, virt_bb
;
2713 basic_block join
= gimple_bb (def
);
2714 if ((rec
= ipa_get_stmt_member_ptr_load_param (d1
, false, &offset
)))
2716 if (ipa_get_stmt_member_ptr_load_param (d2
, false, NULL
))
2719 bb
= EDGE_PRED (join
, 0)->src
;
2720 virt_bb
= gimple_bb (d2
);
2722 else if ((rec
= ipa_get_stmt_member_ptr_load_param (d2
, false, &offset
)))
2724 bb
= EDGE_PRED (join
, 1)->src
;
2725 virt_bb
= gimple_bb (d1
);
2730 /* Second, we need to check that the basic blocks are laid out in the way
2731 corresponding to the pattern. */
2733 if (!single_pred_p (virt_bb
) || !single_succ_p (virt_bb
)
2734 || single_succ (virt_bb
) != join
)
2738 if (single_pred (virt_bb
) != bb
)
2740 /* In cases when the distinction between a normal and a virtual
2741 function is encoded in the delta field, the load of the
2742 actual non-virtual function pointer can be in its own BB. */
2744 if (!single_pred_p (bb
) || !single_succ_p (bb
))
2746 bb
= single_pred (bb
);
2747 if (bb
!= single_pred (virt_bb
))
2751 /* Third, let's see that the branching is done depending on the least
2752 significant bit of the pfn. */
2754 gcond
*branch
= safe_dyn_cast
<gcond
*> (*gsi_last_bb (bb
));
2758 if ((gimple_cond_code (branch
) != NE_EXPR
2759 && gimple_cond_code (branch
) != EQ_EXPR
)
2760 || !integer_zerop (gimple_cond_rhs (branch
)))
2763 tree cond
= gimple_cond_lhs (branch
);
2764 if (!ipa_is_ssa_with_stmt_def (cond
))
2767 def
= SSA_NAME_DEF_STMT (cond
);
2768 if (!is_gimple_assign (def
)
2769 || gimple_assign_rhs_code (def
) != BIT_AND_EXPR
2770 || !integer_onep (gimple_assign_rhs2 (def
)))
2773 cond
= gimple_assign_rhs1 (def
);
2774 if (!ipa_is_ssa_with_stmt_def (cond
))
2777 def
= SSA_NAME_DEF_STMT (cond
);
2779 if (is_gimple_assign (def
)
2780 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def
)))
2782 cond
= gimple_assign_rhs1 (def
);
2783 if (!ipa_is_ssa_with_stmt_def (cond
))
2785 def
= SSA_NAME_DEF_STMT (cond
);
2789 rec2
= ipa_get_stmt_member_ptr_load_param (def
,
2790 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2791 == ptrmemfunc_vbit_in_delta
),
2796 if (TREE_CODE (rec
) == SSA_NAME
)
2798 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (rec
));
2800 || !parm_ref_data_preserved_p (fbi
, index
, call
,
2801 gimple_assign_rhs1 (def
)))
2807 index
= ipa_get_param_decl_index (info
, rec
);
2809 || !parm_preserved_before_stmt_p (fbi
, index
, call
, rec
))
2814 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
,
2816 cs
->indirect_info
->offset
= offset
;
2817 cs
->indirect_info
->agg_contents
= 1;
2818 cs
->indirect_info
->member_ptr
= 1;
2819 cs
->indirect_info
->by_ref
= by_ref
;
2820 cs
->indirect_info
->guaranteed_unmodified
= 1;
2825 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2826 object referenced in the expression is a formal parameter of the caller
2827 FBI->node (described by FBI->info), create a call note for the
2831 ipa_analyze_virtual_call_uses (struct ipa_func_body_info
*fbi
,
2832 gcall
*call
, tree target
)
2834 tree obj
= OBJ_TYPE_REF_OBJECT (target
);
2836 HOST_WIDE_INT anc_offset
;
2838 if (!flag_devirtualize
)
2841 if (TREE_CODE (obj
) != SSA_NAME
)
2844 class ipa_node_params
*info
= fbi
->info
;
2845 if (SSA_NAME_IS_DEFAULT_DEF (obj
))
2847 if (TREE_CODE (SSA_NAME_VAR (obj
)) != PARM_DECL
)
2851 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (obj
));
2852 gcc_assert (index
>= 0);
2853 if (detect_type_change_ssa (fbi
, obj
, obj_type_ref_class (target
),
2859 gimple
*stmt
= SSA_NAME_DEF_STMT (obj
);
2862 expr
= get_ancestor_addr_info (stmt
, &obj
, &anc_offset
);
2865 index
= ipa_get_param_decl_index (info
,
2866 SSA_NAME_VAR (TREE_OPERAND (expr
, 0)));
2867 gcc_assert (index
>= 0);
2868 if (detect_type_change (fbi
, obj
, expr
, obj_type_ref_class (target
),
2873 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
,
2875 class cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
2876 ii
->offset
= anc_offset
;
2877 ii
->otr_token
= tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target
));
2878 ii
->otr_type
= obj_type_ref_class (target
);
2879 ii
->polymorphic
= 1;
2882 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2883 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2884 containing intermediate information about each formal parameter. */
2887 ipa_analyze_call_uses (struct ipa_func_body_info
*fbi
, gcall
*call
)
2889 tree target
= gimple_call_fn (call
);
2892 || (TREE_CODE (target
) != SSA_NAME
2893 && !virtual_method_call_p (target
)))
2896 struct cgraph_edge
*cs
= fbi
->node
->get_edge (call
);
2897 /* If we previously turned the call into a direct call, there is
2898 no need to analyze. */
2899 if (cs
&& !cs
->indirect_unknown_callee
)
2902 if (cs
->indirect_info
->polymorphic
&& flag_devirtualize
)
2905 tree target
= gimple_call_fn (call
);
2906 ipa_polymorphic_call_context
context (current_function_decl
,
2907 target
, call
, &instance
);
2909 gcc_checking_assert (cs
->indirect_info
->otr_type
2910 == obj_type_ref_class (target
));
2911 gcc_checking_assert (cs
->indirect_info
->otr_token
2912 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target
)));
2914 cs
->indirect_info
->vptr_changed
2915 = !context
.get_dynamic_type (instance
,
2916 OBJ_TYPE_REF_OBJECT (target
),
2917 obj_type_ref_class (target
), call
,
2918 &fbi
->aa_walk_budget
);
2919 cs
->indirect_info
->context
= context
;
2922 if (TREE_CODE (target
) == SSA_NAME
)
2923 ipa_analyze_indirect_call_uses (fbi
, call
, target
);
2924 else if (virtual_method_call_p (target
))
2925 ipa_analyze_virtual_call_uses (fbi
, call
, target
);
2929 /* Analyze the call statement STMT with respect to formal parameters (described
2930 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2931 formal parameters are called. */
2934 ipa_analyze_stmt_uses (struct ipa_func_body_info
*fbi
, gimple
*stmt
)
2936 if (is_gimple_call (stmt
))
2937 ipa_analyze_call_uses (fbi
, as_a
<gcall
*> (stmt
));
2940 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2941 If OP is a parameter declaration, mark it as used in the info structure
2945 visit_ref_for_mod_analysis (gimple
*, tree op
, tree
, void *data
)
2947 class ipa_node_params
*info
= (class ipa_node_params
*) data
;
2949 op
= get_base_address (op
);
2951 && TREE_CODE (op
) == PARM_DECL
)
2953 int index
= ipa_get_param_decl_index (info
, op
);
2954 gcc_assert (index
>= 0);
2955 ipa_set_param_used (info
, index
, true);
2961 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2962 the findings in various structures of the associated ipa_node_params
2963 structure, such as parameter flags, notes etc. FBI holds various data about
2964 the function being analyzed. */
2967 ipa_analyze_params_uses_in_bb (struct ipa_func_body_info
*fbi
, basic_block bb
)
2969 gimple_stmt_iterator gsi
;
2970 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2972 gimple
*stmt
= gsi_stmt (gsi
);
2974 if (is_gimple_debug (stmt
))
2977 ipa_analyze_stmt_uses (fbi
, stmt
);
2978 walk_stmt_load_store_addr_ops (stmt
, fbi
->info
,
2979 visit_ref_for_mod_analysis
,
2980 visit_ref_for_mod_analysis
,
2981 visit_ref_for_mod_analysis
);
2983 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2984 walk_stmt_load_store_addr_ops (gsi_stmt (gsi
), fbi
->info
,
2985 visit_ref_for_mod_analysis
,
2986 visit_ref_for_mod_analysis
,
2987 visit_ref_for_mod_analysis
);
2990 /* Return true EXPR is a load from a dereference of SSA_NAME NAME. */
2993 load_from_dereferenced_name (tree expr
, tree name
)
2995 tree base
= get_base_address (expr
);
2996 return (TREE_CODE (base
) == MEM_REF
2997 && TREE_OPERAND (base
, 0) == name
);
3000 /* Calculate controlled uses of parameters of NODE. */
3003 ipa_analyze_controlled_uses (struct cgraph_node
*node
)
3005 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
3007 for (int i
= 0; i
< ipa_get_param_count (info
); i
++)
3009 tree parm
= ipa_get_param (info
, i
);
3011 bool load_dereferenced
= false;
3013 /* For SSA regs see if parameter is used. For non-SSA we compute
3014 the flag during modification analysis. */
3015 if (is_gimple_reg (parm
))
3017 tree ddef
= ssa_default_def (DECL_STRUCT_FUNCTION (node
->decl
),
3019 if (ddef
&& !has_zero_uses (ddef
))
3021 imm_use_iterator imm_iter
;
3024 ipa_set_param_used (info
, i
, true);
3025 FOR_EACH_IMM_USE_STMT (stmt
, imm_iter
, ddef
)
3027 if (is_gimple_debug (stmt
))
3030 int all_stmt_uses
= 0;
3031 use_operand_p use_p
;
3032 FOR_EACH_IMM_USE_ON_STMT (use_p
, imm_iter
)
3035 if (is_gimple_call (stmt
))
3037 if (gimple_call_internal_p (stmt
))
3039 call_uses
= IPA_UNDESCRIBED_USE
;
3042 int recognized_stmt_uses
;
3043 if (gimple_call_fn (stmt
) == ddef
)
3044 recognized_stmt_uses
= 1;
3046 recognized_stmt_uses
= 0;
3047 unsigned arg_count
= gimple_call_num_args (stmt
);
3048 for (unsigned i
= 0; i
< arg_count
; i
++)
3050 tree arg
= gimple_call_arg (stmt
, i
);
3052 recognized_stmt_uses
++;
3053 else if (load_from_dereferenced_name (arg
, ddef
))
3055 load_dereferenced
= true;
3056 recognized_stmt_uses
++;
3060 if (recognized_stmt_uses
!= all_stmt_uses
)
3062 call_uses
= IPA_UNDESCRIBED_USE
;
3066 call_uses
+= all_stmt_uses
;
3068 else if (gimple_assign_single_p (stmt
))
3070 tree rhs
= gimple_assign_rhs1 (stmt
);
3071 if (all_stmt_uses
!= 1
3072 || !load_from_dereferenced_name (rhs
, ddef
))
3074 call_uses
= IPA_UNDESCRIBED_USE
;
3077 load_dereferenced
= true;
3081 call_uses
= IPA_UNDESCRIBED_USE
;
3090 call_uses
= IPA_UNDESCRIBED_USE
;
3091 ipa_set_controlled_uses (info
, i
, call_uses
);
3092 ipa_set_param_load_dereferenced (info
, i
, load_dereferenced
);
3096 /* Free stuff in BI. */
3099 free_ipa_bb_info (struct ipa_bb_info
*bi
)
3101 bi
->cg_edges
.release ();
3102 bi
->param_aa_statuses
.release ();
3105 /* Dominator walker driving the analysis. */
3107 class analysis_dom_walker
: public dom_walker
3110 analysis_dom_walker (struct ipa_func_body_info
*fbi
)
3111 : dom_walker (CDI_DOMINATORS
), m_fbi (fbi
) {}
3113 edge
before_dom_children (basic_block
) final override
;
3116 struct ipa_func_body_info
*m_fbi
;
3120 analysis_dom_walker::before_dom_children (basic_block bb
)
3122 ipa_analyze_params_uses_in_bb (m_fbi
, bb
);
3123 ipa_compute_jump_functions_for_bb (m_fbi
, bb
);
3127 /* Release body info FBI. */
3130 ipa_release_body_info (struct ipa_func_body_info
*fbi
)
3133 struct ipa_bb_info
*bi
;
3135 FOR_EACH_VEC_ELT (fbi
->bb_infos
, i
, bi
)
3136 free_ipa_bb_info (bi
);
3137 fbi
->bb_infos
.release ();
3140 /* Initialize the array describing properties of formal parameters
3141 of NODE, analyze their uses and compute jump functions associated
3142 with actual arguments of calls from within NODE. */
3145 ipa_analyze_node (struct cgraph_node
*node
)
3147 struct ipa_func_body_info fbi
;
3148 class ipa_node_params
*info
;
3150 ipa_check_create_node_params ();
3151 ipa_check_create_edge_args ();
3152 info
= ipa_node_params_sum
->get_create (node
);
3154 if (info
->analysis_done
)
3156 info
->analysis_done
= 1;
3158 if (ipa_func_spec_opts_forbid_analysis_p (node
)
3159 || (count_formal_params (node
->decl
)
3160 >= (1 << IPA_PROP_ARG_INDEX_LIMIT_BITS
)))
3162 gcc_assert (!ipa_get_param_count (info
));
3166 struct function
*func
= DECL_STRUCT_FUNCTION (node
->decl
);
3168 calculate_dominance_info (CDI_DOMINATORS
);
3169 ipa_initialize_node_params (node
);
3170 ipa_analyze_controlled_uses (node
);
3174 fbi
.bb_infos
= vNULL
;
3175 fbi
.bb_infos
.safe_grow_cleared (last_basic_block_for_fn (cfun
), true);
3176 fbi
.param_count
= ipa_get_param_count (info
);
3177 fbi
.aa_walk_budget
= opt_for_fn (node
->decl
, param_ipa_max_aa_steps
);
3179 for (struct cgraph_edge
*cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
3181 ipa_bb_info
*bi
= ipa_get_bb_info (&fbi
, gimple_bb (cs
->call_stmt
));
3182 bi
->cg_edges
.safe_push (cs
);
3185 for (struct cgraph_edge
*cs
= node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
3187 ipa_bb_info
*bi
= ipa_get_bb_info (&fbi
, gimple_bb (cs
->call_stmt
));
3188 bi
->cg_edges
.safe_push (cs
);
3191 enable_ranger (cfun
, false);
3192 analysis_dom_walker (&fbi
).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
3193 disable_ranger (cfun
);
3195 ipa_release_body_info (&fbi
);
3196 free_dominance_info (CDI_DOMINATORS
);
3200 /* Update the jump functions associated with call graph edge E when the call
3201 graph edge CS is being inlined, assuming that E->caller is already (possibly
3202 indirectly) inlined into CS->callee and that E has not been inlined. */
3205 update_jump_functions_after_inlining (struct cgraph_edge
*cs
,
3206 struct cgraph_edge
*e
)
3208 ipa_edge_args
*top
= ipa_edge_args_sum
->get (cs
);
3209 ipa_edge_args
*args
= ipa_edge_args_sum
->get (e
);
3212 int count
= ipa_get_cs_argument_count (args
);
3215 for (i
= 0; i
< count
; i
++)
3217 struct ipa_jump_func
*dst
= ipa_get_ith_jump_func (args
, i
);
3218 class ipa_polymorphic_call_context
*dst_ctx
3219 = ipa_get_ith_polymorhic_call_context (args
, i
);
3223 struct ipa_agg_jf_item
*item
;
3226 FOR_EACH_VEC_ELT (*dst
->agg
.items
, j
, item
)
3229 struct ipa_jump_func
*src
;
3231 if (item
->jftype
!= IPA_JF_PASS_THROUGH
3232 && item
->jftype
!= IPA_JF_LOAD_AGG
)
3235 dst_fid
= item
->value
.pass_through
.formal_id
;
3236 if (!top
|| dst_fid
>= ipa_get_cs_argument_count (top
))
3238 item
->jftype
= IPA_JF_UNKNOWN
;
3242 item
->value
.pass_through
.formal_id
= -1;
3243 src
= ipa_get_ith_jump_func (top
, dst_fid
);
3244 if (src
->type
== IPA_JF_CONST
)
3246 if (item
->jftype
== IPA_JF_PASS_THROUGH
3247 && item
->value
.pass_through
.operation
== NOP_EXPR
)
3249 item
->jftype
= IPA_JF_CONST
;
3250 item
->value
.constant
= src
->value
.constant
.value
;
3254 else if (src
->type
== IPA_JF_PASS_THROUGH
3255 && src
->value
.pass_through
.operation
== NOP_EXPR
)
3257 if (item
->jftype
== IPA_JF_PASS_THROUGH
3258 || !item
->value
.load_agg
.by_ref
3259 || src
->value
.pass_through
.agg_preserved
)
3260 item
->value
.pass_through
.formal_id
3261 = src
->value
.pass_through
.formal_id
;
3263 else if (src
->type
== IPA_JF_ANCESTOR
)
3265 if (item
->jftype
== IPA_JF_PASS_THROUGH
)
3267 if (!src
->value
.ancestor
.offset
)
3268 item
->value
.pass_through
.formal_id
3269 = src
->value
.ancestor
.formal_id
;
3271 else if (src
->value
.ancestor
.agg_preserved
)
3273 gcc_checking_assert (item
->value
.load_agg
.by_ref
);
3275 item
->value
.pass_through
.formal_id
3276 = src
->value
.ancestor
.formal_id
;
3277 item
->value
.load_agg
.offset
3278 += src
->value
.ancestor
.offset
;
3282 if (item
->value
.pass_through
.formal_id
< 0)
3283 item
->jftype
= IPA_JF_UNKNOWN
;
3289 ipa_set_jf_unknown (dst
);
3293 if (dst
->type
== IPA_JF_ANCESTOR
)
3295 struct ipa_jump_func
*src
;
3296 int dst_fid
= dst
->value
.ancestor
.formal_id
;
3297 class ipa_polymorphic_call_context
*src_ctx
3298 = ipa_get_ith_polymorhic_call_context (top
, dst_fid
);
3300 /* Variable number of arguments can cause havoc if we try to access
3301 one that does not exist in the inlined edge. So make sure we
3303 if (dst_fid
>= ipa_get_cs_argument_count (top
))
3305 ipa_set_jf_unknown (dst
);
3309 src
= ipa_get_ith_jump_func (top
, dst_fid
);
3311 if (src_ctx
&& !src_ctx
->useless_p ())
3313 class ipa_polymorphic_call_context ctx
= *src_ctx
;
3315 /* TODO: Make type preserved safe WRT contexts. */
3316 if (!ipa_get_jf_ancestor_type_preserved (dst
))
3317 ctx
.possible_dynamic_type_change (e
->in_polymorphic_cdtor
);
3318 ctx
.offset_by (dst
->value
.ancestor
.offset
);
3319 if (!ctx
.useless_p ())
3323 vec_safe_grow_cleared (args
->polymorphic_call_contexts
,
3325 dst_ctx
= ipa_get_ith_polymorhic_call_context (args
, i
);
3328 dst_ctx
->combine_with (ctx
);
3332 /* Parameter and argument in ancestor jump function must be pointer
3333 type, which means access to aggregate must be by-reference. */
3334 gcc_assert (!src
->agg
.items
|| src
->agg
.by_ref
);
3336 if (src
->agg
.items
&& dst
->value
.ancestor
.agg_preserved
)
3338 struct ipa_agg_jf_item
*item
;
3341 /* Currently we do not produce clobber aggregate jump functions,
3342 replace with merging when we do. */
3343 gcc_assert (!dst
->agg
.items
);
3345 dst
->agg
.items
= vec_safe_copy (src
->agg
.items
);
3346 dst
->agg
.by_ref
= src
->agg
.by_ref
;
3347 FOR_EACH_VEC_SAFE_ELT (dst
->agg
.items
, j
, item
)
3348 item
->offset
-= dst
->value
.ancestor
.offset
;
3351 if (src
->type
== IPA_JF_PASS_THROUGH
3352 && src
->value
.pass_through
.operation
== NOP_EXPR
)
3354 dst
->value
.ancestor
.formal_id
= src
->value
.pass_through
.formal_id
;
3355 dst
->value
.ancestor
.agg_preserved
&=
3356 src
->value
.pass_through
.agg_preserved
;
3358 else if (src
->type
== IPA_JF_ANCESTOR
)
3360 dst
->value
.ancestor
.formal_id
= src
->value
.ancestor
.formal_id
;
3361 dst
->value
.ancestor
.offset
+= src
->value
.ancestor
.offset
;
3362 dst
->value
.ancestor
.agg_preserved
&=
3363 src
->value
.ancestor
.agg_preserved
;
3364 dst
->value
.ancestor
.keep_null
|= src
->value
.ancestor
.keep_null
;
3367 ipa_set_jf_unknown (dst
);
3369 else if (dst
->type
== IPA_JF_PASS_THROUGH
)
3371 struct ipa_jump_func
*src
;
3372 /* We must check range due to calls with variable number of arguments
3373 and we cannot combine jump functions with operations. */
3374 if (dst
->value
.pass_through
.operation
== NOP_EXPR
3375 && (top
&& dst
->value
.pass_through
.formal_id
3376 < ipa_get_cs_argument_count (top
)))
3378 int dst_fid
= dst
->value
.pass_through
.formal_id
;
3379 src
= ipa_get_ith_jump_func (top
, dst_fid
);
3380 bool dst_agg_p
= ipa_get_jf_pass_through_agg_preserved (dst
);
3381 class ipa_polymorphic_call_context
*src_ctx
3382 = ipa_get_ith_polymorhic_call_context (top
, dst_fid
);
3384 if (src_ctx
&& !src_ctx
->useless_p ())
3386 class ipa_polymorphic_call_context ctx
= *src_ctx
;
3388 /* TODO: Make type preserved safe WRT contexts. */
3389 if (!ipa_get_jf_pass_through_type_preserved (dst
))
3390 ctx
.possible_dynamic_type_change (e
->in_polymorphic_cdtor
);
3391 if (!ctx
.useless_p ())
3395 vec_safe_grow_cleared (args
->polymorphic_call_contexts
,
3397 dst_ctx
= ipa_get_ith_polymorhic_call_context (args
, i
);
3399 dst_ctx
->combine_with (ctx
);
3404 case IPA_JF_UNKNOWN
:
3405 ipa_set_jf_unknown (dst
);
3409 bool rd
= ipa_get_jf_pass_through_refdesc_decremented (dst
);
3410 ipa_set_jf_cst_copy (dst
, src
);
3412 ipa_zap_jf_refdesc (dst
);
3417 case IPA_JF_PASS_THROUGH
:
3419 int formal_id
= ipa_get_jf_pass_through_formal_id (src
);
3420 enum tree_code operation
;
3421 operation
= ipa_get_jf_pass_through_operation (src
);
3423 if (operation
== NOP_EXPR
)
3427 && ipa_get_jf_pass_through_agg_preserved (src
);
3428 ipa_set_jf_simple_pass_through (dst
, formal_id
, agg_p
);
3430 else if (TREE_CODE_CLASS (operation
) == tcc_unary
)
3431 ipa_set_jf_unary_pass_through (dst
, formal_id
, operation
);
3434 tree operand
= ipa_get_jf_pass_through_operand (src
);
3435 ipa_set_jf_arith_pass_through (dst
, formal_id
, operand
,
3440 case IPA_JF_ANCESTOR
:
3444 && ipa_get_jf_ancestor_agg_preserved (src
);
3445 ipa_set_ancestor_jf (dst
,
3446 ipa_get_jf_ancestor_offset (src
),
3447 ipa_get_jf_ancestor_formal_id (src
),
3449 ipa_get_jf_ancestor_keep_null (src
));
3457 && (dst_agg_p
|| !src
->agg
.by_ref
))
3459 /* Currently we do not produce clobber aggregate jump
3460 functions, replace with merging when we do. */
3461 gcc_assert (!dst
->agg
.items
);
3463 dst
->agg
.by_ref
= src
->agg
.by_ref
;
3464 dst
->agg
.items
= vec_safe_copy (src
->agg
.items
);
3468 ipa_set_jf_unknown (dst
);
3473 /* If TARGET is an addr_expr of a function declaration, make it the
3474 (SPECULATIVE)destination of an indirect edge IE and return the edge.
3475 Otherwise, return NULL. */
3477 struct cgraph_edge
*
3478 ipa_make_edge_direct_to_target (struct cgraph_edge
*ie
, tree target
,
3481 struct cgraph_node
*callee
;
3482 bool unreachable
= false;
3484 if (TREE_CODE (target
) == ADDR_EXPR
)
3485 target
= TREE_OPERAND (target
, 0);
3486 if (TREE_CODE (target
) != FUNCTION_DECL
)
3488 target
= canonicalize_constructor_val (target
, NULL
);
3489 if (!target
|| TREE_CODE (target
) != FUNCTION_DECL
)
3491 /* Member pointer call that goes through a VMT lookup. */
3492 if (ie
->indirect_info
->member_ptr
3493 /* Or if target is not an invariant expression and we do not
3494 know if it will evaulate to function at runtime.
3495 This can happen when folding through &VAR, where &VAR
3496 is IP invariant, but VAR itself is not.
3498 TODO: Revisit this when GCC 5 is branched. It seems that
3499 member_ptr check is not needed and that we may try to fold
3500 the expression and see if VAR is readonly. */
3501 || !is_gimple_ip_invariant (target
))
3503 if (dump_enabled_p ())
3505 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, ie
->call_stmt
,
3506 "discovered direct call non-invariant %s\n",
3507 ie
->caller
->dump_name ());
3513 if (dump_enabled_p ())
3515 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, ie
->call_stmt
,
3516 "discovered direct call to non-function in %s, "
3517 "making it __builtin_unreachable\n",
3518 ie
->caller
->dump_name ());
3521 target
= builtin_decl_unreachable ();
3522 callee
= cgraph_node::get_create (target
);
3526 callee
= cgraph_node::get (target
);
3529 callee
= cgraph_node::get (target
);
3531 /* Because may-edges are not explicitely represented and vtable may be external,
3532 we may create the first reference to the object in the unit. */
3533 if (!callee
|| callee
->inlined_to
)
3536 /* We are better to ensure we can refer to it.
3537 In the case of static functions we are out of luck, since we already
3538 removed its body. In the case of public functions we may or may
3539 not introduce the reference. */
3540 if (!canonicalize_constructor_val (target
, NULL
)
3541 || !TREE_PUBLIC (target
))
3544 fprintf (dump_file
, "ipa-prop: Discovered call to a known target "
3545 "(%s -> %s) but cannot refer to it. Giving up.\n",
3546 ie
->caller
->dump_name (),
3547 ie
->callee
->dump_name ());
3550 callee
= cgraph_node::get_create (target
);
3553 /* If the edge is already speculated. */
3554 if (speculative
&& ie
->speculative
)
3558 cgraph_edge
*e2
= ie
->speculative_call_for_target (callee
);
3562 fprintf (dump_file
, "ipa-prop: Discovered call to a "
3563 "speculative target (%s -> %s) but the call is "
3564 "already speculated to different target. "
3566 ie
->caller
->dump_name (), callee
->dump_name ());
3572 "ipa-prop: Discovered call to a speculative target "
3573 "(%s -> %s) this agree with previous speculation.\n",
3574 ie
->caller
->dump_name (), callee
->dump_name ());
3580 if (!dbg_cnt (devirt
))
3583 ipa_check_create_node_params ();
3585 /* We cannot make edges to inline clones. It is bug that someone removed
3586 the cgraph node too early. */
3587 gcc_assert (!callee
->inlined_to
);
3589 if (dump_file
&& !unreachable
)
3591 fprintf (dump_file
, "ipa-prop: Discovered %s call to a %s target "
3592 "(%s -> %s), for stmt ",
3593 ie
->indirect_info
->polymorphic
? "a virtual" : "an indirect",
3594 speculative
? "speculative" : "known",
3595 ie
->caller
->dump_name (),
3596 callee
->dump_name ());
3598 print_gimple_stmt (dump_file
, ie
->call_stmt
, 2, TDF_SLIM
);
3600 fprintf (dump_file
, "with uid %i\n", ie
->lto_stmt_uid
);
3602 if (dump_enabled_p ())
3604 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, ie
->call_stmt
,
3605 "converting indirect call in %s to direct call to %s\n",
3606 ie
->caller
->dump_name (), callee
->dump_name ());
3610 struct cgraph_edge
*orig
= ie
;
3611 ie
= cgraph_edge::make_direct (ie
, callee
);
3612 /* If we resolved speculative edge the cost is already up to date
3613 for direct call (adjusted by inline_edge_duplication_hook). */
3616 ipa_call_summary
*es
= ipa_call_summaries
->get (ie
);
3617 es
->call_stmt_size
-= (eni_size_weights
.indirect_call_cost
3618 - eni_size_weights
.call_cost
);
3619 es
->call_stmt_time
-= (eni_time_weights
.indirect_call_cost
3620 - eni_time_weights
.call_cost
);
3625 if (!callee
->can_be_discarded_p ())
3628 alias
= dyn_cast
<cgraph_node
*> (callee
->noninterposable_alias ());
3632 /* make_speculative will update ie's cost to direct call cost. */
3633 ie
= ie
->make_speculative
3634 (callee
, ie
->count
.apply_scale (8, 10));
3640 /* Attempt to locate an interprocedural constant at a given REQ_OFFSET in
3641 CONSTRUCTOR and return it. Return NULL if the search fails for some
3645 find_constructor_constant_at_offset (tree constructor
, HOST_WIDE_INT req_offset
)
3647 tree type
= TREE_TYPE (constructor
);
3648 if (TREE_CODE (type
) != ARRAY_TYPE
3649 && TREE_CODE (type
) != RECORD_TYPE
)
3654 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (constructor
), ix
, index
, val
)
3656 HOST_WIDE_INT elt_offset
;
3657 if (TREE_CODE (type
) == ARRAY_TYPE
)
3660 tree unit_size
= TYPE_SIZE_UNIT (TREE_TYPE (type
));
3661 gcc_assert (TREE_CODE (unit_size
) == INTEGER_CST
);
3665 if (TREE_CODE (index
) == RANGE_EXPR
)
3666 off
= wi::to_offset (TREE_OPERAND (index
, 0));
3668 off
= wi::to_offset (index
);
3669 if (TYPE_DOMAIN (type
) && TYPE_MIN_VALUE (TYPE_DOMAIN (type
)))
3671 tree low_bound
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
3672 gcc_assert (TREE_CODE (unit_size
) == INTEGER_CST
);
3673 off
= wi::sext (off
- wi::to_offset (low_bound
),
3674 TYPE_PRECISION (TREE_TYPE (index
)));
3676 off
*= wi::to_offset (unit_size
);
3677 /* ??? Handle more than just the first index of a
3681 off
= wi::to_offset (unit_size
) * ix
;
3683 off
= wi::lshift (off
, LOG2_BITS_PER_UNIT
);
3684 if (!wi::fits_shwi_p (off
) || wi::neg_p (off
))
3686 elt_offset
= off
.to_shwi ();
3688 else if (TREE_CODE (type
) == RECORD_TYPE
)
3690 gcc_checking_assert (index
&& TREE_CODE (index
) == FIELD_DECL
);
3691 if (DECL_BIT_FIELD (index
))
3693 elt_offset
= int_bit_position (index
);
3698 if (elt_offset
> req_offset
)
3701 if (TREE_CODE (val
) == CONSTRUCTOR
)
3702 return find_constructor_constant_at_offset (val
,
3703 req_offset
- elt_offset
);
3705 if (elt_offset
== req_offset
3706 && is_gimple_reg_type (TREE_TYPE (val
))
3707 && is_gimple_ip_invariant (val
))
3713 /* Check whether SCALAR could be used to look up an aggregate interprocedural
3714 invariant from a static constructor and if so, return it. Otherwise return
3718 ipa_find_agg_cst_from_init (tree scalar
, HOST_WIDE_INT offset
, bool by_ref
)
3722 if (TREE_CODE (scalar
) != ADDR_EXPR
)
3724 scalar
= TREE_OPERAND (scalar
, 0);
3728 || !is_global_var (scalar
)
3729 || !TREE_READONLY (scalar
)
3730 || !DECL_INITIAL (scalar
)
3731 || TREE_CODE (DECL_INITIAL (scalar
)) != CONSTRUCTOR
)
3734 return find_constructor_constant_at_offset (DECL_INITIAL (scalar
), offset
);
3737 /* Retrieve value from AGG_JFUNC for the given OFFSET or return NULL if there
3738 is none. BY_REF specifies whether the value has to be passed by reference
3742 ipa_find_agg_cst_from_jfunc_items (struct ipa_agg_jump_function
*agg_jfunc
,
3743 ipa_node_params
*src_info
,
3744 cgraph_node
*src_node
,
3745 HOST_WIDE_INT offset
, bool by_ref
)
3747 if (by_ref
!= agg_jfunc
->by_ref
)
3750 for (const ipa_agg_jf_item
&item
: agg_jfunc
->items
)
3751 if (item
.offset
== offset
)
3752 return ipa_agg_value_from_jfunc (src_info
, src_node
, &item
);
3757 /* Remove a reference to SYMBOL from the list of references of a node given by
3758 reference description RDESC. Return true if the reference has been
3759 successfully found and removed. */
3762 remove_described_reference (symtab_node
*symbol
, struct ipa_cst_ref_desc
*rdesc
)
3764 struct ipa_ref
*to_del
;
3765 struct cgraph_edge
*origin
;
3770 to_del
= origin
->caller
->find_reference (symbol
, origin
->call_stmt
,
3771 origin
->lto_stmt_uid
, IPA_REF_ADDR
);
3775 to_del
->remove_reference ();
3777 fprintf (dump_file
, "ipa-prop: Removed a reference from %s to %s.\n",
3778 origin
->caller
->dump_name (), symbol
->dump_name ());
3782 /* If JFUNC has a reference description with refcount different from
3783 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
3784 NULL. JFUNC must be a constant jump function. */
3786 static struct ipa_cst_ref_desc
*
3787 jfunc_rdesc_usable (struct ipa_jump_func
*jfunc
)
3789 struct ipa_cst_ref_desc
*rdesc
= ipa_get_jf_constant_rdesc (jfunc
);
3790 if (rdesc
&& rdesc
->refcount
!= IPA_UNDESCRIBED_USE
)
3796 /* If the value of constant jump function JFUNC is an address of a function
3797 declaration, return the associated call graph node. Otherwise return
3800 static symtab_node
*
3801 symtab_node_for_jfunc (struct ipa_jump_func
*jfunc
)
3803 gcc_checking_assert (jfunc
->type
== IPA_JF_CONST
);
3804 tree cst
= ipa_get_jf_constant (jfunc
);
3805 if (TREE_CODE (cst
) != ADDR_EXPR
3806 || (TREE_CODE (TREE_OPERAND (cst
, 0)) != FUNCTION_DECL
3807 && TREE_CODE (TREE_OPERAND (cst
, 0)) != VAR_DECL
))
3810 return symtab_node::get (TREE_OPERAND (cst
, 0));
3814 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
3815 refcount and if it hits zero, remove reference to SYMBOL from the caller of
3816 the edge specified in the rdesc. Return false if either the symbol or the
3817 reference could not be found, otherwise return true. */
3820 try_decrement_rdesc_refcount (struct ipa_jump_func
*jfunc
)
3822 struct ipa_cst_ref_desc
*rdesc
;
3823 if (jfunc
->type
== IPA_JF_CONST
3824 && (rdesc
= jfunc_rdesc_usable (jfunc
))
3825 && --rdesc
->refcount
== 0)
3827 symtab_node
*symbol
= symtab_node_for_jfunc (jfunc
);
3831 return remove_described_reference (symbol
, rdesc
);
3836 /* Try to find a destination for indirect edge IE that corresponds to a simple
3837 call or a call of a member function pointer and where the destination is a
3838 pointer formal parameter described by jump function JFUNC. TARGET_TYPE is
3839 the type of the parameter to which the result of JFUNC is passed. If it can
3840 be determined, return the newly direct edge, otherwise return NULL.
3841 NEW_ROOT and NEW_ROOT_INFO is the node and its info that JFUNC lattices are
3844 static struct cgraph_edge
*
3845 try_make_edge_direct_simple_call (struct cgraph_edge
*ie
,
3846 struct ipa_jump_func
*jfunc
, tree target_type
,
3847 struct cgraph_node
*new_root
,
3848 class ipa_node_params
*new_root_info
)
3850 struct cgraph_edge
*cs
;
3851 tree target
= NULL_TREE
;
3852 bool agg_contents
= ie
->indirect_info
->agg_contents
;
3853 tree scalar
= ipa_value_from_jfunc (new_root_info
, jfunc
, target_type
);
3857 target
= ipa_find_agg_cst_from_init (scalar
, ie
->indirect_info
->offset
,
3858 ie
->indirect_info
->by_ref
);
3859 if (!target
&& ie
->indirect_info
->guaranteed_unmodified
)
3860 target
= ipa_find_agg_cst_from_jfunc_items (&jfunc
->agg
, new_root_info
,
3862 ie
->indirect_info
->offset
,
3863 ie
->indirect_info
->by_ref
);
3869 cs
= ipa_make_edge_direct_to_target (ie
, target
);
3871 if (cs
&& !agg_contents
)
3874 gcc_checking_assert (cs
->callee
3876 || jfunc
->type
!= IPA_JF_CONST
3877 || !symtab_node_for_jfunc (jfunc
)
3878 || cs
->callee
== symtab_node_for_jfunc (jfunc
)));
3879 ok
= try_decrement_rdesc_refcount (jfunc
);
3880 gcc_checking_assert (ok
);
3886 /* Return the target to be used in cases of impossible devirtualization. IE
3887 and target (the latter can be NULL) are dumped when dumping is enabled. */
3890 ipa_impossible_devirt_target (struct cgraph_edge
*ie
, tree target
)
3896 "Type inconsistent devirtualization: %s->%s\n",
3897 ie
->caller
->dump_name (),
3898 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target
)));
3901 "No devirtualization target in %s\n",
3902 ie
->caller
->dump_name ());
3904 tree new_target
= builtin_decl_unreachable ();
3905 cgraph_node::get_create (new_target
);
3909 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3910 call based on a formal parameter which is described by jump function JFUNC
3911 and if it can be determined, make it direct and return the direct edge.
3912 Otherwise, return NULL. CTX describes the polymorphic context that the
3913 parameter the call is based on brings along with it. NEW_ROOT and
3914 NEW_ROOT_INFO is the node and its info that JFUNC lattices are relative
3917 static struct cgraph_edge
*
3918 try_make_edge_direct_virtual_call (struct cgraph_edge
*ie
,
3919 struct ipa_jump_func
*jfunc
,
3920 class ipa_polymorphic_call_context ctx
,
3921 struct cgraph_node
*new_root
,
3922 class ipa_node_params
*new_root_info
)
3925 bool speculative
= false;
3927 if (!opt_for_fn (ie
->caller
->decl
, flag_devirtualize
))
3930 gcc_assert (!ie
->indirect_info
->by_ref
);
3932 /* Try to do lookup via known virtual table pointer value. */
3933 if (!ie
->indirect_info
->vptr_changed
3934 || opt_for_fn (ie
->caller
->decl
, flag_devirtualize_speculatively
))
3937 unsigned HOST_WIDE_INT offset
;
3939 if (jfunc
->type
== IPA_JF_CONST
)
3940 t
= ipa_find_agg_cst_from_init (ipa_get_jf_constant (jfunc
),
3941 ie
->indirect_info
->offset
, true);
3943 t
= ipa_find_agg_cst_from_jfunc_items (&jfunc
->agg
, new_root_info
,
3945 ie
->indirect_info
->offset
, true);
3946 if (t
&& vtable_pointer_value_to_vtable (t
, &vtable
, &offset
))
3949 t
= gimple_get_virt_method_for_vtable (ie
->indirect_info
->otr_token
,
3950 vtable
, offset
, &can_refer
);
3954 || fndecl_built_in_p (t
, BUILT_IN_UNREACHABLE
,
3955 BUILT_IN_UNREACHABLE_TRAP
)
3956 || !possible_polymorphic_call_target_p
3957 (ie
, cgraph_node::get (t
)))
3959 /* Do not speculate builtin_unreachable, it is stupid! */
3960 if (!ie
->indirect_info
->vptr_changed
)
3961 target
= ipa_impossible_devirt_target (ie
, target
);
3968 speculative
= ie
->indirect_info
->vptr_changed
;
3974 ipa_polymorphic_call_context
ie_context (ie
);
3975 vec
<cgraph_node
*>targets
;
3978 ctx
.offset_by (ie
->indirect_info
->offset
);
3979 if (ie
->indirect_info
->vptr_changed
)
3980 ctx
.possible_dynamic_type_change (ie
->in_polymorphic_cdtor
,
3981 ie
->indirect_info
->otr_type
);
3982 ctx
.combine_with (ie_context
, ie
->indirect_info
->otr_type
);
3983 targets
= possible_polymorphic_call_targets
3984 (ie
->indirect_info
->otr_type
,
3985 ie
->indirect_info
->otr_token
,
3987 if (final
&& targets
.length () <= 1)
3989 speculative
= false;
3990 if (targets
.length () == 1)
3991 target
= targets
[0]->decl
;
3993 target
= ipa_impossible_devirt_target (ie
, NULL_TREE
);
3995 else if (!target
&& opt_for_fn (ie
->caller
->decl
, flag_devirtualize_speculatively
)
3996 && !ie
->speculative
&& ie
->maybe_hot_p ())
3999 n
= try_speculative_devirtualization (ie
->indirect_info
->otr_type
,
4000 ie
->indirect_info
->otr_token
,
4001 ie
->indirect_info
->context
);
4011 if (!possible_polymorphic_call_target_p
4012 (ie
, cgraph_node::get_create (target
)))
4016 target
= ipa_impossible_devirt_target (ie
, target
);
4018 return ipa_make_edge_direct_to_target (ie
, target
, speculative
);
4024 /* Update the param called notes associated with NODE when CS is being inlined,
4025 assuming NODE is (potentially indirectly) inlined into CS->callee.
4026 Moreover, if the callee is discovered to be constant, create a new cgraph
4027 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
4028 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
4031 update_indirect_edges_after_inlining (struct cgraph_edge
*cs
,
4032 struct cgraph_node
*node
,
4033 vec
<cgraph_edge
*> *new_edges
)
4035 class ipa_edge_args
*top
;
4036 struct cgraph_edge
*ie
, *next_ie
, *new_direct_edge
;
4037 struct cgraph_node
*new_root
;
4038 class ipa_node_params
*new_root_info
, *inlined_node_info
;
4041 ipa_check_create_edge_args ();
4042 top
= ipa_edge_args_sum
->get (cs
);
4043 new_root
= cs
->caller
->inlined_to
4044 ? cs
->caller
->inlined_to
: cs
->caller
;
4045 new_root_info
= ipa_node_params_sum
->get (new_root
);
4046 inlined_node_info
= ipa_node_params_sum
->get (cs
->callee
->function_symbol ());
4048 for (ie
= node
->indirect_calls
; ie
; ie
= next_ie
)
4050 class cgraph_indirect_call_info
*ici
= ie
->indirect_info
;
4051 struct ipa_jump_func
*jfunc
;
4054 next_ie
= ie
->next_callee
;
4056 if (ici
->param_index
== -1)
4059 /* We must check range due to calls with variable number of arguments: */
4060 if (!top
|| ici
->param_index
>= ipa_get_cs_argument_count (top
))
4062 ici
->param_index
= -1;
4066 param_index
= ici
->param_index
;
4067 jfunc
= ipa_get_ith_jump_func (top
, param_index
);
4069 auto_vec
<cgraph_node
*, 4> spec_targets
;
4070 if (ie
->speculative
)
4071 for (cgraph_edge
*direct
= ie
->first_speculative_call_target ();
4073 direct
= direct
->next_speculative_call_target ())
4074 spec_targets
.safe_push (direct
->callee
);
4076 if (!opt_for_fn (node
->decl
, flag_indirect_inlining
))
4077 new_direct_edge
= NULL
;
4078 else if (ici
->polymorphic
)
4080 ipa_polymorphic_call_context ctx
;
4081 ctx
= ipa_context_from_jfunc (new_root_info
, cs
, param_index
, jfunc
);
4082 new_direct_edge
= try_make_edge_direct_virtual_call (ie
, jfunc
, ctx
,
4088 tree target_type
= ipa_get_type (inlined_node_info
, param_index
);
4089 new_direct_edge
= try_make_edge_direct_simple_call (ie
, jfunc
,
4095 /* If speculation was removed, then we need to do nothing. */
4096 if (new_direct_edge
&& new_direct_edge
!= ie
4097 && spec_targets
.contains (new_direct_edge
->callee
))
4099 new_direct_edge
->indirect_inlining_edge
= 1;
4101 if (!new_direct_edge
->speculative
)
4104 else if (new_direct_edge
)
4106 new_direct_edge
->indirect_inlining_edge
= 1;
4109 new_edges
->safe_push (new_direct_edge
);
4112 /* If speculative edge was introduced we still need to update
4113 call info of the indirect edge. */
4114 if (!new_direct_edge
->speculative
)
4117 if (jfunc
->type
== IPA_JF_PASS_THROUGH
4118 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
4120 if (ici
->agg_contents
4121 && !ipa_get_jf_pass_through_agg_preserved (jfunc
)
4122 && !ici
->polymorphic
)
4123 ici
->param_index
= -1;
4126 ici
->param_index
= ipa_get_jf_pass_through_formal_id (jfunc
);
4127 if (ici
->polymorphic
4128 && !ipa_get_jf_pass_through_type_preserved (jfunc
))
4129 ici
->vptr_changed
= true;
4130 ipa_set_param_used_by_indirect_call (new_root_info
,
4131 ici
->param_index
, true);
4132 if (ici
->polymorphic
)
4133 ipa_set_param_used_by_polymorphic_call (new_root_info
,
4134 ici
->param_index
, true);
4137 else if (jfunc
->type
== IPA_JF_ANCESTOR
)
4139 if (ici
->agg_contents
4140 && !ipa_get_jf_ancestor_agg_preserved (jfunc
)
4141 && !ici
->polymorphic
)
4142 ici
->param_index
= -1;
4145 ici
->param_index
= ipa_get_jf_ancestor_formal_id (jfunc
);
4146 ici
->offset
+= ipa_get_jf_ancestor_offset (jfunc
);
4147 if (ici
->polymorphic
4148 && !ipa_get_jf_ancestor_type_preserved (jfunc
))
4149 ici
->vptr_changed
= true;
4150 ipa_set_param_used_by_indirect_call (new_root_info
,
4151 ici
->param_index
, true);
4152 if (ici
->polymorphic
)
4153 ipa_set_param_used_by_polymorphic_call (new_root_info
,
4154 ici
->param_index
, true);
4158 /* Either we can find a destination for this edge now or never. */
4159 ici
->param_index
= -1;
4165 /* Recursively traverse subtree of NODE (including node) made of inlined
4166 cgraph_edges when CS has been inlined and invoke
4167 update_indirect_edges_after_inlining on all nodes and
4168 update_jump_functions_after_inlining on all non-inlined edges that lead out
4169 of this subtree. Newly discovered indirect edges will be added to
4170 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
4174 propagate_info_to_inlined_callees (struct cgraph_edge
*cs
,
4175 struct cgraph_node
*node
,
4176 vec
<cgraph_edge
*> *new_edges
)
4178 struct cgraph_edge
*e
;
4181 res
= update_indirect_edges_after_inlining (cs
, node
, new_edges
);
4183 for (e
= node
->callees
; e
; e
= e
->next_callee
)
4184 if (!e
->inline_failed
)
4185 res
|= propagate_info_to_inlined_callees (cs
, e
->callee
, new_edges
);
4187 update_jump_functions_after_inlining (cs
, e
);
4188 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
4189 update_jump_functions_after_inlining (cs
, e
);
4194 /* Combine two controlled uses counts as done during inlining. */
4197 combine_controlled_uses_counters (int c
, int d
)
4199 if (c
== IPA_UNDESCRIBED_USE
|| d
== IPA_UNDESCRIBED_USE
)
4200 return IPA_UNDESCRIBED_USE
;
4205 /* Propagate number of controlled users from CS->caleee to the new root of the
4206 tree of inlined nodes. */
4209 propagate_controlled_uses (struct cgraph_edge
*cs
)
4211 ipa_edge_args
*args
= ipa_edge_args_sum
->get (cs
);
4214 struct cgraph_node
*new_root
= cs
->caller
->inlined_to
4215 ? cs
->caller
->inlined_to
: cs
->caller
;
4216 ipa_node_params
*new_root_info
= ipa_node_params_sum
->get (new_root
);
4217 ipa_node_params
*old_root_info
= ipa_node_params_sum
->get (cs
->callee
);
4223 count
= MIN (ipa_get_cs_argument_count (args
),
4224 ipa_get_param_count (old_root_info
));
4225 for (i
= 0; i
< count
; i
++)
4227 struct ipa_jump_func
*jf
= ipa_get_ith_jump_func (args
, i
);
4228 struct ipa_cst_ref_desc
*rdesc
;
4230 if (jf
->type
== IPA_JF_PASS_THROUGH
4231 && !ipa_get_jf_pass_through_refdesc_decremented (jf
))
4234 src_idx
= ipa_get_jf_pass_through_formal_id (jf
);
4235 c
= ipa_get_controlled_uses (new_root_info
, src_idx
);
4236 d
= ipa_get_controlled_uses (old_root_info
, i
);
4238 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf
)
4239 == NOP_EXPR
|| c
== IPA_UNDESCRIBED_USE
);
4240 c
= combine_controlled_uses_counters (c
, d
);
4241 ipa_set_controlled_uses (new_root_info
, src_idx
, c
);
4243 if (c
!= IPA_UNDESCRIBED_USE
)
4245 lderef
= (ipa_get_param_load_dereferenced (new_root_info
, src_idx
)
4246 || ipa_get_param_load_dereferenced (old_root_info
, i
));
4247 ipa_set_param_load_dereferenced (new_root_info
, src_idx
, lderef
);
4250 if (c
== 0 && !lderef
&& new_root_info
->ipcp_orig_node
)
4252 struct cgraph_node
*n
;
4253 struct ipa_ref
*ref
;
4254 tree t
= new_root_info
->known_csts
[src_idx
];
4256 if (t
&& TREE_CODE (t
) == ADDR_EXPR
4257 && TREE_CODE (TREE_OPERAND (t
, 0)) == FUNCTION_DECL
4258 && (n
= cgraph_node::get (TREE_OPERAND (t
, 0)))
4259 && (ref
= new_root
->find_reference (n
, NULL
, 0,
4263 fprintf (dump_file
, "ipa-prop: Removing cloning-created "
4264 "reference from %s to %s.\n",
4265 new_root
->dump_name (),
4267 ref
->remove_reference ();
4271 else if (jf
->type
== IPA_JF_CONST
4272 && (rdesc
= jfunc_rdesc_usable (jf
)))
4274 int d
= ipa_get_controlled_uses (old_root_info
, i
);
4275 int c
= rdesc
->refcount
;
4276 tree cst
= ipa_get_jf_constant (jf
);
4277 rdesc
->refcount
= combine_controlled_uses_counters (c
, d
);
4278 if (rdesc
->refcount
!= IPA_UNDESCRIBED_USE
4279 && ipa_get_param_load_dereferenced (old_root_info
, i
)
4280 && TREE_CODE (cst
) == ADDR_EXPR
4281 && VAR_P (TREE_OPERAND (cst
, 0)))
4283 symtab_node
*n
= symtab_node::get (TREE_OPERAND (cst
, 0));
4284 new_root
->create_reference (n
, IPA_REF_LOAD
, NULL
);
4286 fprintf (dump_file
, "ipa-prop: Address IPA constant will reach "
4287 "a load so adding LOAD reference from %s to %s.\n",
4288 new_root
->dump_name (), n
->dump_name ());
4290 if (rdesc
->refcount
== 0)
4292 gcc_checking_assert (TREE_CODE (cst
) == ADDR_EXPR
4293 && ((TREE_CODE (TREE_OPERAND (cst
, 0))
4295 || VAR_P (TREE_OPERAND (cst
, 0))));
4297 symtab_node
*n
= symtab_node::get (TREE_OPERAND (cst
, 0));
4300 remove_described_reference (n
, rdesc
);
4301 cgraph_node
*clone
= cs
->caller
;
4302 while (clone
->inlined_to
4303 && clone
->ipcp_clone
4304 && clone
!= rdesc
->cs
->caller
)
4306 struct ipa_ref
*ref
;
4307 ref
= clone
->find_reference (n
, NULL
, 0, IPA_REF_ADDR
);
4311 fprintf (dump_file
, "ipa-prop: Removing "
4312 "cloning-created reference "
4314 clone
->dump_name (),
4316 ref
->remove_reference ();
4318 clone
= clone
->callers
->caller
;
4325 for (i
= ipa_get_param_count (old_root_info
);
4326 i
< ipa_get_cs_argument_count (args
);
4329 struct ipa_jump_func
*jf
= ipa_get_ith_jump_func (args
, i
);
4331 if (jf
->type
== IPA_JF_CONST
)
4333 struct ipa_cst_ref_desc
*rdesc
= jfunc_rdesc_usable (jf
);
4335 rdesc
->refcount
= IPA_UNDESCRIBED_USE
;
4337 else if (jf
->type
== IPA_JF_PASS_THROUGH
)
4338 ipa_set_controlled_uses (new_root_info
,
4339 jf
->value
.pass_through
.formal_id
,
4340 IPA_UNDESCRIBED_USE
);
4344 /* Update jump functions and call note functions on inlining the call site CS.
4345 CS is expected to lead to a node already cloned by
4346 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
4347 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
4351 ipa_propagate_indirect_call_infos (struct cgraph_edge
*cs
,
4352 vec
<cgraph_edge
*> *new_edges
)
4355 /* Do nothing if the preparation phase has not been carried out yet
4356 (i.e. during early inlining). */
4357 if (!ipa_node_params_sum
)
4359 gcc_assert (ipa_edge_args_sum
);
4361 propagate_controlled_uses (cs
);
4362 changed
= propagate_info_to_inlined_callees (cs
, cs
->callee
, new_edges
);
4363 ipa_node_params_sum
->remove (cs
->callee
);
4365 ipa_edge_args
*args
= ipa_edge_args_sum
->get (cs
);
4369 if (args
->jump_functions
)
4371 struct ipa_jump_func
*jf
;
4373 FOR_EACH_VEC_ELT (*args
->jump_functions
, i
, jf
)
4374 if (jf
->type
== IPA_JF_CONST
4375 && ipa_get_jf_constant_rdesc (jf
))
4382 ipa_edge_args_sum
->remove (cs
);
4384 if (ipcp_transformation_sum
)
4385 ipcp_transformation_sum
->remove (cs
->callee
);
4390 /* Ensure that array of edge arguments infos is big enough to accommodate a
4391 structure for all edges and reallocates it if not. Also, allocate
4392 associated hash tables is they do not already exist. */
4395 ipa_check_create_edge_args (void)
4397 if (!ipa_edge_args_sum
)
4399 = (new (ggc_alloc_no_dtor
<ipa_edge_args_sum_t
> ())
4400 ipa_edge_args_sum_t (symtab
, true));
4401 if (!ipa_vr_hash_table
)
4402 ipa_vr_hash_table
= hash_table
<ipa_vr_ggc_hash_traits
>::create_ggc (37);
4405 /* Free all ipa_edge structures. */
4408 ipa_free_all_edge_args (void)
4410 if (!ipa_edge_args_sum
)
4413 ggc_delete (ipa_edge_args_sum
);
4414 ipa_edge_args_sum
= NULL
;
4417 /* Free all ipa_node_params structures. */
4420 ipa_free_all_node_params (void)
4422 if (ipa_node_params_sum
)
4423 ggc_delete (ipa_node_params_sum
);
4424 ipa_node_params_sum
= NULL
;
4427 /* Initialize IPA CP transformation summary and also allocate any necessary hash
4428 tables if they do not already exist. */
4431 ipcp_transformation_initialize (void)
4433 if (!ipa_vr_hash_table
)
4434 ipa_vr_hash_table
= hash_table
<ipa_vr_ggc_hash_traits
>::create_ggc (37);
4435 if (ipcp_transformation_sum
== NULL
)
4437 ipcp_transformation_sum
= ipcp_transformation_t::create_ggc (symtab
);
4438 ipcp_transformation_sum
->disable_insertion_hook ();
4442 /* Release the IPA CP transformation summary. */
4445 ipcp_free_transformation_sum (void)
4447 if (!ipcp_transformation_sum
)
4450 ipcp_transformation_sum
->~function_summary
<ipcp_transformation
*> ();
4451 ggc_free (ipcp_transformation_sum
);
4452 ipcp_transformation_sum
= NULL
;
4455 /* Set the aggregate replacements of NODE to be AGGVALS. */
4458 ipa_set_node_agg_value_chain (struct cgraph_node
*node
,
4459 vec
<ipa_argagg_value
, va_gc
> *aggs
)
4461 ipcp_transformation_initialize ();
4462 ipcp_transformation
*s
= ipcp_transformation_sum
->get_create (node
);
4463 s
->m_agg_values
= aggs
;
4466 /* Hook that is called by cgraph.cc when an edge is removed. Adjust reference
4467 count data structures accordingly. */
4470 ipa_edge_args_sum_t::remove (cgraph_edge
*cs
, ipa_edge_args
*args
)
4472 if (args
->jump_functions
)
4474 struct ipa_jump_func
*jf
;
4476 FOR_EACH_VEC_ELT (*args
->jump_functions
, i
, jf
)
4478 struct ipa_cst_ref_desc
*rdesc
;
4479 try_decrement_rdesc_refcount (jf
);
4480 if (jf
->type
== IPA_JF_CONST
4481 && (rdesc
= ipa_get_jf_constant_rdesc (jf
))
4488 /* Method invoked when an edge is duplicated. Copy ipa_edge_args and adjust
4489 reference count data strucutres accordingly. */
4492 ipa_edge_args_sum_t::duplicate (cgraph_edge
*src
, cgraph_edge
*dst
,
4493 ipa_edge_args
*old_args
, ipa_edge_args
*new_args
)
4497 new_args
->jump_functions
= vec_safe_copy (old_args
->jump_functions
);
4498 if (old_args
->polymorphic_call_contexts
)
4499 new_args
->polymorphic_call_contexts
4500 = vec_safe_copy (old_args
->polymorphic_call_contexts
);
4502 for (i
= 0; i
< vec_safe_length (old_args
->jump_functions
); i
++)
4504 struct ipa_jump_func
*src_jf
= ipa_get_ith_jump_func (old_args
, i
);
4505 struct ipa_jump_func
*dst_jf
= ipa_get_ith_jump_func (new_args
, i
);
4507 dst_jf
->agg
.items
= vec_safe_copy (dst_jf
->agg
.items
);
4509 if (src_jf
->type
== IPA_JF_CONST
)
4511 struct ipa_cst_ref_desc
*src_rdesc
= jfunc_rdesc_usable (src_jf
);
4514 dst_jf
->value
.constant
.rdesc
= NULL
;
4515 else if (src
->caller
== dst
->caller
)
4517 /* Creation of a speculative edge. If the source edge is the one
4518 grabbing a reference, we must create a new (duplicate)
4519 reference description. Otherwise they refer to the same
4520 description corresponding to a reference taken in a function
4521 src->caller is inlined to. In that case we just must
4522 increment the refcount. */
4523 if (src_rdesc
->cs
== src
)
4525 symtab_node
*n
= symtab_node_for_jfunc (src_jf
);
4526 gcc_checking_assert (n
);
4528 = src
->caller
->find_reference (n
, src
->call_stmt
,
4531 gcc_checking_assert (ref
);
4532 dst
->caller
->clone_reference (ref
, ref
->stmt
);
4534 ipa_cst_ref_desc
*dst_rdesc
= ipa_refdesc_pool
.allocate ();
4535 dst_rdesc
->cs
= dst
;
4536 dst_rdesc
->refcount
= src_rdesc
->refcount
;
4537 dst_rdesc
->next_duplicate
= NULL
;
4538 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
4542 src_rdesc
->refcount
++;
4543 dst_jf
->value
.constant
.rdesc
= src_rdesc
;
4546 else if (src_rdesc
->cs
== src
)
4548 struct ipa_cst_ref_desc
*dst_rdesc
= ipa_refdesc_pool
.allocate ();
4549 dst_rdesc
->cs
= dst
;
4550 dst_rdesc
->refcount
= src_rdesc
->refcount
;
4551 dst_rdesc
->next_duplicate
= src_rdesc
->next_duplicate
;
4552 src_rdesc
->next_duplicate
= dst_rdesc
;
4553 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
4557 struct ipa_cst_ref_desc
*dst_rdesc
;
4558 /* This can happen during inlining, when a JFUNC can refer to a
4559 reference taken in a function up in the tree of inline clones.
4560 We need to find the duplicate that refers to our tree of
4563 gcc_assert (dst
->caller
->inlined_to
);
4564 for (dst_rdesc
= src_rdesc
->next_duplicate
;
4566 dst_rdesc
= dst_rdesc
->next_duplicate
)
4568 struct cgraph_node
*top
;
4569 top
= dst_rdesc
->cs
->caller
->inlined_to
4570 ? dst_rdesc
->cs
->caller
->inlined_to
4571 : dst_rdesc
->cs
->caller
;
4572 if (dst
->caller
->inlined_to
== top
)
4575 gcc_assert (dst_rdesc
);
4576 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
4579 else if (dst_jf
->type
== IPA_JF_PASS_THROUGH
4580 && src
->caller
== dst
->caller
)
4582 struct cgraph_node
*inline_root
= dst
->caller
->inlined_to
4583 ? dst
->caller
->inlined_to
: dst
->caller
;
4584 ipa_node_params
*root_info
= ipa_node_params_sum
->get (inline_root
);
4585 int idx
= ipa_get_jf_pass_through_formal_id (dst_jf
);
4587 int c
= ipa_get_controlled_uses (root_info
, idx
);
4588 if (c
!= IPA_UNDESCRIBED_USE
)
4591 ipa_set_controlled_uses (root_info
, idx
, c
);
4597 /* Analyze newly added function into callgraph. */
4600 ipa_add_new_function (cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
4602 if (node
->has_gimple_body_p ())
4603 ipa_analyze_node (node
);
4606 /* Hook that is called by summary when a node is duplicated. */
4609 ipa_node_params_t::duplicate(cgraph_node
*, cgraph_node
*,
4610 ipa_node_params
*old_info
,
4611 ipa_node_params
*new_info
)
4613 new_info
->descriptors
= vec_safe_copy (old_info
->descriptors
);
4614 gcc_assert (new_info
->lattices
.is_empty ());
4615 new_info
->ipcp_orig_node
= old_info
->ipcp_orig_node
;
4616 new_info
->known_csts
= old_info
->known_csts
.copy ();
4617 new_info
->known_contexts
= old_info
->known_contexts
.copy ();
4619 new_info
->analysis_done
= old_info
->analysis_done
;
4620 new_info
->node_enqueued
= old_info
->node_enqueued
;
4621 new_info
->versionable
= old_info
->versionable
;
4624 /* Duplication of ipcp transformation summaries. */
4627 ipcp_transformation_t::duplicate(cgraph_node
*, cgraph_node
*dst
,
4628 ipcp_transformation
*src_trans
,
4629 ipcp_transformation
*dst_trans
)
4631 /* Avoid redundant work of duplicating vectors we will never use. */
4632 if (dst
->inlined_to
)
4634 dst_trans
->m_agg_values
= vec_safe_copy (src_trans
->m_agg_values
);
4635 dst_trans
->m_vr
= vec_safe_copy (src_trans
->m_vr
);
4638 /* Register our cgraph hooks if they are not already there. */
4641 ipa_register_cgraph_hooks (void)
4643 ipa_check_create_node_params ();
4644 ipa_check_create_edge_args ();
4646 function_insertion_hook_holder
=
4647 symtab
->add_cgraph_insertion_hook (&ipa_add_new_function
, NULL
);
4650 /* Unregister our cgraph hooks if they are not already there. */
4653 ipa_unregister_cgraph_hooks (void)
4655 if (function_insertion_hook_holder
)
4656 symtab
->remove_cgraph_insertion_hook (function_insertion_hook_holder
);
4657 function_insertion_hook_holder
= NULL
;
4660 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4661 longer needed after ipa-cp. */
4664 ipa_free_all_structures_after_ipa_cp (void)
4666 if (!optimize
&& !in_lto_p
)
4668 ipa_free_all_edge_args ();
4669 ipa_free_all_node_params ();
4670 ipcp_sources_pool
.release ();
4671 ipcp_cst_values_pool
.release ();
4672 ipcp_poly_ctx_values_pool
.release ();
4673 ipcp_agg_lattice_pool
.release ();
4674 ipa_unregister_cgraph_hooks ();
4675 ipa_refdesc_pool
.release ();
4679 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4680 longer needed after indirect inlining. */
4683 ipa_free_all_structures_after_iinln (void)
4685 ipa_free_all_edge_args ();
4686 ipa_free_all_node_params ();
4687 ipa_unregister_cgraph_hooks ();
4688 ipcp_sources_pool
.release ();
4689 ipcp_cst_values_pool
.release ();
4690 ipcp_poly_ctx_values_pool
.release ();
4691 ipcp_agg_lattice_pool
.release ();
4692 ipa_refdesc_pool
.release ();
4695 /* Print ipa_tree_map data structures of all functions in the
4699 ipa_print_node_params (FILE *f
, struct cgraph_node
*node
)
4702 class ipa_node_params
*info
;
4704 if (!node
->definition
)
4706 info
= ipa_node_params_sum
->get (node
);
4707 fprintf (f
, " function %s parameter descriptors:\n", node
->dump_name ());
4710 fprintf (f
, " no params return\n");
4713 count
= ipa_get_param_count (info
);
4714 for (i
= 0; i
< count
; i
++)
4719 ipa_dump_param (f
, info
, i
);
4720 if (ipa_is_param_used (info
, i
))
4721 fprintf (f
, " used");
4722 if (ipa_is_param_used_by_ipa_predicates (info
, i
))
4723 fprintf (f
, " used_by_ipa_predicates");
4724 if (ipa_is_param_used_by_indirect_call (info
, i
))
4725 fprintf (f
, " used_by_indirect_call");
4726 if (ipa_is_param_used_by_polymorphic_call (info
, i
))
4727 fprintf (f
, " used_by_polymorphic_call");
4728 c
= ipa_get_controlled_uses (info
, i
);
4729 if (c
== IPA_UNDESCRIBED_USE
)
4730 fprintf (f
, " undescribed_use");
4732 fprintf (f
, " controlled_uses=%i %s", c
,
4733 ipa_get_param_load_dereferenced (info
, i
)
4734 ? "(load_dereferenced)" : "");
4739 /* Print ipa_tree_map data structures of all functions in the
4743 ipa_print_all_params (FILE * f
)
4745 struct cgraph_node
*node
;
4747 fprintf (f
, "\nFunction parameters:\n");
4748 FOR_EACH_FUNCTION (node
)
4749 ipa_print_node_params (f
, node
);
4752 /* Stream out jump function JUMP_FUNC to OB. */
4755 ipa_write_jump_function (struct output_block
*ob
,
4756 struct ipa_jump_func
*jump_func
)
4758 struct ipa_agg_jf_item
*item
;
4759 struct bitpack_d bp
;
4763 /* ADDR_EXPRs are very comon IP invariants; save some streamer data
4764 as well as WPA memory by handling them specially. */
4765 if (jump_func
->type
== IPA_JF_CONST
4766 && TREE_CODE (jump_func
->value
.constant
.value
) == ADDR_EXPR
)
4769 streamer_write_uhwi (ob
, jump_func
->type
* 2 + flag
);
4770 switch (jump_func
->type
)
4772 case IPA_JF_UNKNOWN
:
4776 EXPR_LOCATION (jump_func
->value
.constant
.value
) == UNKNOWN_LOCATION
);
4777 stream_write_tree (ob
,
4779 ? TREE_OPERAND (jump_func
->value
.constant
.value
, 0)
4780 : jump_func
->value
.constant
.value
, true);
4782 case IPA_JF_PASS_THROUGH
:
4783 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.operation
);
4784 if (jump_func
->value
.pass_through
.operation
== NOP_EXPR
)
4786 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4787 bp
= bitpack_create (ob
->main_stream
);
4788 bp_pack_value (&bp
, jump_func
->value
.pass_through
.agg_preserved
, 1);
4789 gcc_assert (!jump_func
->value
.pass_through
.refdesc_decremented
);
4790 streamer_write_bitpack (&bp
);
4792 else if (TREE_CODE_CLASS (jump_func
->value
.pass_through
.operation
)
4794 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4797 stream_write_tree (ob
, jump_func
->value
.pass_through
.operand
, true);
4798 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4801 case IPA_JF_ANCESTOR
:
4802 streamer_write_uhwi (ob
, jump_func
->value
.ancestor
.offset
);
4803 streamer_write_uhwi (ob
, jump_func
->value
.ancestor
.formal_id
);
4804 bp
= bitpack_create (ob
->main_stream
);
4805 bp_pack_value (&bp
, jump_func
->value
.ancestor
.agg_preserved
, 1);
4806 bp_pack_value (&bp
, jump_func
->value
.ancestor
.keep_null
, 1);
4807 streamer_write_bitpack (&bp
);
4810 fatal_error (UNKNOWN_LOCATION
, "invalid jump function in LTO stream");
4813 count
= vec_safe_length (jump_func
->agg
.items
);
4814 streamer_write_uhwi (ob
, count
);
4817 bp
= bitpack_create (ob
->main_stream
);
4818 bp_pack_value (&bp
, jump_func
->agg
.by_ref
, 1);
4819 streamer_write_bitpack (&bp
);
4822 FOR_EACH_VEC_SAFE_ELT (jump_func
->agg
.items
, i
, item
)
4824 stream_write_tree (ob
, item
->type
, true);
4825 streamer_write_uhwi (ob
, item
->offset
);
4826 streamer_write_uhwi (ob
, item
->jftype
);
4827 switch (item
->jftype
)
4829 case IPA_JF_UNKNOWN
:
4832 stream_write_tree (ob
, item
->value
.constant
, true);
4834 case IPA_JF_PASS_THROUGH
:
4835 case IPA_JF_LOAD_AGG
:
4836 streamer_write_uhwi (ob
, item
->value
.pass_through
.operation
);
4837 streamer_write_uhwi (ob
, item
->value
.pass_through
.formal_id
);
4838 if (TREE_CODE_CLASS (item
->value
.pass_through
.operation
)
4840 stream_write_tree (ob
, item
->value
.pass_through
.operand
, true);
4841 if (item
->jftype
== IPA_JF_LOAD_AGG
)
4843 stream_write_tree (ob
, item
->value
.load_agg
.type
, true);
4844 streamer_write_uhwi (ob
, item
->value
.load_agg
.offset
);
4845 bp
= bitpack_create (ob
->main_stream
);
4846 bp_pack_value (&bp
, item
->value
.load_agg
.by_ref
, 1);
4847 streamer_write_bitpack (&bp
);
4851 fatal_error (UNKNOWN_LOCATION
,
4852 "invalid jump function in LTO stream");
4856 bp
= bitpack_create (ob
->main_stream
);
4857 if (jump_func
->m_vr
)
4858 jump_func
->m_vr
->streamer_write (ob
);
4861 bp_pack_value (&bp
, false, 1);
4862 streamer_write_bitpack (&bp
);
4866 /* Read in jump function JUMP_FUNC from IB. */
4869 ipa_read_jump_function (class lto_input_block
*ib
,
4870 struct ipa_jump_func
*jump_func
,
4871 struct cgraph_edge
*cs
,
4872 class data_in
*data_in
,
4875 enum jump_func_type jftype
;
4876 enum tree_code operation
;
4878 int val
= streamer_read_uhwi (ib
);
4879 bool flag
= val
& 1;
4881 jftype
= (enum jump_func_type
) (val
/ 2);
4884 case IPA_JF_UNKNOWN
:
4885 ipa_set_jf_unknown (jump_func
);
4889 tree t
= stream_read_tree (ib
, data_in
);
4890 if (flag
&& prevails
)
4891 t
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
4892 ipa_set_jf_constant (jump_func
, t
, cs
);
4895 case IPA_JF_PASS_THROUGH
:
4896 operation
= (enum tree_code
) streamer_read_uhwi (ib
);
4897 if (operation
== NOP_EXPR
)
4899 int formal_id
= streamer_read_uhwi (ib
);
4900 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4901 bool agg_preserved
= bp_unpack_value (&bp
, 1);
4902 ipa_set_jf_simple_pass_through (jump_func
, formal_id
, agg_preserved
);
4904 else if (TREE_CODE_CLASS (operation
) == tcc_unary
)
4906 int formal_id
= streamer_read_uhwi (ib
);
4907 ipa_set_jf_unary_pass_through (jump_func
, formal_id
, operation
);
4911 tree operand
= stream_read_tree (ib
, data_in
);
4912 int formal_id
= streamer_read_uhwi (ib
);
4913 ipa_set_jf_arith_pass_through (jump_func
, formal_id
, operand
,
4917 case IPA_JF_ANCESTOR
:
4919 HOST_WIDE_INT offset
= streamer_read_uhwi (ib
);
4920 int formal_id
= streamer_read_uhwi (ib
);
4921 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4922 bool agg_preserved
= bp_unpack_value (&bp
, 1);
4923 bool keep_null
= bp_unpack_value (&bp
, 1);
4924 ipa_set_ancestor_jf (jump_func
, offset
, formal_id
, agg_preserved
,
4929 fatal_error (UNKNOWN_LOCATION
, "invalid jump function in LTO stream");
4932 count
= streamer_read_uhwi (ib
);
4935 jump_func
->agg
.items
= NULL
;
4936 vec_safe_reserve (jump_func
->agg
.items
, count
, true);
4940 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4941 jump_func
->agg
.by_ref
= bp_unpack_value (&bp
, 1);
4943 for (i
= 0; i
< count
; i
++)
4945 struct ipa_agg_jf_item item
;
4946 item
.type
= stream_read_tree (ib
, data_in
);
4947 item
.offset
= streamer_read_uhwi (ib
);
4948 item
.jftype
= (enum jump_func_type
) streamer_read_uhwi (ib
);
4950 switch (item
.jftype
)
4952 case IPA_JF_UNKNOWN
:
4955 item
.value
.constant
= stream_read_tree (ib
, data_in
);
4957 case IPA_JF_PASS_THROUGH
:
4958 case IPA_JF_LOAD_AGG
:
4959 operation
= (enum tree_code
) streamer_read_uhwi (ib
);
4960 item
.value
.pass_through
.operation
= operation
;
4961 item
.value
.pass_through
.formal_id
= streamer_read_uhwi (ib
);
4962 if (TREE_CODE_CLASS (operation
) == tcc_unary
)
4963 item
.value
.pass_through
.operand
= NULL_TREE
;
4965 item
.value
.pass_through
.operand
= stream_read_tree (ib
, data_in
);
4966 if (item
.jftype
== IPA_JF_LOAD_AGG
)
4968 struct bitpack_d bp
;
4969 item
.value
.load_agg
.type
= stream_read_tree (ib
, data_in
);
4970 item
.value
.load_agg
.offset
= streamer_read_uhwi (ib
);
4971 bp
= streamer_read_bitpack (ib
);
4972 item
.value
.load_agg
.by_ref
= bp_unpack_value (&bp
, 1);
4976 fatal_error (UNKNOWN_LOCATION
,
4977 "invalid jump function in LTO stream");
4980 jump_func
->agg
.items
->quick_push (item
);
4984 vr
.streamer_read (ib
, data_in
);
4988 ipa_set_jfunc_vr (jump_func
, vr
);
4991 jump_func
->m_vr
= NULL
;
4994 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
4995 relevant to indirect inlining to OB. */
4998 ipa_write_indirect_edge_info (struct output_block
*ob
,
4999 struct cgraph_edge
*cs
)
5001 class cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
5002 struct bitpack_d bp
;
5004 streamer_write_hwi (ob
, ii
->param_index
);
5005 bp
= bitpack_create (ob
->main_stream
);
5006 bp_pack_value (&bp
, ii
->polymorphic
, 1);
5007 bp_pack_value (&bp
, ii
->agg_contents
, 1);
5008 bp_pack_value (&bp
, ii
->member_ptr
, 1);
5009 bp_pack_value (&bp
, ii
->by_ref
, 1);
5010 bp_pack_value (&bp
, ii
->guaranteed_unmodified
, 1);
5011 bp_pack_value (&bp
, ii
->vptr_changed
, 1);
5012 streamer_write_bitpack (&bp
);
5013 if (ii
->agg_contents
|| ii
->polymorphic
)
5014 streamer_write_hwi (ob
, ii
->offset
);
5016 gcc_assert (ii
->offset
== 0);
5018 if (ii
->polymorphic
)
5020 streamer_write_hwi (ob
, ii
->otr_token
);
5021 stream_write_tree (ob
, ii
->otr_type
, true);
5022 ii
->context
.stream_out (ob
);
5026 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
5027 relevant to indirect inlining from IB. */
5030 ipa_read_indirect_edge_info (class lto_input_block
*ib
,
5031 class data_in
*data_in
,
5032 struct cgraph_edge
*cs
,
5033 class ipa_node_params
*info
)
5035 class cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
5036 struct bitpack_d bp
;
5038 ii
->param_index
= (int) streamer_read_hwi (ib
);
5039 bp
= streamer_read_bitpack (ib
);
5040 ii
->polymorphic
= bp_unpack_value (&bp
, 1);
5041 ii
->agg_contents
= bp_unpack_value (&bp
, 1);
5042 ii
->member_ptr
= bp_unpack_value (&bp
, 1);
5043 ii
->by_ref
= bp_unpack_value (&bp
, 1);
5044 ii
->guaranteed_unmodified
= bp_unpack_value (&bp
, 1);
5045 ii
->vptr_changed
= bp_unpack_value (&bp
, 1);
5046 if (ii
->agg_contents
|| ii
->polymorphic
)
5047 ii
->offset
= (HOST_WIDE_INT
) streamer_read_hwi (ib
);
5050 if (ii
->polymorphic
)
5052 ii
->otr_token
= (HOST_WIDE_INT
) streamer_read_hwi (ib
);
5053 ii
->otr_type
= stream_read_tree (ib
, data_in
);
5054 ii
->context
.stream_in (ib
, data_in
);
5056 if (info
&& ii
->param_index
>= 0)
5058 if (ii
->polymorphic
)
5059 ipa_set_param_used_by_polymorphic_call (info
,
5060 ii
->param_index
, true);
5061 ipa_set_param_used_by_indirect_call (info
,
5062 ii
->param_index
, true);
5066 /* Stream out NODE info to OB. */
5069 ipa_write_node_info (struct output_block
*ob
, struct cgraph_node
*node
)
5072 lto_symtab_encoder_t encoder
;
5073 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
5075 struct cgraph_edge
*e
;
5076 struct bitpack_d bp
;
5078 encoder
= ob
->decl_state
->symtab_node_encoder
;
5079 node_ref
= lto_symtab_encoder_encode (encoder
, node
);
5080 streamer_write_uhwi (ob
, node_ref
);
5082 streamer_write_uhwi (ob
, ipa_get_param_count (info
));
5083 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
5084 streamer_write_uhwi (ob
, ipa_get_param_move_cost (info
, j
));
5085 bp
= bitpack_create (ob
->main_stream
);
5086 gcc_assert (info
->analysis_done
5087 || ipa_get_param_count (info
) == 0);
5088 gcc_assert (!info
->node_enqueued
);
5089 gcc_assert (!info
->ipcp_orig_node
);
5090 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
5092 /* TODO: We could just not stream the bit in the undescribed case. */
5093 bool d
= (ipa_get_controlled_uses (info
, j
) != IPA_UNDESCRIBED_USE
)
5094 ? ipa_get_param_load_dereferenced (info
, j
) : true;
5095 bp_pack_value (&bp
, d
, 1);
5096 bp_pack_value (&bp
, ipa_is_param_used (info
, j
), 1);
5098 streamer_write_bitpack (&bp
);
5099 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
5101 streamer_write_hwi (ob
, ipa_get_controlled_uses (info
, j
));
5102 stream_write_tree (ob
, ipa_get_type (info
, j
), true);
5104 for (e
= node
->callees
; e
; e
= e
->next_callee
)
5106 ipa_edge_args
*args
= ipa_edge_args_sum
->get (e
);
5110 streamer_write_uhwi (ob
, 0);
5114 streamer_write_uhwi (ob
,
5115 ipa_get_cs_argument_count (args
) * 2
5116 + (args
->polymorphic_call_contexts
!= NULL
));
5117 for (j
= 0; j
< ipa_get_cs_argument_count (args
); j
++)
5119 ipa_write_jump_function (ob
, ipa_get_ith_jump_func (args
, j
));
5120 if (args
->polymorphic_call_contexts
!= NULL
)
5121 ipa_get_ith_polymorhic_call_context (args
, j
)->stream_out (ob
);
5124 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
5126 ipa_edge_args
*args
= ipa_edge_args_sum
->get (e
);
5128 streamer_write_uhwi (ob
, 0);
5131 streamer_write_uhwi (ob
,
5132 ipa_get_cs_argument_count (args
) * 2
5133 + (args
->polymorphic_call_contexts
!= NULL
));
5134 for (j
= 0; j
< ipa_get_cs_argument_count (args
); j
++)
5136 ipa_write_jump_function (ob
, ipa_get_ith_jump_func (args
, j
));
5137 if (args
->polymorphic_call_contexts
!= NULL
)
5138 ipa_get_ith_polymorhic_call_context (args
, j
)->stream_out (ob
);
5141 ipa_write_indirect_edge_info (ob
, e
);
5145 /* Stream in edge E from IB. */
5148 ipa_read_edge_info (class lto_input_block
*ib
,
5149 class data_in
*data_in
,
5150 struct cgraph_edge
*e
, bool prevails
)
5152 int count
= streamer_read_uhwi (ib
);
5153 bool contexts_computed
= count
& 1;
5159 && (e
->possibly_call_in_translation_unit_p ()
5160 /* Also stream in jump functions to builtins in hope that they
5161 will get fnspecs. */
5162 || fndecl_built_in_p (e
->callee
->decl
, BUILT_IN_NORMAL
)))
5164 ipa_edge_args
*args
= ipa_edge_args_sum
->get_create (e
);
5165 vec_safe_grow_cleared (args
->jump_functions
, count
, true);
5166 if (contexts_computed
)
5167 vec_safe_grow_cleared (args
->polymorphic_call_contexts
, count
, true);
5168 for (int k
= 0; k
< count
; k
++)
5170 ipa_read_jump_function (ib
, ipa_get_ith_jump_func (args
, k
), e
,
5172 if (contexts_computed
)
5173 ipa_get_ith_polymorhic_call_context (args
, k
)->stream_in
5179 for (int k
= 0; k
< count
; k
++)
5181 struct ipa_jump_func dummy
;
5182 ipa_read_jump_function (ib
, &dummy
, e
,
5184 if (contexts_computed
)
5186 class ipa_polymorphic_call_context ctx
;
5187 ctx
.stream_in (ib
, data_in
);
5193 /* Stream in NODE info from IB. */
5196 ipa_read_node_info (class lto_input_block
*ib
, struct cgraph_node
*node
,
5197 class data_in
*data_in
)
5200 struct cgraph_edge
*e
;
5201 struct bitpack_d bp
;
5202 bool prevails
= node
->prevailing_p ();
5203 ipa_node_params
*info
5204 = prevails
? ipa_node_params_sum
->get_create (node
) : NULL
;
5206 int param_count
= streamer_read_uhwi (ib
);
5209 ipa_alloc_node_params (node
, param_count
);
5210 for (k
= 0; k
< param_count
; k
++)
5211 (*info
->descriptors
)[k
].move_cost
= streamer_read_uhwi (ib
);
5212 if (ipa_get_param_count (info
) != 0)
5213 info
->analysis_done
= true;
5214 info
->node_enqueued
= false;
5217 for (k
= 0; k
< param_count
; k
++)
5218 streamer_read_uhwi (ib
);
5220 bp
= streamer_read_bitpack (ib
);
5221 for (k
= 0; k
< param_count
; k
++)
5223 bool load_dereferenced
= bp_unpack_value (&bp
, 1);
5224 bool used
= bp_unpack_value (&bp
, 1);
5228 ipa_set_param_load_dereferenced (info
, k
, load_dereferenced
);
5229 ipa_set_param_used (info
, k
, used
);
5232 for (k
= 0; k
< param_count
; k
++)
5234 int nuses
= streamer_read_hwi (ib
);
5235 tree type
= stream_read_tree (ib
, data_in
);
5239 ipa_set_controlled_uses (info
, k
, nuses
);
5240 (*info
->descriptors
)[k
].decl_or_type
= type
;
5243 for (e
= node
->callees
; e
; e
= e
->next_callee
)
5244 ipa_read_edge_info (ib
, data_in
, e
, prevails
);
5245 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
5247 ipa_read_edge_info (ib
, data_in
, e
, prevails
);
5248 ipa_read_indirect_edge_info (ib
, data_in
, e
, info
);
5252 /* Write jump functions for nodes in SET. */
5255 ipa_prop_write_jump_functions (void)
5257 struct output_block
*ob
;
5258 unsigned int count
= 0;
5259 lto_symtab_encoder_iterator lsei
;
5260 lto_symtab_encoder_t encoder
;
5262 if (!ipa_node_params_sum
|| !ipa_edge_args_sum
)
5265 ob
= create_output_block (LTO_section_jump_functions
);
5266 encoder
= ob
->decl_state
->symtab_node_encoder
;
5268 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5269 lsei_next_function_in_partition (&lsei
))
5271 cgraph_node
*node
= lsei_cgraph_node (lsei
);
5272 if (node
->has_gimple_body_p ()
5273 && ipa_node_params_sum
->get (node
) != NULL
)
5277 streamer_write_uhwi (ob
, count
);
5279 /* Process all of the functions. */
5280 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5281 lsei_next_function_in_partition (&lsei
))
5283 cgraph_node
*node
= lsei_cgraph_node (lsei
);
5284 if (node
->has_gimple_body_p ()
5285 && ipa_node_params_sum
->get (node
) != NULL
)
5286 ipa_write_node_info (ob
, node
);
5288 streamer_write_char_stream (ob
->main_stream
, 0);
5289 produce_asm (ob
, NULL
);
5290 destroy_output_block (ob
);
5293 /* Read section in file FILE_DATA of length LEN with data DATA. */
5296 ipa_prop_read_section (struct lto_file_decl_data
*file_data
, const char *data
,
5299 const struct lto_function_header
*header
=
5300 (const struct lto_function_header
*) data
;
5301 const int cfg_offset
= sizeof (struct lto_function_header
);
5302 const int main_offset
= cfg_offset
+ header
->cfg_size
;
5303 const int string_offset
= main_offset
+ header
->main_size
;
5304 class data_in
*data_in
;
5308 lto_input_block
ib_main ((const char *) data
+ main_offset
,
5309 header
->main_size
, file_data
);
5312 lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
5313 header
->string_size
, vNULL
);
5314 count
= streamer_read_uhwi (&ib_main
);
5316 for (i
= 0; i
< count
; i
++)
5319 struct cgraph_node
*node
;
5320 lto_symtab_encoder_t encoder
;
5322 index
= streamer_read_uhwi (&ib_main
);
5323 encoder
= file_data
->symtab_node_encoder
;
5324 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref (encoder
,
5326 gcc_assert (node
->definition
);
5327 ipa_read_node_info (&ib_main
, node
, data_in
);
5329 lto_free_section_data (file_data
, LTO_section_jump_functions
, NULL
, data
,
5331 lto_data_in_delete (data_in
);
5334 /* Read ipcp jump functions. */
5337 ipa_prop_read_jump_functions (void)
5339 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
5340 struct lto_file_decl_data
*file_data
;
5343 ipa_check_create_node_params ();
5344 ipa_check_create_edge_args ();
5345 ipa_register_cgraph_hooks ();
5347 while ((file_data
= file_data_vec
[j
++]))
5351 = lto_get_summary_section_data (file_data
, LTO_section_jump_functions
,
5354 ipa_prop_read_section (file_data
, data
, len
);
5358 /* Return true if the IPA-CP transformation summary TS is non-NULL and contains
5361 useful_ipcp_transformation_info_p (ipcp_transformation
*ts
)
5365 if (!vec_safe_is_empty (ts
->m_agg_values
)
5366 || !vec_safe_is_empty (ts
->m_vr
))
5371 /* Write into OB IPA-CP transfromation summary TS describing NODE. */
5374 write_ipcp_transformation_info (output_block
*ob
, cgraph_node
*node
,
5375 ipcp_transformation
*ts
)
5377 lto_symtab_encoder_t encoder
= ob
->decl_state
->symtab_node_encoder
;
5378 int node_ref
= lto_symtab_encoder_encode (encoder
, node
);
5379 streamer_write_uhwi (ob
, node_ref
);
5381 streamer_write_uhwi (ob
, vec_safe_length (ts
->m_agg_values
));
5382 for (const ipa_argagg_value
&av
: ts
->m_agg_values
)
5384 struct bitpack_d bp
;
5386 stream_write_tree (ob
, av
.value
, true);
5387 streamer_write_uhwi (ob
, av
.unit_offset
);
5388 streamer_write_uhwi (ob
, av
.index
);
5390 bp
= bitpack_create (ob
->main_stream
);
5391 bp_pack_value (&bp
, av
.by_ref
, 1);
5392 bp_pack_value (&bp
, av
.killed
, 1);
5393 streamer_write_bitpack (&bp
);
5396 streamer_write_uhwi (ob
, vec_safe_length (ts
->m_vr
));
5397 for (const ipa_vr
&parm_vr
: ts
->m_vr
)
5398 parm_vr
.streamer_write (ob
);
5401 /* Stream in the aggregate value replacement chain for NODE from IB. */
5404 read_ipcp_transformation_info (lto_input_block
*ib
, cgraph_node
*node
,
5407 unsigned int count
, i
;
5408 ipcp_transformation_initialize ();
5409 ipcp_transformation
*ts
= ipcp_transformation_sum
->get_create (node
);
5411 count
= streamer_read_uhwi (ib
);
5414 vec_safe_grow_cleared (ts
->m_agg_values
, count
, true);
5415 for (i
= 0; i
<count
; i
++)
5417 ipa_argagg_value
*av
= &(*ts
->m_agg_values
)[i
];;
5419 av
->value
= stream_read_tree (ib
, data_in
);
5420 av
->unit_offset
= streamer_read_uhwi (ib
);
5421 av
->index
= streamer_read_uhwi (ib
);
5423 bitpack_d bp
= streamer_read_bitpack (ib
);
5424 av
->by_ref
= bp_unpack_value (&bp
, 1);
5425 av
->killed
= bp_unpack_value (&bp
, 1);
5429 count
= streamer_read_uhwi (ib
);
5432 vec_safe_grow_cleared (ts
->m_vr
, count
, true);
5433 for (i
= 0; i
< count
; i
++)
5436 parm_vr
= &(*ts
->m_vr
)[i
];
5437 parm_vr
->streamer_read (ib
, data_in
);
5442 /* Write all aggregate replacement for nodes in set. */
5445 ipcp_write_transformation_summaries (void)
5447 struct output_block
*ob
;
5448 unsigned int count
= 0;
5449 lto_symtab_encoder_t encoder
;
5451 ob
= create_output_block (LTO_section_ipcp_transform
);
5452 encoder
= ob
->decl_state
->symtab_node_encoder
;
5455 for (int i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
5457 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
5458 cgraph_node
*cnode
= dyn_cast
<cgraph_node
*> (snode
);
5461 ipcp_transformation
*ts
= ipcp_get_transformation_summary (cnode
);
5462 if (useful_ipcp_transformation_info_p (ts
)
5463 && lto_symtab_encoder_encode_body_p (encoder
, cnode
))
5467 streamer_write_uhwi (ob
, count
);
5469 for (int i
= 0; i
< lto_symtab_encoder_size (encoder
); i
++)
5471 symtab_node
*snode
= lto_symtab_encoder_deref (encoder
, i
);
5472 cgraph_node
*cnode
= dyn_cast
<cgraph_node
*> (snode
);
5475 ipcp_transformation
*ts
= ipcp_get_transformation_summary (cnode
);
5476 if (useful_ipcp_transformation_info_p (ts
)
5477 && lto_symtab_encoder_encode_body_p (encoder
, cnode
))
5478 write_ipcp_transformation_info (ob
, cnode
, ts
);
5480 streamer_write_char_stream (ob
->main_stream
, 0);
5481 produce_asm (ob
, NULL
);
5482 destroy_output_block (ob
);
5485 /* Read replacements section in file FILE_DATA of length LEN with data
5489 read_replacements_section (struct lto_file_decl_data
*file_data
,
5493 const struct lto_function_header
*header
=
5494 (const struct lto_function_header
*) data
;
5495 const int cfg_offset
= sizeof (struct lto_function_header
);
5496 const int main_offset
= cfg_offset
+ header
->cfg_size
;
5497 const int string_offset
= main_offset
+ header
->main_size
;
5498 class data_in
*data_in
;
5502 lto_input_block
ib_main ((const char *) data
+ main_offset
,
5503 header
->main_size
, file_data
);
5505 data_in
= lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
5506 header
->string_size
, vNULL
);
5507 count
= streamer_read_uhwi (&ib_main
);
5509 for (i
= 0; i
< count
; i
++)
5512 struct cgraph_node
*node
;
5513 lto_symtab_encoder_t encoder
;
5515 index
= streamer_read_uhwi (&ib_main
);
5516 encoder
= file_data
->symtab_node_encoder
;
5517 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref (encoder
,
5519 read_ipcp_transformation_info (&ib_main
, node
, data_in
);
5521 lto_free_section_data (file_data
, LTO_section_jump_functions
, NULL
, data
,
5523 lto_data_in_delete (data_in
);
5526 /* Read IPA-CP aggregate replacements. */
5529 ipcp_read_transformation_summaries (void)
5531 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
5532 struct lto_file_decl_data
*file_data
;
5535 while ((file_data
= file_data_vec
[j
++]))
5539 = lto_get_summary_section_data (file_data
, LTO_section_ipcp_transform
,
5542 read_replacements_section (file_data
, data
, len
);
5546 /* Adjust the aggregate replacements in TS to reflect any parameter removals
5547 which might have already taken place. If after adjustments there are no
5548 aggregate replacements left, the m_agg_values will be set to NULL. In other
5549 cases, it may be shrunk. */
5552 adjust_agg_replacement_values (cgraph_node
*node
, ipcp_transformation
*ts
)
5554 clone_info
*cinfo
= clone_info::get (node
);
5555 if (!cinfo
|| !cinfo
->param_adjustments
)
5558 auto_vec
<int, 16> new_indices
;
5559 cinfo
->param_adjustments
->get_updated_indices (&new_indices
);
5560 bool removed_item
= false;
5561 unsigned dst_index
= 0;
5562 unsigned count
= ts
->m_agg_values
->length ();
5563 for (unsigned i
= 0; i
< count
; i
++)
5565 ipa_argagg_value
*v
= &(*ts
->m_agg_values
)[i
];
5566 gcc_checking_assert (v
->index
>= 0);
5569 if ((unsigned) v
->index
< new_indices
.length ())
5570 new_idx
= new_indices
[v
->index
];
5576 (*ts
->m_agg_values
)[dst_index
] = *v
;
5580 removed_item
= true;
5585 ggc_free (ts
->m_agg_values
);
5586 ts
->m_agg_values
= NULL
;
5588 else if (removed_item
)
5589 ts
->m_agg_values
->truncate (dst_index
);
5594 /* Dominator walker driving the ipcp modification phase. */
5596 class ipcp_modif_dom_walker
: public dom_walker
5599 ipcp_modif_dom_walker (struct ipa_func_body_info
*fbi
,
5600 vec
<ipa_param_descriptor
, va_gc
> *descs
,
5601 ipcp_transformation
*ts
, bool *sc
)
5602 : dom_walker (CDI_DOMINATORS
), m_fbi (fbi
), m_descriptors (descs
),
5603 m_ts (ts
), m_something_changed (sc
) {}
5605 edge
before_dom_children (basic_block
) final override
;
5607 { return gimple_purge_all_dead_eh_edges (m_need_eh_cleanup
); }
5610 struct ipa_func_body_info
*m_fbi
;
5611 vec
<ipa_param_descriptor
, va_gc
> *m_descriptors
;
5612 ipcp_transformation
*m_ts
;
5613 bool *m_something_changed
;
5614 auto_bitmap m_need_eh_cleanup
;
5618 ipcp_modif_dom_walker::before_dom_children (basic_block bb
)
5620 gimple_stmt_iterator gsi
;
5621 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
5623 gimple
*stmt
= gsi_stmt (gsi
);
5625 HOST_WIDE_INT bit_offset
;
5630 if (!gimple_assign_load_p (stmt
))
5632 rhs
= gimple_assign_rhs1 (stmt
);
5633 if (!is_gimple_reg_type (TREE_TYPE (rhs
)))
5638 while (handled_component_p (t
))
5640 /* V_C_E can do things like convert an array of integers to one
5641 bigger integer and similar things we do not handle below. */
5642 if (TREE_CODE (t
) == VIEW_CONVERT_EXPR
)
5647 t
= TREE_OPERAND (t
, 0);
5652 if (!ipa_load_from_parm_agg (m_fbi
, m_descriptors
, stmt
, rhs
, &index
,
5653 &bit_offset
, &size
, &by_ref
))
5655 unsigned unit_offset
= bit_offset
/ BITS_PER_UNIT
;
5656 ipa_argagg_value_list
avl (m_ts
);
5657 tree v
= avl
.get_value (index
, unit_offset
, by_ref
);
5660 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v
))), size
))
5663 gcc_checking_assert (is_gimple_ip_invariant (v
));
5664 if (!useless_type_conversion_p (TREE_TYPE (rhs
), TREE_TYPE (v
)))
5666 if (fold_convertible_p (TREE_TYPE (rhs
), v
))
5667 val
= fold_build1 (NOP_EXPR
, TREE_TYPE (rhs
), v
);
5668 else if (TYPE_SIZE (TREE_TYPE (rhs
))
5669 == TYPE_SIZE (TREE_TYPE (v
)))
5670 val
= fold_build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (rhs
), v
);
5675 fprintf (dump_file
, " const ");
5676 print_generic_expr (dump_file
, v
);
5677 fprintf (dump_file
, " can't be converted to type of ");
5678 print_generic_expr (dump_file
, rhs
);
5679 fprintf (dump_file
, "\n");
5687 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5689 fprintf (dump_file
, "Modifying stmt:\n ");
5690 print_gimple_stmt (dump_file
, stmt
, 0);
5692 gimple_assign_set_rhs_from_tree (&gsi
, val
);
5695 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5697 fprintf (dump_file
, "into:\n ");
5698 print_gimple_stmt (dump_file
, stmt
, 0);
5699 fprintf (dump_file
, "\n");
5702 *m_something_changed
= true;
5703 if (maybe_clean_eh_stmt (stmt
))
5704 bitmap_set_bit (m_need_eh_cleanup
, bb
->index
);
5709 /* If IPA-CP discovered a constant in parameter PARM at OFFSET of a given SIZE
5710 - whether passed by reference or not is given by BY_REF - return that
5711 constant. Otherwise return NULL_TREE. The is supposed to be used only
5712 after clone materialization and transformation is done (because it asserts
5713 that killed constants have been pruned). */
5716 ipcp_get_aggregate_const (struct function
*func
, tree parm
, bool by_ref
,
5717 HOST_WIDE_INT bit_offset
, HOST_WIDE_INT bit_size
)
5719 cgraph_node
*node
= cgraph_node::get (func
->decl
);
5720 ipcp_transformation
*ts
= ipcp_get_transformation_summary (node
);
5722 if (!ts
|| !ts
->m_agg_values
)
5725 int index
= ts
->get_param_index (func
->decl
, parm
);
5729 ipa_argagg_value_list
avl (ts
);
5730 unsigned unit_offset
= bit_offset
/ BITS_PER_UNIT
;
5731 const ipa_argagg_value
*av
= avl
.get_elt (index
, unit_offset
);
5732 if (!av
|| av
->by_ref
!= by_ref
)
5734 gcc_assert (!av
->killed
);
5737 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v
))), bit_size
))
5743 /* Return true if we have recorded VALUE and MASK about PARM.
5744 Set VALUE and MASk accordingly. */
5747 ipcp_get_parm_bits (tree parm
, tree
*value
, widest_int
*mask
)
5749 cgraph_node
*cnode
= cgraph_node::get (current_function_decl
);
5750 ipcp_transformation
*ts
= ipcp_get_transformation_summary (cnode
);
5752 || vec_safe_length (ts
->m_vr
) == 0
5753 || !irange::supports_p (TREE_TYPE (parm
)))
5756 int i
= ts
->get_param_index (current_function_decl
, parm
);
5759 clone_info
*cinfo
= clone_info::get (cnode
);
5760 if (cinfo
&& cinfo
->param_adjustments
)
5762 i
= cinfo
->param_adjustments
->get_original_index (i
);
5767 vec
<ipa_vr
, va_gc
> &vr
= *ts
->m_vr
;
5768 if (!vr
[i
].known_p ())
5771 vr
[i
].get_vrange (tmp
);
5772 if (tmp
.undefined_p () || tmp
.varying_p ())
5774 irange
&r
= as_a
<irange
> (tmp
);
5775 irange_bitmask bm
= r
.get_bitmask ();
5776 *mask
= widest_int::from (bm
.mask (), TYPE_SIGN (TREE_TYPE (parm
)));
5777 *value
= wide_int_to_tree (TREE_TYPE (parm
), bm
.value ());
5781 /* Update value range of formal parameters of NODE as described in TS. */
5784 ipcp_update_vr (struct cgraph_node
*node
, ipcp_transformation
*ts
)
5786 if (vec_safe_is_empty (ts
->m_vr
))
5788 const vec
<ipa_vr
, va_gc
> &vr
= *ts
->m_vr
;
5789 unsigned count
= vr
.length ();
5793 auto_vec
<int, 16> new_indices
;
5794 bool need_remapping
= false;
5795 clone_info
*cinfo
= clone_info::get (node
);
5796 if (cinfo
&& cinfo
->param_adjustments
)
5798 cinfo
->param_adjustments
->get_updated_indices (&new_indices
);
5799 need_remapping
= true;
5801 auto_vec
<tree
, 16> parm_decls
;
5802 push_function_arg_decls (&parm_decls
, node
->decl
);
5804 for (unsigned i
= 0; i
< count
; ++i
)
5810 if (i
>= new_indices
.length ())
5812 remapped_idx
= new_indices
[i
];
5813 if (remapped_idx
< 0)
5819 parm
= parm_decls
[remapped_idx
];
5821 gcc_checking_assert (parm
);
5822 tree ddef
= ssa_default_def (DECL_STRUCT_FUNCTION (node
->decl
), parm
);
5824 if (!ddef
|| !is_gimple_reg (parm
))
5827 if (vr
[i
].known_p ())
5830 vr
[i
].get_vrange (tmp
);
5832 if (!tmp
.undefined_p () && !tmp
.varying_p ())
5836 fprintf (dump_file
, "Setting value range of param %u "
5837 "(now %i) ", i
, remapped_idx
);
5838 tmp
.dump (dump_file
);
5839 fprintf (dump_file
, "]\n");
5841 set_range_info (ddef
, tmp
);
5843 if (POINTER_TYPE_P (TREE_TYPE (parm
))
5844 && opt_for_fn (node
->decl
, flag_ipa_bit_cp
))
5846 irange
&r
= as_a
<irange
> (tmp
);
5847 irange_bitmask bm
= r
.get_bitmask ();
5848 unsigned tem
= bm
.mask ().to_uhwi ();
5849 unsigned HOST_WIDE_INT bitpos
= bm
.value ().to_uhwi ();
5850 unsigned align
= tem
& -tem
;
5851 unsigned misalign
= bitpos
& (align
- 1);
5858 "Adjusting mask for param %u to ", i
);
5859 print_hex (bm
.mask (), dump_file
);
5860 fprintf (dump_file
, "\n");
5865 "Adjusting align: %u, misalign: %u\n",
5868 unsigned old_align
, old_misalign
;
5869 struct ptr_info_def
*pi
= get_ptr_info (ddef
);
5870 bool old_known
= get_ptr_info_alignment (pi
, &old_align
,
5873 if (old_known
&& old_align
> align
)
5878 "But alignment was already %u.\n",
5880 if ((old_misalign
& (align
- 1)) != misalign
)
5882 "old_misalign (%u) and misalign "
5884 old_misalign
, misalign
);
5891 && ((misalign
& (old_align
- 1)) != old_misalign
))
5893 "old_misalign (%u) and misalign (%u) "
5895 old_misalign
, misalign
);
5897 set_ptr_info_alignment (pi
, align
, misalign
);
5900 else if (dump_file
&& INTEGRAL_TYPE_P (TREE_TYPE (parm
)))
5902 irange
&r
= as_a
<irange
> (tmp
);
5903 irange_bitmask bm
= r
.get_bitmask ();
5904 unsigned prec
= TYPE_PRECISION (TREE_TYPE (parm
));
5905 if (wi::ne_p (bm
.mask (), wi::shwi (-1, prec
)))
5908 "Adjusting mask for param %u to ", i
);
5909 print_hex (bm
.mask (), dump_file
);
5910 fprintf (dump_file
, "\n");
5918 /* IPCP transformation phase doing propagation of aggregate values. */
5921 ipcp_transform_function (struct cgraph_node
*node
)
5923 struct ipa_func_body_info fbi
;
5926 gcc_checking_assert (cfun
);
5927 gcc_checking_assert (current_function_decl
);
5930 fprintf (dump_file
, "Modification phase of node %s\n",
5931 node
->dump_name ());
5933 ipcp_transformation
*ts
= ipcp_get_transformation_summary (node
);
5935 || (vec_safe_is_empty (ts
->m_agg_values
)
5936 && vec_safe_is_empty (ts
->m_vr
)))
5939 ts
->maybe_create_parm_idx_map (cfun
->decl
);
5940 ipcp_update_vr (node
, ts
);
5941 if (vec_safe_is_empty (ts
->m_agg_values
))
5943 param_count
= count_formal_params (node
->decl
);
5944 if (param_count
== 0)
5947 adjust_agg_replacement_values (node
, ts
);
5948 if (vec_safe_is_empty (ts
->m_agg_values
))
5951 fprintf (dump_file
, " All affected aggregate parameters were either "
5952 "removed or converted into scalars, phase done.\n");
5957 fprintf (dump_file
, " Aggregate replacements:");
5958 ipa_argagg_value_list
avs (ts
);
5959 avs
.dump (dump_file
);
5964 fbi
.bb_infos
= vNULL
;
5965 fbi
.bb_infos
.safe_grow_cleared (last_basic_block_for_fn (cfun
), true);
5966 fbi
.param_count
= param_count
;
5967 fbi
.aa_walk_budget
= opt_for_fn (node
->decl
, param_ipa_max_aa_steps
);
5969 vec
<ipa_param_descriptor
, va_gc
> *descriptors
= NULL
;
5970 vec_safe_grow_cleared (descriptors
, param_count
, true);
5971 ipa_populate_param_decls (node
, *descriptors
);
5972 bool modified_mem_access
= false;
5973 calculate_dominance_info (CDI_DOMINATORS
);
5974 ipcp_modif_dom_walker
walker (&fbi
, descriptors
, ts
, &modified_mem_access
);
5975 walker
.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
5976 free_dominance_info (CDI_DOMINATORS
);
5977 bool cfg_changed
= walker
.cleanup_eh ();
5980 struct ipa_bb_info
*bi
;
5981 FOR_EACH_VEC_ELT (fbi
.bb_infos
, i
, bi
)
5982 free_ipa_bb_info (bi
);
5983 fbi
.bb_infos
.release ();
5985 ts
->remove_argaggs_if ([](const ipa_argagg_value
&v
)
5990 vec_free (descriptors
);
5992 delete_unreachable_blocks_update_callgraph (node
, false);
5994 return modified_mem_access
? TODO_update_ssa_only_virtuals
: 0;
5997 /* Record that current function return value range is VAL. */
6000 ipa_record_return_value_range (Value_Range val
)
6002 cgraph_node
*n
= cgraph_node::get (current_function_decl
);
6003 if (!ipa_return_value_sum
)
6005 if (!ipa_vr_hash_table
)
6006 ipa_vr_hash_table
= hash_table
<ipa_vr_ggc_hash_traits
>::create_ggc (37);
6007 ipa_return_value_sum
= new (ggc_alloc_no_dtor
<ipa_return_value_sum_t
> ())
6008 ipa_return_value_sum_t (symtab
, true);
6009 ipa_return_value_sum
->disable_insertion_hook ();
6011 ipa_return_value_sum
->get_create (n
)->vr
= ipa_get_value_range (val
);
6012 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
6014 fprintf (dump_file
, "Recording return range ");
6015 val
.dump (dump_file
);
6016 fprintf (dump_file
, "\n");
6020 /* Return true if value range of DECL is known and if so initialize RANGE. */
6023 ipa_return_value_range (Value_Range
&range
, tree decl
)
6025 cgraph_node
*n
= cgraph_node::get (decl
);
6026 if (!n
|| !ipa_return_value_sum
)
6028 enum availability avail
;
6029 n
= n
->ultimate_alias_target (&avail
);
6030 if (avail
< AVAIL_AVAILABLE
)
6032 if (n
->decl
!= decl
&& !useless_type_conversion_p (TREE_TYPE (decl
), TREE_TYPE (n
->decl
)))
6034 ipa_return_value_summary
*v
= ipa_return_value_sum
->get (n
);
6037 v
->vr
->get_vrange (range
);
6041 /* Reset all state within ipa-prop.cc so that we can rerun the compiler
6042 within the same process. For use by toplev::finalize. */
6045 ipa_prop_cc_finalize (void)
6047 if (function_insertion_hook_holder
)
6048 symtab
->remove_cgraph_insertion_hook (function_insertion_hook_holder
);
6049 function_insertion_hook_holder
= NULL
;
6051 if (ipa_edge_args_sum
)
6052 ggc_delete (ipa_edge_args_sum
);
6053 ipa_edge_args_sum
= NULL
;
6055 if (ipa_node_params_sum
)
6056 ggc_delete (ipa_node_params_sum
);
6057 ipa_node_params_sum
= NULL
;
6060 #include "gt-ipa-prop.h"