gccrs: rust-item: include rust-expr.h
[official-gcc.git] / gcc / ipa-prop.cc
blob83a181672738bcebe1a62ae35032d43b4d814246
1 /* Interprocedural analyses.
2 Copyright (C) 2005-2023 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
9 version.
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
14 for more details.
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/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "rtl.h"
25 #include "tree.h"
26 #include "gimple.h"
27 #include "alloc-pool.h"
28 #include "tree-pass.h"
29 #include "ssa.h"
30 #include "tree-streamer.h"
31 #include "cgraph.h"
32 #include "diagnostic.h"
33 #include "fold-const.h"
34 #include "gimple-iterator.h"
35 #include "gimple-fold.h"
36 #include "tree-eh.h"
37 #include "calls.h"
38 #include "stor-layout.h"
39 #include "print-tree.h"
40 #include "gimplify.h"
41 #include "gimplify-me.h"
42 #include "gimple-walk.h"
43 #include "symbol-summary.h"
44 #include "ipa-prop.h"
45 #include "tree-cfg.h"
46 #include "tree-dfa.h"
47 #include "tree-inline.h"
48 #include "ipa-fnsummary.h"
49 #include "gimple-pretty-print.h"
50 #include "ipa-utils.h"
51 #include "dbgcnt.h"
52 #include "domwalk.h"
53 #include "builtins.h"
54 #include "tree-cfgcleanup.h"
55 #include "options.h"
56 #include "symtab-clones.h"
57 #include "attr-fnspec.h"
58 #include "gimple-range.h"
60 /* Function summary where the parameter infos are actually stored. */
61 ipa_node_params_t *ipa_node_params_sum = NULL;
63 function_summary <ipcp_transformation *> *ipcp_transformation_sum = NULL;
65 /* Edge summary for IPA-CP edge information. */
66 ipa_edge_args_sum_t *ipa_edge_args_sum;
68 /* Traits for a hash table for reusing already existing ipa_bits. */
70 struct ipa_bit_ggc_hash_traits : public ggc_cache_remove <ipa_bits *>
72 typedef ipa_bits *value_type;
73 typedef ipa_bits *compare_type;
74 static hashval_t
75 hash (const ipa_bits *p)
77 hashval_t t = (hashval_t) p->value.to_shwi ();
78 return iterative_hash_host_wide_int (p->mask.to_shwi (), t);
80 static bool
81 equal (const ipa_bits *a, const ipa_bits *b)
83 return a->value == b->value && a->mask == b->mask;
85 static const bool empty_zero_p = true;
86 static void
87 mark_empty (ipa_bits *&p)
89 p = NULL;
91 static bool
92 is_empty (const ipa_bits *p)
94 return p == NULL;
96 static bool
97 is_deleted (const ipa_bits *p)
99 return p == reinterpret_cast<const ipa_bits *> (1);
101 static void
102 mark_deleted (ipa_bits *&p)
104 p = reinterpret_cast<ipa_bits *> (1);
108 /* Hash table for avoid repeated allocations of equal ipa_bits. */
109 static GTY ((cache)) hash_table<ipa_bit_ggc_hash_traits> *ipa_bits_hash_table;
111 /* Traits for a hash table for reusing value_ranges used for IPA. Note that
112 the equiv bitmap is not hashed and is expected to be NULL. */
114 struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <value_range *>
116 typedef value_range *value_type;
117 typedef value_range *compare_type;
118 static hashval_t
119 hash (const value_range *p)
121 inchash::hash hstate (p->kind ());
122 inchash::add_expr (p->min (), hstate);
123 inchash::add_expr (p->max (), hstate);
124 return hstate.end ();
126 static bool
127 equal (const value_range *a, const value_range *b)
129 return (types_compatible_p (a->type (), b->type ())
130 && *a == *b);
132 static const bool empty_zero_p = true;
133 static void
134 mark_empty (value_range *&p)
136 p = NULL;
138 static bool
139 is_empty (const value_range *p)
141 return p == NULL;
143 static bool
144 is_deleted (const value_range *p)
146 return p == reinterpret_cast<const value_range *> (1);
148 static void
149 mark_deleted (value_range *&p)
151 p = reinterpret_cast<value_range *> (1);
155 /* Hash table for avoid repeated allocations of equal value_ranges. */
156 static GTY ((cache)) hash_table<ipa_vr_ggc_hash_traits> *ipa_vr_hash_table;
158 /* Holders of ipa cgraph hooks: */
159 static struct cgraph_node_hook_list *function_insertion_hook_holder;
161 /* Description of a reference to an IPA constant. */
162 struct ipa_cst_ref_desc
164 /* Edge that corresponds to the statement which took the reference. */
165 struct cgraph_edge *cs;
166 /* Linked list of duplicates created when call graph edges are cloned. */
167 struct ipa_cst_ref_desc *next_duplicate;
168 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
169 if out of control. */
170 int refcount;
173 /* Allocation pool for reference descriptions. */
175 static object_allocator<ipa_cst_ref_desc> ipa_refdesc_pool
176 ("IPA-PROP ref descriptions");
178 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
179 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
181 static bool
182 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
184 tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
186 if (!fs_opts)
187 return false;
188 return !opt_for_fn (node->decl, optimize) || !opt_for_fn (node->decl, flag_ipa_cp);
191 /* Return index of the formal whose tree is PTREE in function which corresponds
192 to INFO. */
194 static int
195 ipa_get_param_decl_index_1 (vec<ipa_param_descriptor, va_gc> *descriptors,
196 tree ptree)
198 int i, count;
200 count = vec_safe_length (descriptors);
201 for (i = 0; i < count; i++)
202 if ((*descriptors)[i].decl_or_type == ptree)
203 return i;
205 return -1;
208 /* Return index of the formal whose tree is PTREE in function which corresponds
209 to INFO. */
212 ipa_get_param_decl_index (class ipa_node_params *info, tree ptree)
214 return ipa_get_param_decl_index_1 (info->descriptors, ptree);
217 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
218 NODE. */
220 static void
221 ipa_populate_param_decls (struct cgraph_node *node,
222 vec<ipa_param_descriptor, va_gc> &descriptors)
224 tree fndecl;
225 tree fnargs;
226 tree parm;
227 int param_num;
229 fndecl = node->decl;
230 gcc_assert (gimple_has_body_p (fndecl));
231 fnargs = DECL_ARGUMENTS (fndecl);
232 param_num = 0;
233 for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
235 descriptors[param_num].decl_or_type = parm;
236 unsigned int cost = estimate_move_cost (TREE_TYPE (parm), true);
237 descriptors[param_num].move_cost = cost;
238 /* Watch overflow, move_cost is a bitfield. */
239 gcc_checking_assert (cost == descriptors[param_num].move_cost);
240 param_num++;
244 /* Return how many formal parameters FNDECL has. */
247 count_formal_params (tree fndecl)
249 tree parm;
250 int count = 0;
251 gcc_assert (gimple_has_body_p (fndecl));
253 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
254 count++;
256 return count;
259 /* Return the declaration of Ith formal parameter of the function corresponding
260 to INFO. Note there is no setter function as this array is built just once
261 using ipa_initialize_node_params. */
263 void
264 ipa_dump_param (FILE *file, class ipa_node_params *info, int i)
266 fprintf (file, "param #%i", i);
267 if ((*info->descriptors)[i].decl_or_type)
269 fprintf (file, " ");
270 print_generic_expr (file, (*info->descriptors)[i].decl_or_type);
274 /* If necessary, allocate vector of parameter descriptors in info of NODE.
275 Return true if they were allocated, false if not. */
277 static bool
278 ipa_alloc_node_params (struct cgraph_node *node, int param_count)
280 ipa_node_params *info = ipa_node_params_sum->get_create (node);
282 if (!info->descriptors && param_count)
284 vec_safe_grow_cleared (info->descriptors, param_count, true);
285 return true;
287 else
288 return false;
291 /* Initialize the ipa_node_params structure associated with NODE by counting
292 the function parameters, creating the descriptors and populating their
293 param_decls. */
295 void
296 ipa_initialize_node_params (struct cgraph_node *node)
298 ipa_node_params *info = ipa_node_params_sum->get_create (node);
300 if (!info->descriptors
301 && ipa_alloc_node_params (node, count_formal_params (node->decl)))
302 ipa_populate_param_decls (node, *info->descriptors);
305 /* Print the jump functions associated with call graph edge CS to file F. */
307 static void
308 ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
310 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
311 int count = ipa_get_cs_argument_count (args);
313 for (int i = 0; i < count; i++)
315 struct ipa_jump_func *jump_func;
316 enum jump_func_type type;
318 jump_func = ipa_get_ith_jump_func (args, i);
319 type = jump_func->type;
321 fprintf (f, " param %d: ", i);
322 if (type == IPA_JF_UNKNOWN)
323 fprintf (f, "UNKNOWN\n");
324 else if (type == IPA_JF_CONST)
326 tree val = jump_func->value.constant.value;
327 fprintf (f, "CONST: ");
328 print_generic_expr (f, val);
329 if (TREE_CODE (val) == ADDR_EXPR
330 && TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL)
332 fprintf (f, " -> ");
333 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)));
335 fprintf (f, "\n");
337 else if (type == IPA_JF_PASS_THROUGH)
339 fprintf (f, "PASS THROUGH: ");
340 fprintf (f, "%d, op %s",
341 jump_func->value.pass_through.formal_id,
342 get_tree_code_name(jump_func->value.pass_through.operation));
343 if (jump_func->value.pass_through.operation != NOP_EXPR)
345 fprintf (f, " ");
346 print_generic_expr (f, jump_func->value.pass_through.operand);
348 if (jump_func->value.pass_through.agg_preserved)
349 fprintf (f, ", agg_preserved");
350 fprintf (f, "\n");
352 else if (type == IPA_JF_ANCESTOR)
354 fprintf (f, "ANCESTOR: ");
355 fprintf (f, "%d, offset " HOST_WIDE_INT_PRINT_DEC,
356 jump_func->value.ancestor.formal_id,
357 jump_func->value.ancestor.offset);
358 if (jump_func->value.ancestor.agg_preserved)
359 fprintf (f, ", agg_preserved");
360 if (jump_func->value.ancestor.keep_null)
361 fprintf (f, ", keep_null");
362 fprintf (f, "\n");
365 if (jump_func->agg.items)
367 struct ipa_agg_jf_item *item;
368 int j;
370 fprintf (f, " Aggregate passed by %s:\n",
371 jump_func->agg.by_ref ? "reference" : "value");
372 FOR_EACH_VEC_ELT (*jump_func->agg.items, j, item)
374 fprintf (f, " offset: " HOST_WIDE_INT_PRINT_DEC ", ",
375 item->offset);
376 fprintf (f, "type: ");
377 print_generic_expr (f, item->type);
378 fprintf (f, ", ");
379 if (item->jftype == IPA_JF_PASS_THROUGH)
380 fprintf (f, "PASS THROUGH: %d,",
381 item->value.pass_through.formal_id);
382 else if (item->jftype == IPA_JF_LOAD_AGG)
384 fprintf (f, "LOAD AGG: %d",
385 item->value.pass_through.formal_id);
386 fprintf (f, " [offset: " HOST_WIDE_INT_PRINT_DEC ", by %s],",
387 item->value.load_agg.offset,
388 item->value.load_agg.by_ref ? "reference"
389 : "value");
392 if (item->jftype == IPA_JF_PASS_THROUGH
393 || item->jftype == IPA_JF_LOAD_AGG)
395 fprintf (f, " op %s",
396 get_tree_code_name (item->value.pass_through.operation));
397 if (item->value.pass_through.operation != NOP_EXPR)
399 fprintf (f, " ");
400 print_generic_expr (f, item->value.pass_through.operand);
403 else if (item->jftype == IPA_JF_CONST)
405 fprintf (f, "CONST: ");
406 print_generic_expr (f, item->value.constant);
408 else if (item->jftype == IPA_JF_UNKNOWN)
409 fprintf (f, "UNKNOWN: " HOST_WIDE_INT_PRINT_DEC " bits",
410 tree_to_uhwi (TYPE_SIZE (item->type)));
411 fprintf (f, "\n");
415 class ipa_polymorphic_call_context *ctx
416 = ipa_get_ith_polymorhic_call_context (args, i);
417 if (ctx && !ctx->useless_p ())
419 fprintf (f, " Context: ");
420 ctx->dump (dump_file);
423 if (jump_func->bits)
425 fprintf (f, " value: ");
426 print_hex (jump_func->bits->value, f);
427 fprintf (f, ", mask: ");
428 print_hex (jump_func->bits->mask, f);
429 fprintf (f, "\n");
431 else
432 fprintf (f, " Unknown bits\n");
434 if (jump_func->m_vr)
436 fprintf (f, " VR ");
437 fprintf (f, "%s[",
438 (jump_func->m_vr->kind () == VR_ANTI_RANGE) ? "~" : "");
439 print_decs (wi::to_wide (jump_func->m_vr->min ()), f);
440 fprintf (f, ", ");
441 print_decs (wi::to_wide (jump_func->m_vr->max ()), f);
442 fprintf (f, "]\n");
444 else
445 fprintf (f, " Unknown VR\n");
450 /* Print the jump functions of all arguments on all call graph edges going from
451 NODE to file F. */
453 void
454 ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
456 struct cgraph_edge *cs;
458 fprintf (f, " Jump functions of caller %s:\n", node->dump_name ());
459 for (cs = node->callees; cs; cs = cs->next_callee)
462 fprintf (f, " callsite %s -> %s : \n",
463 node->dump_name (),
464 cs->callee->dump_name ());
465 if (!ipa_edge_args_info_available_for_edge_p (cs))
466 fprintf (f, " no arg info\n");
467 else
468 ipa_print_node_jump_functions_for_edge (f, cs);
471 for (cs = node->indirect_calls; cs; cs = cs->next_callee)
473 class cgraph_indirect_call_info *ii;
475 ii = cs->indirect_info;
476 if (ii->agg_contents)
477 fprintf (f, " indirect %s callsite, calling param %i, "
478 "offset " HOST_WIDE_INT_PRINT_DEC ", %s",
479 ii->member_ptr ? "member ptr" : "aggregate",
480 ii->param_index, ii->offset,
481 ii->by_ref ? "by reference" : "by_value");
482 else
483 fprintf (f, " indirect %s callsite, calling param %i, "
484 "offset " HOST_WIDE_INT_PRINT_DEC,
485 ii->polymorphic ? "polymorphic" : "simple", ii->param_index,
486 ii->offset);
488 if (cs->call_stmt)
490 fprintf (f, ", for stmt ");
491 print_gimple_stmt (f, cs->call_stmt, 0, TDF_SLIM);
493 else
494 fprintf (f, "\n");
495 if (ii->polymorphic)
496 ii->context.dump (f);
497 if (!ipa_edge_args_info_available_for_edge_p (cs))
498 fprintf (f, " no arg info\n");
499 else
500 ipa_print_node_jump_functions_for_edge (f, cs);
504 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
506 void
507 ipa_print_all_jump_functions (FILE *f)
509 struct cgraph_node *node;
511 fprintf (f, "\nJump functions:\n");
512 FOR_EACH_FUNCTION (node)
514 ipa_print_node_jump_functions (f, node);
518 /* Set jfunc to be a know-really nothing jump function. */
520 static void
521 ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
523 jfunc->type = IPA_JF_UNKNOWN;
526 /* Set JFUNC to be a copy of another jmp (to be used by jump function
527 combination code). The two functions will share their rdesc. */
529 static void
530 ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
531 struct ipa_jump_func *src)
534 gcc_checking_assert (src->type == IPA_JF_CONST);
535 dst->type = IPA_JF_CONST;
536 dst->value.constant = src->value.constant;
539 /* Set JFUNC to be a constant jmp function. */
541 static void
542 ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
543 struct cgraph_edge *cs)
545 jfunc->type = IPA_JF_CONST;
546 jfunc->value.constant.value = unshare_expr_without_location (constant);
548 if (TREE_CODE (constant) == ADDR_EXPR
549 && (TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL
550 || (TREE_CODE (TREE_OPERAND (constant, 0)) == VAR_DECL
551 && TREE_STATIC (TREE_OPERAND (constant, 0)))))
553 struct ipa_cst_ref_desc *rdesc;
555 rdesc = ipa_refdesc_pool.allocate ();
556 rdesc->cs = cs;
557 rdesc->next_duplicate = NULL;
558 rdesc->refcount = 1;
559 jfunc->value.constant.rdesc = rdesc;
561 else
562 jfunc->value.constant.rdesc = NULL;
565 /* Set JFUNC to be a simple pass-through jump function. */
566 static void
567 ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
568 bool agg_preserved)
570 jfunc->type = IPA_JF_PASS_THROUGH;
571 jfunc->value.pass_through.operand = NULL_TREE;
572 jfunc->value.pass_through.formal_id = formal_id;
573 jfunc->value.pass_through.operation = NOP_EXPR;
574 jfunc->value.pass_through.agg_preserved = agg_preserved;
577 /* Set JFUNC to be an unary pass through jump function. */
579 static void
580 ipa_set_jf_unary_pass_through (struct ipa_jump_func *jfunc, int formal_id,
581 enum tree_code operation)
583 jfunc->type = IPA_JF_PASS_THROUGH;
584 jfunc->value.pass_through.operand = NULL_TREE;
585 jfunc->value.pass_through.formal_id = formal_id;
586 jfunc->value.pass_through.operation = operation;
587 jfunc->value.pass_through.agg_preserved = false;
589 /* Set JFUNC to be an arithmetic pass through jump function. */
591 static void
592 ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
593 tree operand, enum tree_code operation)
595 jfunc->type = IPA_JF_PASS_THROUGH;
596 jfunc->value.pass_through.operand = unshare_expr_without_location (operand);
597 jfunc->value.pass_through.formal_id = formal_id;
598 jfunc->value.pass_through.operation = operation;
599 jfunc->value.pass_through.agg_preserved = false;
602 /* Set JFUNC to be an ancestor jump function. */
604 static void
605 ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
606 int formal_id, bool agg_preserved, bool keep_null)
608 jfunc->type = IPA_JF_ANCESTOR;
609 jfunc->value.ancestor.formal_id = formal_id;
610 jfunc->value.ancestor.offset = offset;
611 jfunc->value.ancestor.agg_preserved = agg_preserved;
612 jfunc->value.ancestor.keep_null = keep_null;
615 /* Get IPA BB information about the given BB. FBI is the context of analyzis
616 of this function body. */
618 static struct ipa_bb_info *
619 ipa_get_bb_info (struct ipa_func_body_info *fbi, basic_block bb)
621 gcc_checking_assert (fbi);
622 return &fbi->bb_infos[bb->index];
625 /* Structure to be passed in between detect_type_change and
626 check_stmt_for_type_change. */
628 struct prop_type_change_info
630 /* Offset into the object where there is the virtual method pointer we are
631 looking for. */
632 HOST_WIDE_INT offset;
633 /* The declaration or SSA_NAME pointer of the base that we are checking for
634 type change. */
635 tree object;
636 /* Set to true if dynamic type change has been detected. */
637 bool type_maybe_changed;
640 /* Return true if STMT can modify a virtual method table pointer.
642 This function makes special assumptions about both constructors and
643 destructors which are all the functions that are allowed to alter the VMT
644 pointers. It assumes that destructors begin with assignment into all VMT
645 pointers and that constructors essentially look in the following way:
647 1) The very first thing they do is that they call constructors of ancestor
648 sub-objects that have them.
650 2) Then VMT pointers of this and all its ancestors is set to new values
651 corresponding to the type corresponding to the constructor.
653 3) Only afterwards, other stuff such as constructor of member sub-objects
654 and the code written by the user is run. Only this may include calling
655 virtual functions, directly or indirectly.
657 There is no way to call a constructor of an ancestor sub-object in any
658 other way.
660 This means that we do not have to care whether constructors get the correct
661 type information because they will always change it (in fact, if we define
662 the type to be given by the VMT pointer, it is undefined).
664 The most important fact to derive from the above is that if, for some
665 statement in the section 3, we try to detect whether the dynamic type has
666 changed, we can safely ignore all calls as we examine the function body
667 backwards until we reach statements in section 2 because these calls cannot
668 be ancestor constructors or destructors (if the input is not bogus) and so
669 do not change the dynamic type (this holds true only for automatically
670 allocated objects but at the moment we devirtualize only these). We then
671 must detect that statements in section 2 change the dynamic type and can try
672 to derive the new type. That is enough and we can stop, we will never see
673 the calls into constructors of sub-objects in this code. Therefore we can
674 safely ignore all call statements that we traverse.
677 static bool
678 stmt_may_be_vtbl_ptr_store (gimple *stmt)
680 if (is_gimple_call (stmt))
681 return false;
682 if (gimple_clobber_p (stmt))
683 return false;
684 else if (is_gimple_assign (stmt))
686 tree lhs = gimple_assign_lhs (stmt);
688 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
690 if (flag_strict_aliasing
691 && !POINTER_TYPE_P (TREE_TYPE (lhs)))
692 return false;
694 if (TREE_CODE (lhs) == COMPONENT_REF
695 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
696 return false;
697 /* In the future we might want to use get_ref_base_and_extent to find
698 if there is a field corresponding to the offset and if so, proceed
699 almost like if it was a component ref. */
702 return true;
705 /* Callback of walk_aliased_vdefs and a helper function for detect_type_change
706 to check whether a particular statement may modify the virtual table
707 pointerIt stores its result into DATA, which points to a
708 prop_type_change_info structure. */
710 static bool
711 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
713 gimple *stmt = SSA_NAME_DEF_STMT (vdef);
714 struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
716 if (stmt_may_be_vtbl_ptr_store (stmt))
718 tci->type_maybe_changed = true;
719 return true;
721 else
722 return false;
725 /* See if ARG is PARAM_DECl describing instance passed by pointer
726 or reference in FUNCTION. Return false if the dynamic type may change
727 in between beggining of the function until CALL is invoked.
729 Generally functions are not allowed to change type of such instances,
730 but they call destructors. We assume that methods cannot destroy the THIS
731 pointer. Also as a special cases, constructor and destructors may change
732 type of the THIS pointer. */
734 static bool
735 param_type_may_change_p (tree function, tree arg, gimple *call)
737 /* Pure functions cannot do any changes on the dynamic type;
738 that require writting to memory. */
739 if (flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
740 return false;
741 /* We need to check if we are within inlined consturctor
742 or destructor (ideally we would have way to check that the
743 inline cdtor is actually working on ARG, but we don't have
744 easy tie on this, so punt on all non-pure cdtors.
745 We may also record the types of cdtors and once we know type
746 of the instance match them.
748 Also code unification optimizations may merge calls from
749 different blocks making return values unreliable. So
750 do nothing during late optimization. */
751 if (DECL_STRUCT_FUNCTION (function)->after_inlining)
752 return true;
753 if (TREE_CODE (arg) == SSA_NAME
754 && SSA_NAME_IS_DEFAULT_DEF (arg)
755 && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
757 /* Normal (non-THIS) argument. */
758 if ((SSA_NAME_VAR (arg) != DECL_ARGUMENTS (function)
759 || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE)
760 /* THIS pointer of an method - here we want to watch constructors
761 and destructors as those definitely may change the dynamic
762 type. */
763 || (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE
764 && !DECL_CXX_CONSTRUCTOR_P (function)
765 && !DECL_CXX_DESTRUCTOR_P (function)
766 && (SSA_NAME_VAR (arg) == DECL_ARGUMENTS (function))))
768 /* Walk the inline stack and watch out for ctors/dtors. */
769 for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
770 block = BLOCK_SUPERCONTEXT (block))
771 if (inlined_polymorphic_ctor_dtor_block_p (block, false))
772 return true;
773 return false;
776 return true;
779 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
780 callsite CALL) by looking for assignments to its virtual table pointer. If
781 it is, return true. ARG is the object itself (not a pointer
782 to it, unless dereferenced). BASE is the base of the memory access as
783 returned by get_ref_base_and_extent, as is the offset.
785 This is helper function for detect_type_change and detect_type_change_ssa
786 that does the heavy work which is usually unnecesary. */
788 static bool
789 detect_type_change_from_memory_writes (ipa_func_body_info *fbi, tree arg,
790 tree base, tree comp_type, gcall *call,
791 HOST_WIDE_INT offset)
793 struct prop_type_change_info tci;
794 ao_ref ao;
796 gcc_checking_assert (DECL_P (arg)
797 || TREE_CODE (arg) == MEM_REF
798 || handled_component_p (arg));
800 comp_type = TYPE_MAIN_VARIANT (comp_type);
802 /* Const calls cannot call virtual methods through VMT and so type changes do
803 not matter. */
804 if (!flag_devirtualize || !gimple_vuse (call)
805 /* Be sure expected_type is polymorphic. */
806 || !comp_type
807 || TREE_CODE (comp_type) != RECORD_TYPE
808 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))
809 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))))
810 return true;
812 if (fbi->aa_walk_budget == 0)
813 return false;
815 ao_ref_init (&ao, arg);
816 ao.base = base;
817 ao.offset = offset;
818 ao.size = POINTER_SIZE;
819 ao.max_size = ao.size;
821 tci.offset = offset;
822 tci.object = get_base_address (arg);
823 tci.type_maybe_changed = false;
825 int walked
826 = walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
827 &tci, NULL, NULL, fbi->aa_walk_budget);
828 if (walked >= 0)
829 fbi->aa_walk_budget -= walked;
830 else
831 fbi->aa_walk_budget = 0;
833 if (walked >= 0 && !tci.type_maybe_changed)
834 return false;
836 return true;
839 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
840 If it is, return true. ARG is the object itself (not a pointer
841 to it, unless dereferenced). BASE is the base of the memory access as
842 returned by get_ref_base_and_extent, as is the offset. */
844 static bool
845 detect_type_change (ipa_func_body_info *fbi, tree arg, tree base,
846 tree comp_type, gcall *call,
847 HOST_WIDE_INT offset)
849 if (!flag_devirtualize)
850 return false;
852 if (TREE_CODE (base) == MEM_REF
853 && !param_type_may_change_p (current_function_decl,
854 TREE_OPERAND (base, 0),
855 call))
856 return false;
857 return detect_type_change_from_memory_writes (fbi, arg, base, comp_type,
858 call, offset);
861 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
862 SSA name (its dereference will become the base and the offset is assumed to
863 be zero). */
865 static bool
866 detect_type_change_ssa (ipa_func_body_info *fbi, tree arg, tree comp_type,
867 gcall *call)
869 gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
870 if (!flag_devirtualize
871 || !POINTER_TYPE_P (TREE_TYPE (arg)))
872 return false;
874 if (!param_type_may_change_p (current_function_decl, arg, call))
875 return false;
877 arg = build2 (MEM_REF, ptr_type_node, arg,
878 build_int_cst (ptr_type_node, 0));
880 return detect_type_change_from_memory_writes (fbi, arg, arg, comp_type,
881 call, 0);
884 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
885 boolean variable pointed to by DATA. */
887 static bool
888 mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
889 void *data)
891 bool *b = (bool *) data;
892 *b = true;
893 return true;
896 /* Find the nearest valid aa status for parameter specified by INDEX that
897 dominates BB. */
899 static struct ipa_param_aa_status *
900 find_dominating_aa_status (struct ipa_func_body_info *fbi, basic_block bb,
901 int index)
903 while (true)
905 bb = get_immediate_dominator (CDI_DOMINATORS, bb);
906 if (!bb)
907 return NULL;
908 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
909 if (!bi->param_aa_statuses.is_empty ()
910 && bi->param_aa_statuses[index].valid)
911 return &bi->param_aa_statuses[index];
915 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
916 structures and/or intialize the result with a dominating description as
917 necessary. */
919 static struct ipa_param_aa_status *
920 parm_bb_aa_status_for_bb (struct ipa_func_body_info *fbi, basic_block bb,
921 int index)
923 gcc_checking_assert (fbi);
924 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
925 if (bi->param_aa_statuses.is_empty ())
926 bi->param_aa_statuses.safe_grow_cleared (fbi->param_count, true);
927 struct ipa_param_aa_status *paa = &bi->param_aa_statuses[index];
928 if (!paa->valid)
930 gcc_checking_assert (!paa->parm_modified
931 && !paa->ref_modified
932 && !paa->pt_modified);
933 struct ipa_param_aa_status *dom_paa;
934 dom_paa = find_dominating_aa_status (fbi, bb, index);
935 if (dom_paa)
936 *paa = *dom_paa;
937 else
938 paa->valid = true;
941 return paa;
944 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
945 a value known not to be modified in this function before reaching the
946 statement STMT. FBI holds information about the function we have so far
947 gathered but do not survive the summary building stage. */
949 static bool
950 parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index,
951 gimple *stmt, tree parm_load)
953 struct ipa_param_aa_status *paa;
954 bool modified = false;
955 ao_ref refd;
957 tree base = get_base_address (parm_load);
958 gcc_assert (TREE_CODE (base) == PARM_DECL);
959 if (TREE_READONLY (base))
960 return true;
962 gcc_checking_assert (fbi);
963 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
964 if (paa->parm_modified || fbi->aa_walk_budget == 0)
965 return false;
967 gcc_checking_assert (gimple_vuse (stmt) != NULL_TREE);
968 ao_ref_init (&refd, parm_load);
969 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
970 &modified, NULL, NULL,
971 fbi->aa_walk_budget);
972 if (walked < 0)
974 modified = true;
975 fbi->aa_walk_budget = 0;
977 else
978 fbi->aa_walk_budget -= walked;
979 if (paa && modified)
980 paa->parm_modified = true;
981 return !modified;
984 /* If STMT is an assignment that loads a value from an parameter declaration,
985 return the index of the parameter in ipa_node_params which has not been
986 modified. Otherwise return -1. */
988 static int
989 load_from_unmodified_param (struct ipa_func_body_info *fbi,
990 vec<ipa_param_descriptor, va_gc> *descriptors,
991 gimple *stmt)
993 int index;
994 tree op1;
996 if (!gimple_assign_single_p (stmt))
997 return -1;
999 op1 = gimple_assign_rhs1 (stmt);
1000 if (TREE_CODE (op1) != PARM_DECL)
1001 return -1;
1003 index = ipa_get_param_decl_index_1 (descriptors, op1);
1004 if (index < 0
1005 || !parm_preserved_before_stmt_p (fbi, index, stmt, op1))
1006 return -1;
1008 return index;
1011 /* Return true if memory reference REF (which must be a load through parameter
1012 with INDEX) loads data that are known to be unmodified in this function
1013 before reaching statement STMT. */
1015 static bool
1016 parm_ref_data_preserved_p (struct ipa_func_body_info *fbi,
1017 int index, gimple *stmt, tree ref)
1019 struct ipa_param_aa_status *paa;
1020 bool modified = false;
1021 ao_ref refd;
1023 gcc_checking_assert (fbi);
1024 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
1025 if (paa->ref_modified || fbi->aa_walk_budget == 0)
1026 return false;
1028 gcc_checking_assert (gimple_vuse (stmt));
1029 ao_ref_init (&refd, ref);
1030 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
1031 &modified, NULL, NULL,
1032 fbi->aa_walk_budget);
1033 if (walked < 0)
1035 modified = true;
1036 fbi->aa_walk_budget = 0;
1038 else
1039 fbi->aa_walk_budget -= walked;
1040 if (modified)
1041 paa->ref_modified = true;
1042 return !modified;
1045 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
1046 is known to be unmodified in this function before reaching call statement
1047 CALL into which it is passed. FBI describes the function body. */
1049 static bool
1050 parm_ref_data_pass_through_p (struct ipa_func_body_info *fbi, int index,
1051 gimple *call, tree parm)
1053 bool modified = false;
1054 ao_ref refd;
1056 /* It's unnecessary to calculate anything about memory contnets for a const
1057 function because it is not goin to use it. But do not cache the result
1058 either. Also, no such calculations for non-pointers. */
1059 if (!gimple_vuse (call)
1060 || !POINTER_TYPE_P (TREE_TYPE (parm)))
1061 return false;
1063 struct ipa_param_aa_status *paa = parm_bb_aa_status_for_bb (fbi,
1064 gimple_bb (call),
1065 index);
1066 if (paa->pt_modified || fbi->aa_walk_budget == 0)
1067 return false;
1069 ao_ref_init_from_ptr_and_size (&refd, parm, NULL_TREE);
1070 int walked = walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified,
1071 &modified, NULL, NULL,
1072 fbi->aa_walk_budget);
1073 if (walked < 0)
1075 fbi->aa_walk_budget = 0;
1076 modified = true;
1078 else
1079 fbi->aa_walk_budget -= walked;
1080 if (modified)
1081 paa->pt_modified = true;
1082 return !modified;
1085 /* Return true if we can prove that OP is a memory reference loading
1086 data from an aggregate passed as a parameter.
1088 The function works in two modes. If GUARANTEED_UNMODIFIED is NULL, it return
1089 false if it cannot prove that the value has not been modified before the
1090 load in STMT. If GUARANTEED_UNMODIFIED is not NULL, it will return true even
1091 if it cannot prove the value has not been modified, in that case it will
1092 store false to *GUARANTEED_UNMODIFIED, otherwise it will store true there.
1094 INFO and PARMS_AINFO describe parameters of the current function (but the
1095 latter can be NULL), STMT is the load statement. If function returns true,
1096 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1097 within the aggregate and whether it is a load from a value passed by
1098 reference respectively.
1100 Return false if the offset divided by BITS_PER_UNIT would not fit into an
1101 unsigned int. */
1103 bool
1104 ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
1105 vec<ipa_param_descriptor, va_gc> *descriptors,
1106 gimple *stmt, tree op, int *index_p,
1107 HOST_WIDE_INT *offset_p, poly_int64 *size_p,
1108 bool *by_ref_p, bool *guaranteed_unmodified)
1110 int index;
1111 HOST_WIDE_INT size;
1112 bool reverse;
1113 tree base = get_ref_base_and_extent_hwi (op, offset_p, &size, &reverse);
1115 if (!base
1116 || (*offset_p / BITS_PER_UNIT) > UINT_MAX)
1117 return false;
1119 /* We can not propagate across volatile loads. */
1120 if (TREE_THIS_VOLATILE (op))
1121 return false;
1123 if (DECL_P (base))
1125 int index = ipa_get_param_decl_index_1 (descriptors, base);
1126 if (index >= 0
1127 && parm_preserved_before_stmt_p (fbi, index, stmt, op))
1129 *index_p = index;
1130 *by_ref_p = false;
1131 if (size_p)
1132 *size_p = size;
1133 if (guaranteed_unmodified)
1134 *guaranteed_unmodified = true;
1135 return true;
1137 return false;
1140 if (TREE_CODE (base) != MEM_REF
1141 || TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME
1142 || !integer_zerop (TREE_OPERAND (base, 1)))
1143 return false;
1145 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0)))
1147 tree parm = SSA_NAME_VAR (TREE_OPERAND (base, 0));
1148 index = ipa_get_param_decl_index_1 (descriptors, parm);
1150 else
1152 /* This branch catches situations where a pointer parameter is not a
1153 gimple register, for example:
1155 void hip7(S*) (struct S * p)
1157 void (*<T2e4>) (struct S *) D.1867;
1158 struct S * p.1;
1160 <bb 2>:
1161 p.1_1 = p;
1162 D.1867_2 = p.1_1->f;
1163 D.1867_2 ();
1164 gdp = &p;
1167 gimple *def = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0));
1168 index = load_from_unmodified_param (fbi, descriptors, def);
1171 if (index >= 0)
1173 bool data_preserved = parm_ref_data_preserved_p (fbi, index, stmt, op);
1174 if (!data_preserved && !guaranteed_unmodified)
1175 return false;
1177 *index_p = index;
1178 *by_ref_p = true;
1179 if (size_p)
1180 *size_p = size;
1181 if (guaranteed_unmodified)
1182 *guaranteed_unmodified = data_preserved;
1183 return true;
1185 return false;
1188 /* If STMT is an assignment that loads a value from a parameter declaration,
1189 or from an aggregate passed as the parameter either by value or reference,
1190 return the index of the parameter in ipa_node_params. Otherwise return -1.
1192 FBI holds gathered information about the function. INFO describes
1193 parameters of the function, STMT is the assignment statement. If it is a
1194 memory load from an aggregate, *OFFSET_P is filled with offset within the
1195 aggregate, and *BY_REF_P specifies whether the aggregate is passed by
1196 reference. */
1198 static int
1199 load_from_unmodified_param_or_agg (struct ipa_func_body_info *fbi,
1200 class ipa_node_params *info,
1201 gimple *stmt,
1202 HOST_WIDE_INT *offset_p,
1203 bool *by_ref_p)
1205 int index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1206 poly_int64 size;
1208 /* Load value from a parameter declaration. */
1209 if (index >= 0)
1211 *offset_p = -1;
1212 return index;
1215 if (!gimple_assign_load_p (stmt))
1216 return -1;
1218 tree rhs = gimple_assign_rhs1 (stmt);
1220 /* Skip memory reference containing VIEW_CONVERT_EXPR. */
1221 for (tree t = rhs; handled_component_p (t); t = TREE_OPERAND (t, 0))
1222 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
1223 return -1;
1225 /* Skip memory reference containing bit-field. */
1226 if (TREE_CODE (rhs) == BIT_FIELD_REF
1227 || contains_bitfld_component_ref_p (rhs))
1228 return -1;
1230 if (!ipa_load_from_parm_agg (fbi, info->descriptors, stmt, rhs, &index,
1231 offset_p, &size, by_ref_p))
1232 return -1;
1234 gcc_assert (!maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (rhs))),
1235 size));
1236 if (!*by_ref_p)
1238 tree param_type = ipa_get_type (info, index);
1240 if (!param_type || !AGGREGATE_TYPE_P (param_type))
1241 return -1;
1243 else if (TREE_THIS_VOLATILE (rhs))
1244 return -1;
1246 return index;
1249 /* Walk pointer adjustemnts from OP (such as POINTER_PLUS and ADDR_EXPR)
1250 to find original pointer. Initialize RET to the pointer which results from
1251 the walk.
1252 If offset is known return true and initialize OFFSET_RET. */
1254 bool
1255 unadjusted_ptr_and_unit_offset (tree op, tree *ret, poly_int64 *offset_ret)
1257 poly_int64 offset = 0;
1258 bool offset_known = true;
1259 int i;
1261 for (i = 0; i < param_ipa_jump_function_lookups; i++)
1263 if (TREE_CODE (op) == ADDR_EXPR)
1265 poly_int64 extra_offset = 0;
1266 tree base = get_addr_base_and_unit_offset (TREE_OPERAND (op, 0),
1267 &offset);
1268 if (!base)
1270 base = get_base_address (TREE_OPERAND (op, 0));
1271 if (TREE_CODE (base) != MEM_REF)
1272 break;
1273 offset_known = false;
1275 else
1277 if (TREE_CODE (base) != MEM_REF)
1278 break;
1279 offset += extra_offset;
1281 op = TREE_OPERAND (base, 0);
1282 if (mem_ref_offset (base).to_shwi (&extra_offset))
1283 offset += extra_offset;
1284 else
1285 offset_known = false;
1287 else if (TREE_CODE (op) == SSA_NAME
1288 && !SSA_NAME_IS_DEFAULT_DEF (op))
1290 gimple *pstmt = SSA_NAME_DEF_STMT (op);
1292 if (gimple_assign_single_p (pstmt))
1293 op = gimple_assign_rhs1 (pstmt);
1294 else if (is_gimple_assign (pstmt)
1295 && gimple_assign_rhs_code (pstmt) == POINTER_PLUS_EXPR)
1297 poly_int64 extra_offset = 0;
1298 if (ptrdiff_tree_p (gimple_assign_rhs2 (pstmt),
1299 &extra_offset))
1300 offset += extra_offset;
1301 else
1302 offset_known = false;
1303 op = gimple_assign_rhs1 (pstmt);
1305 else
1306 break;
1308 else
1309 break;
1311 *ret = op;
1312 *offset_ret = offset;
1313 return offset_known;
1316 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1317 of an assignment statement STMT, try to determine whether we are actually
1318 handling any of the following cases and construct an appropriate jump
1319 function into JFUNC if so:
1321 1) The passed value is loaded from a formal parameter which is not a gimple
1322 register (most probably because it is addressable, the value has to be
1323 scalar) and we can guarantee the value has not changed. This case can
1324 therefore be described by a simple pass-through jump function. For example:
1326 foo (int a)
1328 int a.0;
1330 a.0_2 = a;
1331 bar (a.0_2);
1333 2) The passed value can be described by a simple arithmetic pass-through
1334 jump function. E.g.
1336 foo (int a)
1338 int D.2064;
1340 D.2064_4 = a.1(D) + 4;
1341 bar (D.2064_4);
1343 This case can also occur in combination of the previous one, e.g.:
1345 foo (int a, int z)
1347 int a.0;
1348 int D.2064;
1350 a.0_3 = a;
1351 D.2064_4 = a.0_3 + 4;
1352 foo (D.2064_4);
1354 3) The passed value is an address of an object within another one (which
1355 also passed by reference). Such situations are described by an ancestor
1356 jump function and describe situations such as:
1358 B::foo() (struct B * const this)
1360 struct A * D.1845;
1362 D.1845_2 = &this_1(D)->D.1748;
1363 A::bar (D.1845_2);
1365 INFO is the structure describing individual parameters access different
1366 stages of IPA optimizations. PARMS_AINFO contains the information that is
1367 only needed for intraprocedural analysis. */
1369 static void
1370 compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
1371 class ipa_node_params *info,
1372 struct ipa_jump_func *jfunc,
1373 gcall *call, gimple *stmt, tree name,
1374 tree param_type)
1376 HOST_WIDE_INT offset, size;
1377 tree op1, tc_ssa, base, ssa;
1378 bool reverse;
1379 int index;
1381 op1 = gimple_assign_rhs1 (stmt);
1383 if (TREE_CODE (op1) == SSA_NAME)
1385 if (SSA_NAME_IS_DEFAULT_DEF (op1))
1386 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
1387 else
1388 index = load_from_unmodified_param (fbi, info->descriptors,
1389 SSA_NAME_DEF_STMT (op1));
1390 tc_ssa = op1;
1392 else
1394 index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1395 tc_ssa = gimple_assign_lhs (stmt);
1398 if (index >= 0)
1400 switch (gimple_assign_rhs_class (stmt))
1402 case GIMPLE_BINARY_RHS:
1404 tree op2 = gimple_assign_rhs2 (stmt);
1405 if (!is_gimple_ip_invariant (op2)
1406 || ((TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
1407 != tcc_comparison)
1408 && !useless_type_conversion_p (TREE_TYPE (name),
1409 TREE_TYPE (op1))))
1410 return;
1412 ipa_set_jf_arith_pass_through (jfunc, index, op2,
1413 gimple_assign_rhs_code (stmt));
1414 break;
1416 case GIMPLE_SINGLE_RHS:
1418 bool agg_p = parm_ref_data_pass_through_p (fbi, index, call,
1419 tc_ssa);
1420 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
1421 break;
1423 case GIMPLE_UNARY_RHS:
1424 if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)))
1425 ipa_set_jf_unary_pass_through (jfunc, index,
1426 gimple_assign_rhs_code (stmt));
1427 default:;
1429 return;
1432 if (TREE_CODE (op1) != ADDR_EXPR)
1433 return;
1434 op1 = TREE_OPERAND (op1, 0);
1435 base = get_ref_base_and_extent_hwi (op1, &offset, &size, &reverse);
1436 offset_int mem_offset;
1437 if (!base
1438 || TREE_CODE (base) != MEM_REF
1439 || !mem_ref_offset (base).is_constant (&mem_offset))
1440 return;
1441 offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
1442 ssa = TREE_OPERAND (base, 0);
1443 if (TREE_CODE (ssa) != SSA_NAME
1444 || !SSA_NAME_IS_DEFAULT_DEF (ssa)
1445 || offset < 0)
1446 return;
1448 /* Dynamic types are changed in constructors and destructors. */
1449 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
1450 if (index >= 0 && param_type && POINTER_TYPE_P (param_type))
1451 ipa_set_ancestor_jf (jfunc, offset, index,
1452 parm_ref_data_pass_through_p (fbi, index, call, ssa),
1453 false);
1456 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1457 it looks like:
1459 iftmp.1_3 = &obj_2(D)->D.1762;
1461 The base of the MEM_REF must be a default definition SSA NAME of a
1462 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1463 whole MEM_REF expression is returned and the offset calculated from any
1464 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1465 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1467 static tree
1468 get_ancestor_addr_info (gimple *assign, tree *obj_p, HOST_WIDE_INT *offset)
1470 HOST_WIDE_INT size;
1471 tree expr, parm, obj;
1472 bool reverse;
1474 if (!gimple_assign_single_p (assign))
1475 return NULL_TREE;
1476 expr = gimple_assign_rhs1 (assign);
1478 if (TREE_CODE (expr) != ADDR_EXPR)
1479 return NULL_TREE;
1480 expr = TREE_OPERAND (expr, 0);
1481 obj = expr;
1482 expr = get_ref_base_and_extent_hwi (expr, offset, &size, &reverse);
1484 offset_int mem_offset;
1485 if (!expr
1486 || TREE_CODE (expr) != MEM_REF
1487 || !mem_ref_offset (expr).is_constant (&mem_offset))
1488 return NULL_TREE;
1489 parm = TREE_OPERAND (expr, 0);
1490 if (TREE_CODE (parm) != SSA_NAME
1491 || !SSA_NAME_IS_DEFAULT_DEF (parm)
1492 || TREE_CODE (SSA_NAME_VAR (parm)) != PARM_DECL)
1493 return NULL_TREE;
1495 *offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
1496 *obj_p = obj;
1497 return expr;
1501 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1502 statement PHI, try to find out whether NAME is in fact a
1503 multiple-inheritance typecast from a descendant into an ancestor of a formal
1504 parameter and thus can be described by an ancestor jump function and if so,
1505 write the appropriate function into JFUNC.
1507 Essentially we want to match the following pattern:
1509 if (obj_2(D) != 0B)
1510 goto <bb 3>;
1511 else
1512 goto <bb 4>;
1514 <bb 3>:
1515 iftmp.1_3 = &obj_2(D)->D.1762;
1517 <bb 4>:
1518 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1519 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1520 return D.1879_6; */
1522 static void
1523 compute_complex_ancestor_jump_func (struct ipa_func_body_info *fbi,
1524 class ipa_node_params *info,
1525 struct ipa_jump_func *jfunc,
1526 gcall *call, gphi *phi)
1528 HOST_WIDE_INT offset;
1529 gimple *assign, *cond;
1530 basic_block phi_bb, assign_bb, cond_bb;
1531 tree tmp, parm, expr, obj;
1532 int index, i;
1534 if (gimple_phi_num_args (phi) != 2)
1535 return;
1537 if (integer_zerop (PHI_ARG_DEF (phi, 1)))
1538 tmp = PHI_ARG_DEF (phi, 0);
1539 else if (integer_zerop (PHI_ARG_DEF (phi, 0)))
1540 tmp = PHI_ARG_DEF (phi, 1);
1541 else
1542 return;
1543 if (TREE_CODE (tmp) != SSA_NAME
1544 || SSA_NAME_IS_DEFAULT_DEF (tmp)
1545 || !POINTER_TYPE_P (TREE_TYPE (tmp))
1546 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) != RECORD_TYPE)
1547 return;
1549 assign = SSA_NAME_DEF_STMT (tmp);
1550 assign_bb = gimple_bb (assign);
1551 if (!single_pred_p (assign_bb))
1552 return;
1553 expr = get_ancestor_addr_info (assign, &obj, &offset);
1554 if (!expr)
1555 return;
1556 parm = TREE_OPERAND (expr, 0);
1557 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (parm));
1558 if (index < 0)
1559 return;
1561 cond_bb = single_pred (assign_bb);
1562 cond = last_stmt (cond_bb);
1563 if (!cond
1564 || gimple_code (cond) != GIMPLE_COND
1565 || gimple_cond_code (cond) != NE_EXPR
1566 || gimple_cond_lhs (cond) != parm
1567 || !integer_zerop (gimple_cond_rhs (cond)))
1568 return;
1570 phi_bb = gimple_bb (phi);
1571 for (i = 0; i < 2; i++)
1573 basic_block pred = EDGE_PRED (phi_bb, i)->src;
1574 if (pred != assign_bb && pred != cond_bb)
1575 return;
1578 ipa_set_ancestor_jf (jfunc, offset, index,
1579 parm_ref_data_pass_through_p (fbi, index, call, parm),
1580 true);
1583 /* Inspect the given TYPE and return true iff it has the same structure (the
1584 same number of fields of the same types) as a C++ member pointer. If
1585 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1586 corresponding fields there. */
1588 static bool
1589 type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
1591 tree fld;
1593 if (TREE_CODE (type) != RECORD_TYPE)
1594 return false;
1596 fld = TYPE_FIELDS (type);
1597 if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
1598 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE
1599 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1600 return false;
1602 if (method_ptr)
1603 *method_ptr = fld;
1605 fld = DECL_CHAIN (fld);
1606 if (!fld || INTEGRAL_TYPE_P (fld)
1607 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1608 return false;
1609 if (delta)
1610 *delta = fld;
1612 if (DECL_CHAIN (fld))
1613 return false;
1615 return true;
1618 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1619 return the rhs of its defining statement, and this statement is stored in
1620 *RHS_STMT. Otherwise return RHS as it is. */
1622 static inline tree
1623 get_ssa_def_if_simple_copy (tree rhs, gimple **rhs_stmt)
1625 while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
1627 gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
1629 if (gimple_assign_single_p (def_stmt))
1630 rhs = gimple_assign_rhs1 (def_stmt);
1631 else
1632 break;
1633 *rhs_stmt = def_stmt;
1635 return rhs;
1638 /* Simple linked list, describing contents of an aggregate before call. */
1640 struct ipa_known_agg_contents_list
1642 /* Offset and size of the described part of the aggregate. */
1643 HOST_WIDE_INT offset, size;
1645 /* Type of the described part of the aggregate. */
1646 tree type;
1648 /* Known constant value or jump function data describing contents. */
1649 struct ipa_load_agg_data value;
1651 /* Pointer to the next structure in the list. */
1652 struct ipa_known_agg_contents_list *next;
1655 /* Add an aggregate content item into a linked list of
1656 ipa_known_agg_contents_list structure, in which all elements
1657 are sorted ascendingly by offset. */
1659 static inline void
1660 add_to_agg_contents_list (struct ipa_known_agg_contents_list **plist,
1661 struct ipa_known_agg_contents_list *item)
1663 struct ipa_known_agg_contents_list *list = *plist;
1665 for (; list; list = list->next)
1667 if (list->offset >= item->offset)
1668 break;
1670 plist = &list->next;
1673 item->next = list;
1674 *plist = item;
1677 /* Check whether a given aggregate content is clobbered by certain element in
1678 a linked list of ipa_known_agg_contents_list. */
1680 static inline bool
1681 clobber_by_agg_contents_list_p (struct ipa_known_agg_contents_list *list,
1682 struct ipa_known_agg_contents_list *item)
1684 for (; list; list = list->next)
1686 if (list->offset >= item->offset)
1687 return list->offset < item->offset + item->size;
1689 if (list->offset + list->size > item->offset)
1690 return true;
1693 return false;
1696 /* Build aggregate jump function from LIST, assuming there are exactly
1697 VALUE_COUNT entries there and that offset of the passed argument
1698 is ARG_OFFSET and store it into JFUNC. */
1700 static void
1701 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
1702 int value_count, HOST_WIDE_INT arg_offset,
1703 struct ipa_jump_func *jfunc)
1705 vec_safe_reserve (jfunc->agg.items, value_count, true);
1706 for (; list; list = list->next)
1708 struct ipa_agg_jf_item item;
1709 tree operand = list->value.pass_through.operand;
1711 if (list->value.pass_through.formal_id >= 0)
1713 /* Content value is derived from some formal paramerter. */
1714 if (list->value.offset >= 0)
1715 item.jftype = IPA_JF_LOAD_AGG;
1716 else
1717 item.jftype = IPA_JF_PASS_THROUGH;
1719 item.value.load_agg = list->value;
1720 if (operand)
1721 item.value.pass_through.operand
1722 = unshare_expr_without_location (operand);
1724 else if (operand)
1726 /* Content value is known constant. */
1727 item.jftype = IPA_JF_CONST;
1728 item.value.constant = unshare_expr_without_location (operand);
1730 else
1731 continue;
1733 item.type = list->type;
1734 gcc_assert (tree_to_shwi (TYPE_SIZE (list->type)) == list->size);
1736 item.offset = list->offset - arg_offset;
1737 gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
1739 jfunc->agg.items->quick_push (item);
1743 /* Given an assignment statement STMT, try to collect information into
1744 AGG_VALUE that will be used to construct jump function for RHS of the
1745 assignment, from which content value of an aggregate part comes.
1747 Besides constant and simple pass-through jump functions, also try to
1748 identify whether it matches the following pattern that can be described by
1749 a load-value-from-aggregate jump function, which is a derivative of simple
1750 pass-through jump function.
1752 foo (int *p)
1756 *(q_5 + 4) = *(p_3(D) + 28) op 1;
1757 bar (q_5);
1760 Here IPA_LOAD_AGG_DATA data structure is informative enough to describe
1761 constant, simple pass-through and load-vale-from-aggregate. If value
1762 is constant, it will be kept in field OPERAND, and field FORMAL_ID is
1763 set to -1. For simple pass-through and load-value-from-aggregate, field
1764 FORMAL_ID specifies the related formal parameter index, and field
1765 OFFSET can be used to distinguish them, -1 means simple pass-through,
1766 otherwise means load-value-from-aggregate. */
1768 static void
1769 analyze_agg_content_value (struct ipa_func_body_info *fbi,
1770 struct ipa_load_agg_data *agg_value,
1771 gimple *stmt)
1773 tree lhs = gimple_assign_lhs (stmt);
1774 tree rhs1 = gimple_assign_rhs1 (stmt);
1775 enum tree_code code;
1776 int index = -1;
1778 /* Initialize jump function data for the aggregate part. */
1779 memset (agg_value, 0, sizeof (*agg_value));
1780 agg_value->pass_through.operation = NOP_EXPR;
1781 agg_value->pass_through.formal_id = -1;
1782 agg_value->offset = -1;
1784 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs)) /* TODO: Support aggregate type. */
1785 || TREE_THIS_VOLATILE (lhs)
1786 || TREE_CODE (lhs) == BIT_FIELD_REF
1787 || contains_bitfld_component_ref_p (lhs))
1788 return;
1790 /* Skip SSA copies. */
1791 while (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
1793 if (TREE_CODE (rhs1) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (rhs1))
1794 break;
1796 stmt = SSA_NAME_DEF_STMT (rhs1);
1797 if (!is_gimple_assign (stmt))
1798 break;
1800 rhs1 = gimple_assign_rhs1 (stmt);
1803 if (gphi *phi = dyn_cast<gphi *> (stmt))
1805 /* Also special case like the following (a is a formal parameter):
1807 _12 = *a_11(D).dim[0].stride;
1809 # iftmp.22_9 = PHI <_12(2), 1(3)>
1811 parm.6.dim[0].stride = iftmp.22_9;
1813 __x_MOD_foo (&parm.6, b_31(D));
1815 The aggregate function describing parm.6.dim[0].stride is encoded as a
1816 PASS-THROUGH jump function with ASSERT_EXPR operation whith operand 1
1817 (the constant from the PHI node). */
1819 if (gimple_phi_num_args (phi) != 2)
1820 return;
1821 tree arg0 = gimple_phi_arg_def (phi, 0);
1822 tree arg1 = gimple_phi_arg_def (phi, 1);
1823 tree operand;
1825 if (is_gimple_ip_invariant (arg1))
1827 operand = arg1;
1828 rhs1 = arg0;
1830 else if (is_gimple_ip_invariant (arg0))
1832 operand = arg0;
1833 rhs1 = arg1;
1835 else
1836 return;
1838 rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
1839 if (!is_gimple_assign (stmt))
1840 return;
1842 code = ASSERT_EXPR;
1843 agg_value->pass_through.operand = operand;
1845 else if (is_gimple_assign (stmt))
1847 code = gimple_assign_rhs_code (stmt);
1848 switch (gimple_assign_rhs_class (stmt))
1850 case GIMPLE_SINGLE_RHS:
1851 if (is_gimple_ip_invariant (rhs1))
1853 agg_value->pass_through.operand = rhs1;
1854 return;
1856 code = NOP_EXPR;
1857 break;
1859 case GIMPLE_UNARY_RHS:
1860 /* NOTE: A GIMPLE_UNARY_RHS operation might not be tcc_unary
1861 (truth_not_expr is example), GIMPLE_BINARY_RHS does not imply
1862 tcc_binary, this subtleness is somewhat misleading.
1864 Since tcc_unary is widely used in IPA-CP code to check an operation
1865 with one operand, here we only allow tc_unary operation to avoid
1866 possible problem. Then we can use (opclass == tc_unary) or not to
1867 distinguish unary and binary. */
1868 if (TREE_CODE_CLASS (code) != tcc_unary || CONVERT_EXPR_CODE_P (code))
1869 return;
1871 rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
1872 break;
1874 case GIMPLE_BINARY_RHS:
1876 gimple *rhs1_stmt = stmt;
1877 gimple *rhs2_stmt = stmt;
1878 tree rhs2 = gimple_assign_rhs2 (stmt);
1880 rhs1 = get_ssa_def_if_simple_copy (rhs1, &rhs1_stmt);
1881 rhs2 = get_ssa_def_if_simple_copy (rhs2, &rhs2_stmt);
1883 if (is_gimple_ip_invariant (rhs2))
1885 agg_value->pass_through.operand = rhs2;
1886 stmt = rhs1_stmt;
1888 else if (is_gimple_ip_invariant (rhs1))
1890 if (TREE_CODE_CLASS (code) == tcc_comparison)
1891 code = swap_tree_comparison (code);
1892 else if (!commutative_tree_code (code))
1893 return;
1895 agg_value->pass_through.operand = rhs1;
1896 stmt = rhs2_stmt;
1897 rhs1 = rhs2;
1899 else
1900 return;
1902 if (TREE_CODE_CLASS (code) != tcc_comparison
1903 && !useless_type_conversion_p (TREE_TYPE (lhs),
1904 TREE_TYPE (rhs1)))
1905 return;
1907 break;
1909 default:
1910 return;
1913 else
1914 return;
1916 if (TREE_CODE (rhs1) != SSA_NAME)
1917 index = load_from_unmodified_param_or_agg (fbi, fbi->info, stmt,
1918 &agg_value->offset,
1919 &agg_value->by_ref);
1920 else if (SSA_NAME_IS_DEFAULT_DEF (rhs1))
1921 index = ipa_get_param_decl_index (fbi->info, SSA_NAME_VAR (rhs1));
1923 if (index >= 0)
1925 if (agg_value->offset >= 0)
1926 agg_value->type = TREE_TYPE (rhs1);
1927 agg_value->pass_through.formal_id = index;
1928 agg_value->pass_through.operation = code;
1930 else
1931 agg_value->pass_through.operand = NULL_TREE;
1934 /* If STMT is a memory store to the object whose address is BASE, extract
1935 information (offset, size, and value) into CONTENT, and return true,
1936 otherwise we conservatively assume the whole object is modified with
1937 unknown content, and return false. CHECK_REF means that access to object
1938 is expected to be in form of MEM_REF expression. */
1940 static bool
1941 extract_mem_content (struct ipa_func_body_info *fbi,
1942 gimple *stmt, tree base, bool check_ref,
1943 struct ipa_known_agg_contents_list *content)
1945 HOST_WIDE_INT lhs_offset, lhs_size;
1946 bool reverse;
1948 if (!is_gimple_assign (stmt))
1949 return false;
1951 tree lhs = gimple_assign_lhs (stmt);
1952 tree lhs_base = get_ref_base_and_extent_hwi (lhs, &lhs_offset, &lhs_size,
1953 &reverse);
1954 if (!lhs_base)
1955 return false;
1957 if (check_ref)
1959 if (TREE_CODE (lhs_base) != MEM_REF
1960 || TREE_OPERAND (lhs_base, 0) != base
1961 || !integer_zerop (TREE_OPERAND (lhs_base, 1)))
1962 return false;
1964 else if (lhs_base != base)
1965 return false;
1967 content->offset = lhs_offset;
1968 content->size = lhs_size;
1969 content->type = TREE_TYPE (lhs);
1970 content->next = NULL;
1972 analyze_agg_content_value (fbi, &content->value, stmt);
1973 return true;
1976 /* Traverse statements from CALL backwards, scanning whether an aggregate given
1977 in ARG is filled in constants or values that are derived from caller's
1978 formal parameter in the way described by some kinds of jump functions. FBI
1979 is the context of the caller function for interprocedural analysis. ARG can
1980 either be an aggregate expression or a pointer to an aggregate. ARG_TYPE is
1981 the type of the aggregate, JFUNC is the jump function for the aggregate. */
1983 static void
1984 determine_known_aggregate_parts (struct ipa_func_body_info *fbi,
1985 gcall *call, tree arg,
1986 tree arg_type,
1987 struct ipa_jump_func *jfunc)
1989 struct ipa_known_agg_contents_list *list = NULL, *all_list = NULL;
1990 bitmap visited = NULL;
1991 int item_count = 0, value_count = 0;
1992 HOST_WIDE_INT arg_offset, arg_size;
1993 tree arg_base;
1994 bool check_ref, by_ref;
1995 ao_ref r;
1996 int max_agg_items = opt_for_fn (fbi->node->decl, param_ipa_max_agg_items);
1998 if (max_agg_items == 0)
1999 return;
2001 /* The function operates in three stages. First, we prepare check_ref, r,
2002 arg_base and arg_offset based on what is actually passed as an actual
2003 argument. */
2005 if (POINTER_TYPE_P (arg_type))
2007 by_ref = true;
2008 if (TREE_CODE (arg) == SSA_NAME)
2010 tree type_size;
2011 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type)))
2012 || !POINTER_TYPE_P (TREE_TYPE (arg)))
2013 return;
2014 check_ref = true;
2015 arg_base = arg;
2016 arg_offset = 0;
2017 type_size = TYPE_SIZE (TREE_TYPE (arg_type));
2018 arg_size = tree_to_uhwi (type_size);
2019 ao_ref_init_from_ptr_and_size (&r, arg_base, NULL_TREE);
2021 else if (TREE_CODE (arg) == ADDR_EXPR)
2023 bool reverse;
2025 arg = TREE_OPERAND (arg, 0);
2026 arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
2027 &arg_size, &reverse);
2028 if (!arg_base)
2029 return;
2030 if (DECL_P (arg_base))
2032 check_ref = false;
2033 ao_ref_init (&r, arg_base);
2035 else
2036 return;
2038 else
2039 return;
2041 else
2043 bool reverse;
2045 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg)));
2047 by_ref = false;
2048 check_ref = false;
2049 arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
2050 &arg_size, &reverse);
2051 if (!arg_base)
2052 return;
2054 ao_ref_init (&r, arg);
2057 /* Second stage traverses virtual SSA web backwards starting from the call
2058 statement, only looks at individual dominating virtual operand (its
2059 definition dominates the call), as long as it is confident that content
2060 of the aggregate is affected by definition of the virtual operand, it
2061 builds a sorted linked list of ipa_agg_jf_list describing that. */
2063 for (tree dom_vuse = gimple_vuse (call);
2064 dom_vuse && fbi->aa_walk_budget > 0;)
2066 gimple *stmt = SSA_NAME_DEF_STMT (dom_vuse);
2068 if (gimple_code (stmt) == GIMPLE_PHI)
2070 dom_vuse = get_continuation_for_phi (stmt, &r, true,
2071 fbi->aa_walk_budget,
2072 &visited, false, NULL, NULL);
2073 continue;
2076 fbi->aa_walk_budget--;
2077 if (stmt_may_clobber_ref_p_1 (stmt, &r))
2079 struct ipa_known_agg_contents_list *content
2080 = XALLOCA (struct ipa_known_agg_contents_list);
2082 if (!extract_mem_content (fbi, stmt, arg_base, check_ref, content))
2083 break;
2085 /* Now we get a dominating virtual operand, and need to check
2086 whether its value is clobbered any other dominating one. */
2087 if ((content->value.pass_through.formal_id >= 0
2088 || content->value.pass_through.operand)
2089 && !clobber_by_agg_contents_list_p (all_list, content)
2090 /* Since IPA-CP stores results with unsigned int offsets, we can
2091 discard those which would not fit now before we stream them to
2092 WPA. */
2093 && (content->offset + content->size - arg_offset
2094 <= (HOST_WIDE_INT) UINT_MAX * BITS_PER_UNIT))
2096 struct ipa_known_agg_contents_list *copy
2097 = XALLOCA (struct ipa_known_agg_contents_list);
2099 /* Add to the list consisting of only dominating virtual
2100 operands, whose definitions can finally reach the call. */
2101 add_to_agg_contents_list (&list, (*copy = *content, copy));
2103 if (++value_count == max_agg_items)
2104 break;
2107 /* Add to the list consisting of all dominating virtual operands. */
2108 add_to_agg_contents_list (&all_list, content);
2110 if (++item_count == 2 * max_agg_items)
2111 break;
2113 dom_vuse = gimple_vuse (stmt);
2116 if (visited)
2117 BITMAP_FREE (visited);
2119 /* Third stage just goes over the list and creates an appropriate vector of
2120 ipa_agg_jf_item structures out of it, of course only if there are
2121 any meaningful items to begin with. */
2123 if (value_count)
2125 jfunc->agg.by_ref = by_ref;
2126 build_agg_jump_func_from_list (list, value_count, arg_offset, jfunc);
2131 /* Return the Ith param type of callee associated with call graph
2132 edge E. */
2134 tree
2135 ipa_get_callee_param_type (struct cgraph_edge *e, int i)
2137 int n;
2138 tree type = (e->callee
2139 ? TREE_TYPE (e->callee->decl)
2140 : gimple_call_fntype (e->call_stmt));
2141 tree t = TYPE_ARG_TYPES (type);
2143 for (n = 0; n < i; n++)
2145 if (!t)
2146 break;
2147 t = TREE_CHAIN (t);
2149 if (t)
2150 return TREE_VALUE (t);
2151 if (!e->callee)
2152 return NULL;
2153 t = DECL_ARGUMENTS (e->callee->decl);
2154 for (n = 0; n < i; n++)
2156 if (!t)
2157 return NULL;
2158 t = TREE_CHAIN (t);
2160 if (t)
2161 return TREE_TYPE (t);
2162 return NULL;
2165 /* Return ipa_bits with VALUE and MASK values, which can be either a newly
2166 allocated structure or a previously existing one shared with other jump
2167 functions and/or transformation summaries. */
2169 ipa_bits *
2170 ipa_get_ipa_bits_for_value (const widest_int &value, const widest_int &mask)
2172 ipa_bits tmp;
2173 tmp.value = value;
2174 tmp.mask = mask;
2176 ipa_bits **slot = ipa_bits_hash_table->find_slot (&tmp, INSERT);
2177 if (*slot)
2178 return *slot;
2180 ipa_bits *res = ggc_alloc<ipa_bits> ();
2181 res->value = value;
2182 res->mask = mask;
2183 *slot = res;
2185 return res;
2188 /* Assign to JF a pointer to ipa_bits structure with VALUE and MASK. Use hash
2189 table in order to avoid creating multiple same ipa_bits structures. */
2191 static void
2192 ipa_set_jfunc_bits (ipa_jump_func *jf, const widest_int &value,
2193 const widest_int &mask)
2195 jf->bits = ipa_get_ipa_bits_for_value (value, mask);
2198 /* Return a pointer to a value_range just like *TMP, but either find it in
2199 ipa_vr_hash_table or allocate it in GC memory. TMP->equiv must be NULL. */
2201 static value_range *
2202 ipa_get_value_range (value_range *tmp)
2204 value_range **slot = ipa_vr_hash_table->find_slot (tmp, INSERT);
2205 if (*slot)
2206 return *slot;
2208 value_range *vr = new (ggc_alloc<value_range> ()) value_range;
2209 *vr = *tmp;
2210 *slot = vr;
2212 return vr;
2215 /* Return a pointer to a value range consisting of TYPE, MIN, MAX and an empty
2216 equiv set. Use hash table in order to avoid creating multiple same copies of
2217 value_ranges. */
2219 static value_range *
2220 ipa_get_value_range (enum value_range_kind kind, tree min, tree max)
2222 value_range tmp (min, max, kind);
2223 return ipa_get_value_range (&tmp);
2226 /* Assign to JF a pointer to a value_range structure with TYPE, MIN and MAX and
2227 a NULL equiv bitmap. Use hash table in order to avoid creating multiple
2228 same value_range structures. */
2230 static void
2231 ipa_set_jfunc_vr (ipa_jump_func *jf, enum value_range_kind type,
2232 tree min, tree max)
2234 jf->m_vr = ipa_get_value_range (type, min, max);
2237 /* Assign to JF a pointer to a value_range just like TMP but either fetch a
2238 copy from ipa_vr_hash_table or allocate a new on in GC memory. */
2240 static void
2241 ipa_set_jfunc_vr (ipa_jump_func *jf, value_range *tmp)
2243 jf->m_vr = ipa_get_value_range (tmp);
2246 /* Compute jump function for all arguments of callsite CS and insert the
2247 information in the jump_functions array in the ipa_edge_args corresponding
2248 to this callsite. */
2250 static void
2251 ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
2252 struct cgraph_edge *cs)
2254 ipa_node_params *info = ipa_node_params_sum->get (cs->caller);
2255 ipa_edge_args *args = ipa_edge_args_sum->get_create (cs);
2256 gcall *call = cs->call_stmt;
2257 int n, arg_num = gimple_call_num_args (call);
2258 bool useful_context = false;
2259 value_range vr;
2261 if (arg_num == 0 || args->jump_functions)
2262 return;
2263 vec_safe_grow_cleared (args->jump_functions, arg_num, true);
2264 if (flag_devirtualize)
2265 vec_safe_grow_cleared (args->polymorphic_call_contexts, arg_num, true);
2267 if (gimple_call_internal_p (call))
2268 return;
2269 if (ipa_func_spec_opts_forbid_analysis_p (cs->caller))
2270 return;
2272 for (n = 0; n < arg_num; n++)
2274 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
2275 tree arg = gimple_call_arg (call, n);
2276 tree param_type = ipa_get_callee_param_type (cs, n);
2277 if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
2279 tree instance;
2280 class ipa_polymorphic_call_context context (cs->caller->decl,
2281 arg, cs->call_stmt,
2282 &instance);
2283 context.get_dynamic_type (instance, arg, NULL, cs->call_stmt,
2284 &fbi->aa_walk_budget);
2285 *ipa_get_ith_polymorhic_call_context (args, n) = context;
2286 if (!context.useless_p ())
2287 useful_context = true;
2290 if (POINTER_TYPE_P (TREE_TYPE (arg)))
2292 bool addr_nonzero = false;
2293 bool strict_overflow = false;
2295 if (TREE_CODE (arg) == SSA_NAME
2296 && param_type
2297 && get_range_query (cfun)->range_of_expr (vr, arg)
2298 && vr.nonzero_p ())
2299 addr_nonzero = true;
2300 else if (tree_single_nonzero_warnv_p (arg, &strict_overflow))
2301 addr_nonzero = true;
2303 if (addr_nonzero)
2305 tree z = build_int_cst (TREE_TYPE (arg), 0);
2306 ipa_set_jfunc_vr (jfunc, VR_ANTI_RANGE, z, z);
2308 else
2309 gcc_assert (!jfunc->m_vr);
2311 else
2313 if (TREE_CODE (arg) == SSA_NAME
2314 && param_type
2315 /* Limit the ranger query to integral types as the rest
2316 of this file uses value_range's, which only hold
2317 integers and pointers. */
2318 && irange::supports_p (TREE_TYPE (arg))
2319 && get_range_query (cfun)->range_of_expr (vr, arg)
2320 && !vr.undefined_p ())
2322 value_range resvr;
2323 range_fold_unary_expr (&resvr, NOP_EXPR, param_type,
2324 &vr, TREE_TYPE (arg));
2325 if (!resvr.undefined_p () && !resvr.varying_p ())
2326 ipa_set_jfunc_vr (jfunc, &resvr);
2327 else
2328 gcc_assert (!jfunc->m_vr);
2330 else
2331 gcc_assert (!jfunc->m_vr);
2334 if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
2335 && (TREE_CODE (arg) == SSA_NAME || TREE_CODE (arg) == INTEGER_CST))
2337 if (TREE_CODE (arg) == SSA_NAME)
2338 ipa_set_jfunc_bits (jfunc, 0,
2339 widest_int::from (get_nonzero_bits (arg),
2340 TYPE_SIGN (TREE_TYPE (arg))));
2341 else
2342 ipa_set_jfunc_bits (jfunc, wi::to_widest (arg), 0);
2344 else if (POINTER_TYPE_P (TREE_TYPE (arg)))
2346 unsigned HOST_WIDE_INT bitpos;
2347 unsigned align;
2349 get_pointer_alignment_1 (arg, &align, &bitpos);
2350 widest_int mask = wi::bit_and_not
2351 (wi::mask<widest_int> (TYPE_PRECISION (TREE_TYPE (arg)), false),
2352 align / BITS_PER_UNIT - 1);
2353 widest_int value = bitpos / BITS_PER_UNIT;
2354 ipa_set_jfunc_bits (jfunc, value, mask);
2356 else
2357 gcc_assert (!jfunc->bits);
2359 if (is_gimple_ip_invariant (arg)
2360 || (VAR_P (arg)
2361 && is_global_var (arg)
2362 && TREE_READONLY (arg)))
2363 ipa_set_jf_constant (jfunc, arg, cs);
2364 else if (!is_gimple_reg_type (TREE_TYPE (arg))
2365 && TREE_CODE (arg) == PARM_DECL)
2367 int index = ipa_get_param_decl_index (info, arg);
2369 gcc_assert (index >=0);
2370 /* Aggregate passed by value, check for pass-through, otherwise we
2371 will attempt to fill in aggregate contents later in this
2372 for cycle. */
2373 if (parm_preserved_before_stmt_p (fbi, index, call, arg))
2375 ipa_set_jf_simple_pass_through (jfunc, index, false);
2376 continue;
2379 else if (TREE_CODE (arg) == SSA_NAME)
2381 if (SSA_NAME_IS_DEFAULT_DEF (arg))
2383 int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
2384 if (index >= 0)
2386 bool agg_p;
2387 agg_p = parm_ref_data_pass_through_p (fbi, index, call, arg);
2388 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
2391 else
2393 gimple *stmt = SSA_NAME_DEF_STMT (arg);
2394 if (is_gimple_assign (stmt))
2395 compute_complex_assign_jump_func (fbi, info, jfunc,
2396 call, stmt, arg, param_type);
2397 else if (gimple_code (stmt) == GIMPLE_PHI)
2398 compute_complex_ancestor_jump_func (fbi, info, jfunc,
2399 call,
2400 as_a <gphi *> (stmt));
2404 /* If ARG is pointer, we cannot use its type to determine the type of aggregate
2405 passed (because type conversions are ignored in gimple). Usually we can
2406 safely get type from function declaration, but in case of K&R prototypes or
2407 variadic functions we can try our luck with type of the pointer passed.
2408 TODO: Since we look for actual initialization of the memory object, we may better
2409 work out the type based on the memory stores we find. */
2410 if (!param_type)
2411 param_type = TREE_TYPE (arg);
2413 if ((jfunc->type != IPA_JF_PASS_THROUGH
2414 || !ipa_get_jf_pass_through_agg_preserved (jfunc))
2415 && (jfunc->type != IPA_JF_ANCESTOR
2416 || !ipa_get_jf_ancestor_agg_preserved (jfunc))
2417 && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
2418 || POINTER_TYPE_P (param_type)))
2419 determine_known_aggregate_parts (fbi, call, arg, param_type, jfunc);
2421 if (!useful_context)
2422 vec_free (args->polymorphic_call_contexts);
2425 /* Compute jump functions for all edges - both direct and indirect - outgoing
2426 from BB. */
2428 static void
2429 ipa_compute_jump_functions_for_bb (struct ipa_func_body_info *fbi, basic_block bb)
2431 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
2432 int i;
2433 struct cgraph_edge *cs;
2435 FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
2437 struct cgraph_node *callee = cs->callee;
2439 if (callee)
2441 callee = callee->ultimate_alias_target ();
2442 /* We do not need to bother analyzing calls to unknown functions
2443 unless they may become known during lto/whopr. */
2444 if (!callee->definition && !flag_lto
2445 && !gimple_call_fnspec (cs->call_stmt).known_p ())
2446 continue;
2448 ipa_compute_jump_functions_for_edge (fbi, cs);
2452 /* If STMT looks like a statement loading a value from a member pointer formal
2453 parameter, return that parameter and store the offset of the field to
2454 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
2455 might be clobbered). If USE_DELTA, then we look for a use of the delta
2456 field rather than the pfn. */
2458 static tree
2459 ipa_get_stmt_member_ptr_load_param (gimple *stmt, bool use_delta,
2460 HOST_WIDE_INT *offset_p)
2462 tree rhs, rec, ref_field, ref_offset, fld, ptr_field, delta_field;
2464 if (!gimple_assign_single_p (stmt))
2465 return NULL_TREE;
2467 rhs = gimple_assign_rhs1 (stmt);
2468 if (TREE_CODE (rhs) == COMPONENT_REF)
2470 ref_field = TREE_OPERAND (rhs, 1);
2471 rhs = TREE_OPERAND (rhs, 0);
2473 else
2474 ref_field = NULL_TREE;
2475 if (TREE_CODE (rhs) != MEM_REF)
2476 return NULL_TREE;
2477 rec = TREE_OPERAND (rhs, 0);
2478 if (TREE_CODE (rec) != ADDR_EXPR)
2479 return NULL_TREE;
2480 rec = TREE_OPERAND (rec, 0);
2481 if (TREE_CODE (rec) != PARM_DECL
2482 || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field))
2483 return NULL_TREE;
2484 ref_offset = TREE_OPERAND (rhs, 1);
2486 if (use_delta)
2487 fld = delta_field;
2488 else
2489 fld = ptr_field;
2490 if (offset_p)
2491 *offset_p = int_bit_position (fld);
2493 if (ref_field)
2495 if (integer_nonzerop (ref_offset))
2496 return NULL_TREE;
2497 return ref_field == fld ? rec : NULL_TREE;
2499 else
2500 return tree_int_cst_equal (byte_position (fld), ref_offset) ? rec
2501 : NULL_TREE;
2504 /* Returns true iff T is an SSA_NAME defined by a statement. */
2506 static bool
2507 ipa_is_ssa_with_stmt_def (tree t)
2509 if (TREE_CODE (t) == SSA_NAME
2510 && !SSA_NAME_IS_DEFAULT_DEF (t))
2511 return true;
2512 else
2513 return false;
2516 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2517 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2518 indirect call graph edge.
2519 If POLYMORPHIC is true record is as a destination of polymorphic call. */
2521 static struct cgraph_edge *
2522 ipa_note_param_call (struct cgraph_node *node, int param_index,
2523 gcall *stmt, bool polymorphic)
2525 struct cgraph_edge *cs;
2527 cs = node->get_edge (stmt);
2528 cs->indirect_info->param_index = param_index;
2529 cs->indirect_info->agg_contents = 0;
2530 cs->indirect_info->member_ptr = 0;
2531 cs->indirect_info->guaranteed_unmodified = 0;
2532 ipa_node_params *info = ipa_node_params_sum->get (node);
2533 ipa_set_param_used_by_indirect_call (info, param_index, true);
2534 if (cs->indirect_info->polymorphic || polymorphic)
2535 ipa_set_param_used_by_polymorphic_call (info, param_index, true);
2536 return cs;
2539 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2540 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2541 intermediate information about each formal parameter. Currently it checks
2542 whether the call calls a pointer that is a formal parameter and if so, the
2543 parameter is marked with the called flag and an indirect call graph edge
2544 describing the call is created. This is very simple for ordinary pointers
2545 represented in SSA but not-so-nice when it comes to member pointers. The
2546 ugly part of this function does nothing more than trying to match the
2547 pattern of such a call. An example of such a pattern is the gimple dump
2548 below, the call is on the last line:
2550 <bb 2>:
2551 f$__delta_5 = f.__delta;
2552 f$__pfn_24 = f.__pfn;
2555 <bb 2>:
2556 f$__delta_5 = MEM[(struct *)&f];
2557 f$__pfn_24 = MEM[(struct *)&f + 4B];
2559 and a few lines below:
2561 <bb 5>
2562 D.2496_3 = (int) f$__pfn_24;
2563 D.2497_4 = D.2496_3 & 1;
2564 if (D.2497_4 != 0)
2565 goto <bb 3>;
2566 else
2567 goto <bb 4>;
2569 <bb 6>:
2570 D.2500_7 = (unsigned int) f$__delta_5;
2571 D.2501_8 = &S + D.2500_7;
2572 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2573 D.2503_10 = *D.2502_9;
2574 D.2504_12 = f$__pfn_24 + -1;
2575 D.2505_13 = (unsigned int) D.2504_12;
2576 D.2506_14 = D.2503_10 + D.2505_13;
2577 D.2507_15 = *D.2506_14;
2578 iftmp.11_16 = (String:: *) D.2507_15;
2580 <bb 7>:
2581 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2582 D.2500_19 = (unsigned int) f$__delta_5;
2583 D.2508_20 = &S + D.2500_19;
2584 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2586 Such patterns are results of simple calls to a member pointer:
2588 int doprinting (int (MyString::* f)(int) const)
2590 MyString S ("somestring");
2592 return (S.*f)(4);
2595 Moreover, the function also looks for called pointers loaded from aggregates
2596 passed by value or reference. */
2598 static void
2599 ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
2600 tree target)
2602 class ipa_node_params *info = fbi->info;
2603 HOST_WIDE_INT offset;
2604 bool by_ref;
2606 if (SSA_NAME_IS_DEFAULT_DEF (target))
2608 tree var = SSA_NAME_VAR (target);
2609 int index = ipa_get_param_decl_index (info, var);
2610 if (index >= 0)
2611 ipa_note_param_call (fbi->node, index, call, false);
2612 return;
2615 int index;
2616 gimple *def = SSA_NAME_DEF_STMT (target);
2617 bool guaranteed_unmodified;
2618 if (gimple_assign_single_p (def)
2619 && ipa_load_from_parm_agg (fbi, info->descriptors, def,
2620 gimple_assign_rhs1 (def), &index, &offset,
2621 NULL, &by_ref, &guaranteed_unmodified))
2623 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2624 call, false);
2625 cs->indirect_info->offset = offset;
2626 cs->indirect_info->agg_contents = 1;
2627 cs->indirect_info->by_ref = by_ref;
2628 cs->indirect_info->guaranteed_unmodified = guaranteed_unmodified;
2629 return;
2632 /* Now we need to try to match the complex pattern of calling a member
2633 pointer. */
2634 if (gimple_code (def) != GIMPLE_PHI
2635 || gimple_phi_num_args (def) != 2
2636 || !POINTER_TYPE_P (TREE_TYPE (target))
2637 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
2638 return;
2640 /* First, we need to check whether one of these is a load from a member
2641 pointer that is a parameter to this function. */
2642 tree n1 = PHI_ARG_DEF (def, 0);
2643 tree n2 = PHI_ARG_DEF (def, 1);
2644 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
2645 return;
2646 gimple *d1 = SSA_NAME_DEF_STMT (n1);
2647 gimple *d2 = SSA_NAME_DEF_STMT (n2);
2649 tree rec;
2650 basic_block bb, virt_bb;
2651 basic_block join = gimple_bb (def);
2652 if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false, &offset)))
2654 if (ipa_get_stmt_member_ptr_load_param (d2, false, NULL))
2655 return;
2657 bb = EDGE_PRED (join, 0)->src;
2658 virt_bb = gimple_bb (d2);
2660 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false, &offset)))
2662 bb = EDGE_PRED (join, 1)->src;
2663 virt_bb = gimple_bb (d1);
2665 else
2666 return;
2668 /* Second, we need to check that the basic blocks are laid out in the way
2669 corresponding to the pattern. */
2671 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
2672 || single_pred (virt_bb) != bb
2673 || single_succ (virt_bb) != join)
2674 return;
2676 /* Third, let's see that the branching is done depending on the least
2677 significant bit of the pfn. */
2679 gimple *branch = last_stmt (bb);
2680 if (!branch || gimple_code (branch) != GIMPLE_COND)
2681 return;
2683 if ((gimple_cond_code (branch) != NE_EXPR
2684 && gimple_cond_code (branch) != EQ_EXPR)
2685 || !integer_zerop (gimple_cond_rhs (branch)))
2686 return;
2688 tree cond = gimple_cond_lhs (branch);
2689 if (!ipa_is_ssa_with_stmt_def (cond))
2690 return;
2692 def = SSA_NAME_DEF_STMT (cond);
2693 if (!is_gimple_assign (def)
2694 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
2695 || !integer_onep (gimple_assign_rhs2 (def)))
2696 return;
2698 cond = gimple_assign_rhs1 (def);
2699 if (!ipa_is_ssa_with_stmt_def (cond))
2700 return;
2702 def = SSA_NAME_DEF_STMT (cond);
2704 if (is_gimple_assign (def)
2705 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
2707 cond = gimple_assign_rhs1 (def);
2708 if (!ipa_is_ssa_with_stmt_def (cond))
2709 return;
2710 def = SSA_NAME_DEF_STMT (cond);
2713 tree rec2;
2714 rec2 = ipa_get_stmt_member_ptr_load_param (def,
2715 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2716 == ptrmemfunc_vbit_in_delta),
2717 NULL);
2718 if (rec != rec2)
2719 return;
2721 index = ipa_get_param_decl_index (info, rec);
2722 if (index >= 0
2723 && parm_preserved_before_stmt_p (fbi, index, call, rec))
2725 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2726 call, false);
2727 cs->indirect_info->offset = offset;
2728 cs->indirect_info->agg_contents = 1;
2729 cs->indirect_info->member_ptr = 1;
2730 cs->indirect_info->guaranteed_unmodified = 1;
2733 return;
2736 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2737 object referenced in the expression is a formal parameter of the caller
2738 FBI->node (described by FBI->info), create a call note for the
2739 statement. */
2741 static void
2742 ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
2743 gcall *call, tree target)
2745 tree obj = OBJ_TYPE_REF_OBJECT (target);
2746 int index;
2747 HOST_WIDE_INT anc_offset;
2749 if (!flag_devirtualize)
2750 return;
2752 if (TREE_CODE (obj) != SSA_NAME)
2753 return;
2755 class ipa_node_params *info = fbi->info;
2756 if (SSA_NAME_IS_DEFAULT_DEF (obj))
2758 if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
2759 return;
2761 anc_offset = 0;
2762 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
2763 gcc_assert (index >= 0);
2764 if (detect_type_change_ssa (fbi, obj, obj_type_ref_class (target),
2765 call))
2766 return;
2768 else
2770 gimple *stmt = SSA_NAME_DEF_STMT (obj);
2771 tree expr;
2773 expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
2774 if (!expr)
2775 return;
2776 index = ipa_get_param_decl_index (info,
2777 SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
2778 gcc_assert (index >= 0);
2779 if (detect_type_change (fbi, obj, expr, obj_type_ref_class (target),
2780 call, anc_offset))
2781 return;
2784 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2785 call, true);
2786 class cgraph_indirect_call_info *ii = cs->indirect_info;
2787 ii->offset = anc_offset;
2788 ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
2789 ii->otr_type = obj_type_ref_class (target);
2790 ii->polymorphic = 1;
2793 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2794 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2795 containing intermediate information about each formal parameter. */
2797 static void
2798 ipa_analyze_call_uses (struct ipa_func_body_info *fbi, gcall *call)
2800 tree target = gimple_call_fn (call);
2802 if (!target
2803 || (TREE_CODE (target) != SSA_NAME
2804 && !virtual_method_call_p (target)))
2805 return;
2807 struct cgraph_edge *cs = fbi->node->get_edge (call);
2808 /* If we previously turned the call into a direct call, there is
2809 no need to analyze. */
2810 if (cs && !cs->indirect_unknown_callee)
2811 return;
2813 if (cs->indirect_info->polymorphic && flag_devirtualize)
2815 tree instance;
2816 tree target = gimple_call_fn (call);
2817 ipa_polymorphic_call_context context (current_function_decl,
2818 target, call, &instance);
2820 gcc_checking_assert (cs->indirect_info->otr_type
2821 == obj_type_ref_class (target));
2822 gcc_checking_assert (cs->indirect_info->otr_token
2823 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
2825 cs->indirect_info->vptr_changed
2826 = !context.get_dynamic_type (instance,
2827 OBJ_TYPE_REF_OBJECT (target),
2828 obj_type_ref_class (target), call,
2829 &fbi->aa_walk_budget);
2830 cs->indirect_info->context = context;
2833 if (TREE_CODE (target) == SSA_NAME)
2834 ipa_analyze_indirect_call_uses (fbi, call, target);
2835 else if (virtual_method_call_p (target))
2836 ipa_analyze_virtual_call_uses (fbi, call, target);
2840 /* Analyze the call statement STMT with respect to formal parameters (described
2841 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2842 formal parameters are called. */
2844 static void
2845 ipa_analyze_stmt_uses (struct ipa_func_body_info *fbi, gimple *stmt)
2847 if (is_gimple_call (stmt))
2848 ipa_analyze_call_uses (fbi, as_a <gcall *> (stmt));
2851 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2852 If OP is a parameter declaration, mark it as used in the info structure
2853 passed in DATA. */
2855 static bool
2856 visit_ref_for_mod_analysis (gimple *, tree op, tree, void *data)
2858 class ipa_node_params *info = (class ipa_node_params *) data;
2860 op = get_base_address (op);
2861 if (op
2862 && TREE_CODE (op) == PARM_DECL)
2864 int index = ipa_get_param_decl_index (info, op);
2865 gcc_assert (index >= 0);
2866 ipa_set_param_used (info, index, true);
2869 return false;
2872 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2873 the findings in various structures of the associated ipa_node_params
2874 structure, such as parameter flags, notes etc. FBI holds various data about
2875 the function being analyzed. */
2877 static void
2878 ipa_analyze_params_uses_in_bb (struct ipa_func_body_info *fbi, basic_block bb)
2880 gimple_stmt_iterator gsi;
2881 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2883 gimple *stmt = gsi_stmt (gsi);
2885 if (is_gimple_debug (stmt))
2886 continue;
2888 ipa_analyze_stmt_uses (fbi, stmt);
2889 walk_stmt_load_store_addr_ops (stmt, fbi->info,
2890 visit_ref_for_mod_analysis,
2891 visit_ref_for_mod_analysis,
2892 visit_ref_for_mod_analysis);
2894 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2895 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), fbi->info,
2896 visit_ref_for_mod_analysis,
2897 visit_ref_for_mod_analysis,
2898 visit_ref_for_mod_analysis);
2901 /* Return true EXPR is a load from a dereference of SSA_NAME NAME. */
2903 static bool
2904 load_from_dereferenced_name (tree expr, tree name)
2906 tree base = get_base_address (expr);
2907 return (TREE_CODE (base) == MEM_REF
2908 && TREE_OPERAND (base, 0) == name);
2911 /* Calculate controlled uses of parameters of NODE. */
2913 static void
2914 ipa_analyze_controlled_uses (struct cgraph_node *node)
2916 ipa_node_params *info = ipa_node_params_sum->get (node);
2918 for (int i = 0; i < ipa_get_param_count (info); i++)
2920 tree parm = ipa_get_param (info, i);
2921 int call_uses = 0;
2922 bool load_dereferenced = false;
2924 /* For SSA regs see if parameter is used. For non-SSA we compute
2925 the flag during modification analysis. */
2926 if (is_gimple_reg (parm))
2928 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl),
2929 parm);
2930 if (ddef && !has_zero_uses (ddef))
2932 imm_use_iterator imm_iter;
2933 gimple *stmt;
2935 ipa_set_param_used (info, i, true);
2936 FOR_EACH_IMM_USE_STMT (stmt, imm_iter, ddef)
2938 if (is_gimple_debug (stmt))
2939 continue;
2941 int all_stmt_uses = 0;
2942 use_operand_p use_p;
2943 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2944 all_stmt_uses++;
2946 if (is_gimple_call (stmt))
2948 if (gimple_call_internal_p (stmt))
2950 call_uses = IPA_UNDESCRIBED_USE;
2951 break;
2953 int recognized_stmt_uses;
2954 if (gimple_call_fn (stmt) == ddef)
2955 recognized_stmt_uses = 1;
2956 else
2957 recognized_stmt_uses = 0;
2958 unsigned arg_count = gimple_call_num_args (stmt);
2959 for (unsigned i = 0; i < arg_count; i++)
2961 tree arg = gimple_call_arg (stmt, i);
2962 if (arg == ddef)
2963 recognized_stmt_uses++;
2964 else if (load_from_dereferenced_name (arg, ddef))
2966 load_dereferenced = true;
2967 recognized_stmt_uses++;
2971 if (recognized_stmt_uses != all_stmt_uses)
2973 call_uses = IPA_UNDESCRIBED_USE;
2974 break;
2976 if (call_uses >= 0)
2977 call_uses += all_stmt_uses;
2979 else if (gimple_assign_single_p (stmt))
2981 tree rhs = gimple_assign_rhs1 (stmt);
2982 if (all_stmt_uses != 1
2983 || !load_from_dereferenced_name (rhs, ddef))
2985 call_uses = IPA_UNDESCRIBED_USE;
2986 break;
2988 load_dereferenced = true;
2990 else
2992 call_uses = IPA_UNDESCRIBED_USE;
2993 break;
2997 else
2998 call_uses = 0;
3000 else
3001 call_uses = IPA_UNDESCRIBED_USE;
3002 ipa_set_controlled_uses (info, i, call_uses);
3003 ipa_set_param_load_dereferenced (info, i, load_dereferenced);
3007 /* Free stuff in BI. */
3009 static void
3010 free_ipa_bb_info (struct ipa_bb_info *bi)
3012 bi->cg_edges.release ();
3013 bi->param_aa_statuses.release ();
3016 /* Dominator walker driving the analysis. */
3018 class analysis_dom_walker : public dom_walker
3020 public:
3021 analysis_dom_walker (struct ipa_func_body_info *fbi)
3022 : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
3024 edge before_dom_children (basic_block) final override;
3026 private:
3027 struct ipa_func_body_info *m_fbi;
3030 edge
3031 analysis_dom_walker::before_dom_children (basic_block bb)
3033 ipa_analyze_params_uses_in_bb (m_fbi, bb);
3034 ipa_compute_jump_functions_for_bb (m_fbi, bb);
3035 return NULL;
3038 /* Release body info FBI. */
3040 void
3041 ipa_release_body_info (struct ipa_func_body_info *fbi)
3043 int i;
3044 struct ipa_bb_info *bi;
3046 FOR_EACH_VEC_ELT (fbi->bb_infos, i, bi)
3047 free_ipa_bb_info (bi);
3048 fbi->bb_infos.release ();
3051 /* Initialize the array describing properties of formal parameters
3052 of NODE, analyze their uses and compute jump functions associated
3053 with actual arguments of calls from within NODE. */
3055 void
3056 ipa_analyze_node (struct cgraph_node *node)
3058 struct ipa_func_body_info fbi;
3059 class ipa_node_params *info;
3061 ipa_check_create_node_params ();
3062 ipa_check_create_edge_args ();
3063 info = ipa_node_params_sum->get_create (node);
3065 if (info->analysis_done)
3066 return;
3067 info->analysis_done = 1;
3069 if (ipa_func_spec_opts_forbid_analysis_p (node)
3070 || (count_formal_params (node->decl)
3071 >= (1 << IPA_PROP_ARG_INDEX_LIMIT_BITS)))
3073 gcc_assert (!ipa_get_param_count (info));
3074 return;
3077 struct function *func = DECL_STRUCT_FUNCTION (node->decl);
3078 push_cfun (func);
3079 calculate_dominance_info (CDI_DOMINATORS);
3080 ipa_initialize_node_params (node);
3081 ipa_analyze_controlled_uses (node);
3083 fbi.node = node;
3084 fbi.info = info;
3085 fbi.bb_infos = vNULL;
3086 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
3087 fbi.param_count = ipa_get_param_count (info);
3088 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
3090 for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
3092 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3093 bi->cg_edges.safe_push (cs);
3096 for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
3098 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3099 bi->cg_edges.safe_push (cs);
3102 analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3104 ipa_release_body_info (&fbi);
3105 free_dominance_info (CDI_DOMINATORS);
3106 pop_cfun ();
3109 /* Update the jump functions associated with call graph edge E when the call
3110 graph edge CS is being inlined, assuming that E->caller is already (possibly
3111 indirectly) inlined into CS->callee and that E has not been inlined. */
3113 static void
3114 update_jump_functions_after_inlining (struct cgraph_edge *cs,
3115 struct cgraph_edge *e)
3117 ipa_edge_args *top = ipa_edge_args_sum->get (cs);
3118 ipa_edge_args *args = ipa_edge_args_sum->get (e);
3119 if (!args)
3120 return;
3121 int count = ipa_get_cs_argument_count (args);
3122 int i;
3124 for (i = 0; i < count; i++)
3126 struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
3127 class ipa_polymorphic_call_context *dst_ctx
3128 = ipa_get_ith_polymorhic_call_context (args, i);
3130 if (dst->agg.items)
3132 struct ipa_agg_jf_item *item;
3133 int j;
3135 FOR_EACH_VEC_ELT (*dst->agg.items, j, item)
3137 int dst_fid;
3138 struct ipa_jump_func *src;
3140 if (item->jftype != IPA_JF_PASS_THROUGH
3141 && item->jftype != IPA_JF_LOAD_AGG)
3142 continue;
3144 dst_fid = item->value.pass_through.formal_id;
3145 if (!top || dst_fid >= ipa_get_cs_argument_count (top))
3147 item->jftype = IPA_JF_UNKNOWN;
3148 continue;
3151 item->value.pass_through.formal_id = -1;
3152 src = ipa_get_ith_jump_func (top, dst_fid);
3153 if (src->type == IPA_JF_CONST)
3155 if (item->jftype == IPA_JF_PASS_THROUGH
3156 && item->value.pass_through.operation == NOP_EXPR)
3158 item->jftype = IPA_JF_CONST;
3159 item->value.constant = src->value.constant.value;
3160 continue;
3163 else if (src->type == IPA_JF_PASS_THROUGH
3164 && src->value.pass_through.operation == NOP_EXPR)
3166 if (item->jftype == IPA_JF_PASS_THROUGH
3167 || !item->value.load_agg.by_ref
3168 || src->value.pass_through.agg_preserved)
3169 item->value.pass_through.formal_id
3170 = src->value.pass_through.formal_id;
3172 else if (src->type == IPA_JF_ANCESTOR)
3174 if (item->jftype == IPA_JF_PASS_THROUGH)
3176 if (!src->value.ancestor.offset)
3177 item->value.pass_through.formal_id
3178 = src->value.ancestor.formal_id;
3180 else if (src->value.ancestor.agg_preserved)
3182 gcc_checking_assert (item->value.load_agg.by_ref);
3184 item->value.pass_through.formal_id
3185 = src->value.ancestor.formal_id;
3186 item->value.load_agg.offset
3187 += src->value.ancestor.offset;
3191 if (item->value.pass_through.formal_id < 0)
3192 item->jftype = IPA_JF_UNKNOWN;
3196 if (!top)
3198 ipa_set_jf_unknown (dst);
3199 continue;
3202 if (dst->type == IPA_JF_ANCESTOR)
3204 struct ipa_jump_func *src;
3205 int dst_fid = dst->value.ancestor.formal_id;
3206 class ipa_polymorphic_call_context *src_ctx
3207 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3209 /* Variable number of arguments can cause havoc if we try to access
3210 one that does not exist in the inlined edge. So make sure we
3211 don't. */
3212 if (dst_fid >= ipa_get_cs_argument_count (top))
3214 ipa_set_jf_unknown (dst);
3215 continue;
3218 src = ipa_get_ith_jump_func (top, dst_fid);
3220 if (src_ctx && !src_ctx->useless_p ())
3222 class ipa_polymorphic_call_context ctx = *src_ctx;
3224 /* TODO: Make type preserved safe WRT contexts. */
3225 if (!ipa_get_jf_ancestor_type_preserved (dst))
3226 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3227 ctx.offset_by (dst->value.ancestor.offset);
3228 if (!ctx.useless_p ())
3230 if (!dst_ctx)
3232 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3233 count, true);
3234 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3237 dst_ctx->combine_with (ctx);
3241 /* Parameter and argument in ancestor jump function must be pointer
3242 type, which means access to aggregate must be by-reference. */
3243 gcc_assert (!src->agg.items || src->agg.by_ref);
3245 if (src->agg.items && dst->value.ancestor.agg_preserved)
3247 struct ipa_agg_jf_item *item;
3248 int j;
3250 /* Currently we do not produce clobber aggregate jump functions,
3251 replace with merging when we do. */
3252 gcc_assert (!dst->agg.items);
3254 dst->agg.items = vec_safe_copy (src->agg.items);
3255 dst->agg.by_ref = src->agg.by_ref;
3256 FOR_EACH_VEC_SAFE_ELT (dst->agg.items, j, item)
3257 item->offset -= dst->value.ancestor.offset;
3260 if (src->type == IPA_JF_PASS_THROUGH
3261 && src->value.pass_through.operation == NOP_EXPR)
3263 dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
3264 dst->value.ancestor.agg_preserved &=
3265 src->value.pass_through.agg_preserved;
3267 else if (src->type == IPA_JF_ANCESTOR)
3269 dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
3270 dst->value.ancestor.offset += src->value.ancestor.offset;
3271 dst->value.ancestor.agg_preserved &=
3272 src->value.ancestor.agg_preserved;
3273 dst->value.ancestor.keep_null |= src->value.ancestor.keep_null;
3275 else
3276 ipa_set_jf_unknown (dst);
3278 else if (dst->type == IPA_JF_PASS_THROUGH)
3280 struct ipa_jump_func *src;
3281 /* We must check range due to calls with variable number of arguments
3282 and we cannot combine jump functions with operations. */
3283 if (dst->value.pass_through.operation == NOP_EXPR
3284 && (top && dst->value.pass_through.formal_id
3285 < ipa_get_cs_argument_count (top)))
3287 int dst_fid = dst->value.pass_through.formal_id;
3288 src = ipa_get_ith_jump_func (top, dst_fid);
3289 bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
3290 class ipa_polymorphic_call_context *src_ctx
3291 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3293 if (src_ctx && !src_ctx->useless_p ())
3295 class ipa_polymorphic_call_context ctx = *src_ctx;
3297 /* TODO: Make type preserved safe WRT contexts. */
3298 if (!ipa_get_jf_pass_through_type_preserved (dst))
3299 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3300 if (!ctx.useless_p ())
3302 if (!dst_ctx)
3304 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3305 count, true);
3306 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3308 dst_ctx->combine_with (ctx);
3311 switch (src->type)
3313 case IPA_JF_UNKNOWN:
3314 ipa_set_jf_unknown (dst);
3315 break;
3316 case IPA_JF_CONST:
3317 ipa_set_jf_cst_copy (dst, src);
3318 break;
3320 case IPA_JF_PASS_THROUGH:
3322 int formal_id = ipa_get_jf_pass_through_formal_id (src);
3323 enum tree_code operation;
3324 operation = ipa_get_jf_pass_through_operation (src);
3326 if (operation == NOP_EXPR)
3328 bool agg_p;
3329 agg_p = dst_agg_p
3330 && ipa_get_jf_pass_through_agg_preserved (src);
3331 ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
3333 else if (TREE_CODE_CLASS (operation) == tcc_unary)
3334 ipa_set_jf_unary_pass_through (dst, formal_id, operation);
3335 else
3337 tree operand = ipa_get_jf_pass_through_operand (src);
3338 ipa_set_jf_arith_pass_through (dst, formal_id, operand,
3339 operation);
3341 break;
3343 case IPA_JF_ANCESTOR:
3345 bool agg_p;
3346 agg_p = dst_agg_p
3347 && ipa_get_jf_ancestor_agg_preserved (src);
3348 ipa_set_ancestor_jf (dst,
3349 ipa_get_jf_ancestor_offset (src),
3350 ipa_get_jf_ancestor_formal_id (src),
3351 agg_p,
3352 ipa_get_jf_ancestor_keep_null (src));
3353 break;
3355 default:
3356 gcc_unreachable ();
3359 if (src->agg.items
3360 && (dst_agg_p || !src->agg.by_ref))
3362 /* Currently we do not produce clobber aggregate jump
3363 functions, replace with merging when we do. */
3364 gcc_assert (!dst->agg.items);
3366 dst->agg.by_ref = src->agg.by_ref;
3367 dst->agg.items = vec_safe_copy (src->agg.items);
3370 else
3371 ipa_set_jf_unknown (dst);
3376 /* If TARGET is an addr_expr of a function declaration, make it the
3377 (SPECULATIVE)destination of an indirect edge IE and return the edge.
3378 Otherwise, return NULL. */
3380 struct cgraph_edge *
3381 ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
3382 bool speculative)
3384 struct cgraph_node *callee;
3385 bool unreachable = false;
3387 if (TREE_CODE (target) == ADDR_EXPR)
3388 target = TREE_OPERAND (target, 0);
3389 if (TREE_CODE (target) != FUNCTION_DECL)
3391 target = canonicalize_constructor_val (target, NULL);
3392 if (!target || TREE_CODE (target) != FUNCTION_DECL)
3394 /* Member pointer call that goes through a VMT lookup. */
3395 if (ie->indirect_info->member_ptr
3396 /* Or if target is not an invariant expression and we do not
3397 know if it will evaulate to function at runtime.
3398 This can happen when folding through &VAR, where &VAR
3399 is IP invariant, but VAR itself is not.
3401 TODO: Revisit this when GCC 5 is branched. It seems that
3402 member_ptr check is not needed and that we may try to fold
3403 the expression and see if VAR is readonly. */
3404 || !is_gimple_ip_invariant (target))
3406 if (dump_enabled_p ())
3408 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3409 "discovered direct call non-invariant %s\n",
3410 ie->caller->dump_name ());
3412 return NULL;
3416 if (dump_enabled_p ())
3418 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3419 "discovered direct call to non-function in %s, "
3420 "making it __builtin_unreachable\n",
3421 ie->caller->dump_name ());
3424 target = builtin_decl_unreachable ();
3425 callee = cgraph_node::get_create (target);
3426 unreachable = true;
3428 else
3429 callee = cgraph_node::get (target);
3431 else
3432 callee = cgraph_node::get (target);
3434 /* Because may-edges are not explicitely represented and vtable may be external,
3435 we may create the first reference to the object in the unit. */
3436 if (!callee || callee->inlined_to)
3439 /* We are better to ensure we can refer to it.
3440 In the case of static functions we are out of luck, since we already
3441 removed its body. In the case of public functions we may or may
3442 not introduce the reference. */
3443 if (!canonicalize_constructor_val (target, NULL)
3444 || !TREE_PUBLIC (target))
3446 if (dump_file)
3447 fprintf (dump_file, "ipa-prop: Discovered call to a known target "
3448 "(%s -> %s) but cannot refer to it. Giving up.\n",
3449 ie->caller->dump_name (),
3450 ie->callee->dump_name ());
3451 return NULL;
3453 callee = cgraph_node::get_create (target);
3456 /* If the edge is already speculated. */
3457 if (speculative && ie->speculative)
3459 if (dump_file)
3461 cgraph_edge *e2 = ie->speculative_call_for_target (callee);
3462 if (!e2)
3464 if (dump_file)
3465 fprintf (dump_file, "ipa-prop: Discovered call to a "
3466 "speculative target (%s -> %s) but the call is "
3467 "already speculated to different target. "
3468 "Giving up.\n",
3469 ie->caller->dump_name (), callee->dump_name ());
3471 else
3473 if (dump_file)
3474 fprintf (dump_file,
3475 "ipa-prop: Discovered call to a speculative target "
3476 "(%s -> %s) this agree with previous speculation.\n",
3477 ie->caller->dump_name (), callee->dump_name ());
3480 return NULL;
3483 if (!dbg_cnt (devirt))
3484 return NULL;
3486 ipa_check_create_node_params ();
3488 /* We cannot make edges to inline clones. It is bug that someone removed
3489 the cgraph node too early. */
3490 gcc_assert (!callee->inlined_to);
3492 if (dump_file && !unreachable)
3494 fprintf (dump_file, "ipa-prop: Discovered %s call to a %s target "
3495 "(%s -> %s), for stmt ",
3496 ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
3497 speculative ? "speculative" : "known",
3498 ie->caller->dump_name (),
3499 callee->dump_name ());
3500 if (ie->call_stmt)
3501 print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
3502 else
3503 fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
3505 if (dump_enabled_p ())
3507 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3508 "converting indirect call in %s to direct call to %s\n",
3509 ie->caller->dump_name (), callee->dump_name ());
3511 if (!speculative)
3513 struct cgraph_edge *orig = ie;
3514 ie = cgraph_edge::make_direct (ie, callee);
3515 /* If we resolved speculative edge the cost is already up to date
3516 for direct call (adjusted by inline_edge_duplication_hook). */
3517 if (ie == orig)
3519 ipa_call_summary *es = ipa_call_summaries->get (ie);
3520 es->call_stmt_size -= (eni_size_weights.indirect_call_cost
3521 - eni_size_weights.call_cost);
3522 es->call_stmt_time -= (eni_time_weights.indirect_call_cost
3523 - eni_time_weights.call_cost);
3526 else
3528 if (!callee->can_be_discarded_p ())
3530 cgraph_node *alias;
3531 alias = dyn_cast<cgraph_node *> (callee->noninterposable_alias ());
3532 if (alias)
3533 callee = alias;
3535 /* make_speculative will update ie's cost to direct call cost. */
3536 ie = ie->make_speculative
3537 (callee, ie->count.apply_scale (8, 10));
3540 return ie;
3543 /* Attempt to locate an interprocedural constant at a given REQ_OFFSET in
3544 CONSTRUCTOR and return it. Return NULL if the search fails for some
3545 reason. */
3547 static tree
3548 find_constructor_constant_at_offset (tree constructor, HOST_WIDE_INT req_offset)
3550 tree type = TREE_TYPE (constructor);
3551 if (TREE_CODE (type) != ARRAY_TYPE
3552 && TREE_CODE (type) != RECORD_TYPE)
3553 return NULL;
3555 unsigned ix;
3556 tree index, val;
3557 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (constructor), ix, index, val)
3559 HOST_WIDE_INT elt_offset;
3560 if (TREE_CODE (type) == ARRAY_TYPE)
3562 offset_int off;
3563 tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
3564 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3566 if (index)
3568 if (TREE_CODE (index) == RANGE_EXPR)
3569 off = wi::to_offset (TREE_OPERAND (index, 0));
3570 else
3571 off = wi::to_offset (index);
3572 if (TYPE_DOMAIN (type) && TYPE_MIN_VALUE (TYPE_DOMAIN (type)))
3574 tree low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
3575 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3576 off = wi::sext (off - wi::to_offset (low_bound),
3577 TYPE_PRECISION (TREE_TYPE (index)));
3579 off *= wi::to_offset (unit_size);
3580 /* ??? Handle more than just the first index of a
3581 RANGE_EXPR. */
3583 else
3584 off = wi::to_offset (unit_size) * ix;
3586 off = wi::lshift (off, LOG2_BITS_PER_UNIT);
3587 if (!wi::fits_shwi_p (off) || wi::neg_p (off))
3588 continue;
3589 elt_offset = off.to_shwi ();
3591 else if (TREE_CODE (type) == RECORD_TYPE)
3593 gcc_checking_assert (index && TREE_CODE (index) == FIELD_DECL);
3594 if (DECL_BIT_FIELD (index))
3595 continue;
3596 elt_offset = int_bit_position (index);
3598 else
3599 gcc_unreachable ();
3601 if (elt_offset > req_offset)
3602 return NULL;
3604 if (TREE_CODE (val) == CONSTRUCTOR)
3605 return find_constructor_constant_at_offset (val,
3606 req_offset - elt_offset);
3608 if (elt_offset == req_offset
3609 && is_gimple_reg_type (TREE_TYPE (val))
3610 && is_gimple_ip_invariant (val))
3611 return val;
3613 return NULL;
3616 /* Check whether SCALAR could be used to look up an aggregate interprocedural
3617 invariant from a static constructor and if so, return it. Otherwise return
3618 NULL. */
3620 tree
3621 ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset, bool by_ref)
3623 if (by_ref)
3625 if (TREE_CODE (scalar) != ADDR_EXPR)
3626 return NULL;
3627 scalar = TREE_OPERAND (scalar, 0);
3630 if (!VAR_P (scalar)
3631 || !is_global_var (scalar)
3632 || !TREE_READONLY (scalar)
3633 || !DECL_INITIAL (scalar)
3634 || TREE_CODE (DECL_INITIAL (scalar)) != CONSTRUCTOR)
3635 return NULL;
3637 return find_constructor_constant_at_offset (DECL_INITIAL (scalar), offset);
3640 /* Retrieve value from AGG_JFUNC for the given OFFSET or return NULL if there
3641 is none. BY_REF specifies whether the value has to be passed by reference
3642 or by value. */
3644 static tree
3645 ipa_find_agg_cst_from_jfunc_items (struct ipa_agg_jump_function *agg_jfunc,
3646 ipa_node_params *src_info,
3647 cgraph_node *src_node,
3648 HOST_WIDE_INT offset, bool by_ref)
3650 if (by_ref != agg_jfunc->by_ref)
3651 return NULL_TREE;
3653 for (const ipa_agg_jf_item &item : agg_jfunc->items)
3654 if (item.offset == offset)
3655 return ipa_agg_value_from_jfunc (src_info, src_node, &item);
3657 return NULL_TREE;
3660 /* Remove a reference to SYMBOL from the list of references of a node given by
3661 reference description RDESC. Return true if the reference has been
3662 successfully found and removed. */
3664 static bool
3665 remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
3667 struct ipa_ref *to_del;
3668 struct cgraph_edge *origin;
3670 origin = rdesc->cs;
3671 if (!origin)
3672 return false;
3673 to_del = origin->caller->find_reference (symbol, origin->call_stmt,
3674 origin->lto_stmt_uid);
3675 if (!to_del)
3676 return false;
3678 to_del->remove_reference ();
3679 if (dump_file)
3680 fprintf (dump_file, "ipa-prop: Removed a reference from %s to %s.\n",
3681 origin->caller->dump_name (), symbol->dump_name ());
3682 return true;
3685 /* If JFUNC has a reference description with refcount different from
3686 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
3687 NULL. JFUNC must be a constant jump function. */
3689 static struct ipa_cst_ref_desc *
3690 jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
3692 struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
3693 if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
3694 return rdesc;
3695 else
3696 return NULL;
3699 /* If the value of constant jump function JFUNC is an address of a function
3700 declaration, return the associated call graph node. Otherwise return
3701 NULL. */
3703 static symtab_node *
3704 symtab_node_for_jfunc (struct ipa_jump_func *jfunc)
3706 gcc_checking_assert (jfunc->type == IPA_JF_CONST);
3707 tree cst = ipa_get_jf_constant (jfunc);
3708 if (TREE_CODE (cst) != ADDR_EXPR
3709 || (TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL
3710 && TREE_CODE (TREE_OPERAND (cst, 0)) != VAR_DECL))
3711 return NULL;
3713 return symtab_node::get (TREE_OPERAND (cst, 0));
3717 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
3718 refcount and if it hits zero, remove reference to SYMBOL from the caller of
3719 the edge specified in the rdesc. Return false if either the symbol or the
3720 reference could not be found, otherwise return true. */
3722 static bool
3723 try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
3725 struct ipa_cst_ref_desc *rdesc;
3726 if (jfunc->type == IPA_JF_CONST
3727 && (rdesc = jfunc_rdesc_usable (jfunc))
3728 && --rdesc->refcount == 0)
3730 symtab_node *symbol = symtab_node_for_jfunc (jfunc);
3731 if (!symbol)
3732 return false;
3734 return remove_described_reference (symbol, rdesc);
3736 return true;
3739 /* Try to find a destination for indirect edge IE that corresponds to a simple
3740 call or a call of a member function pointer and where the destination is a
3741 pointer formal parameter described by jump function JFUNC. TARGET_TYPE is
3742 the type of the parameter to which the result of JFUNC is passed. If it can
3743 be determined, return the newly direct edge, otherwise return NULL.
3744 NEW_ROOT and NEW_ROOT_INFO is the node and its info that JFUNC lattices are
3745 relative to. */
3747 static struct cgraph_edge *
3748 try_make_edge_direct_simple_call (struct cgraph_edge *ie,
3749 struct ipa_jump_func *jfunc, tree target_type,
3750 struct cgraph_node *new_root,
3751 class ipa_node_params *new_root_info)
3753 struct cgraph_edge *cs;
3754 tree target = NULL_TREE;
3755 bool agg_contents = ie->indirect_info->agg_contents;
3756 tree scalar = ipa_value_from_jfunc (new_root_info, jfunc, target_type);
3757 if (agg_contents)
3759 if (scalar)
3760 target = ipa_find_agg_cst_from_init (scalar, ie->indirect_info->offset,
3761 ie->indirect_info->by_ref);
3762 if (!target && ie->indirect_info->guaranteed_unmodified)
3763 target = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3764 new_root,
3765 ie->indirect_info->offset,
3766 ie->indirect_info->by_ref);
3768 else
3769 target = scalar;
3770 if (!target)
3771 return NULL;
3772 cs = ipa_make_edge_direct_to_target (ie, target);
3774 if (cs && !agg_contents)
3776 bool ok;
3777 gcc_checking_assert (cs->callee
3778 && (cs != ie
3779 || jfunc->type != IPA_JF_CONST
3780 || !symtab_node_for_jfunc (jfunc)
3781 || cs->callee == symtab_node_for_jfunc (jfunc)));
3782 ok = try_decrement_rdesc_refcount (jfunc);
3783 gcc_checking_assert (ok);
3786 return cs;
3789 /* Return the target to be used in cases of impossible devirtualization. IE
3790 and target (the latter can be NULL) are dumped when dumping is enabled. */
3792 tree
3793 ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
3795 if (dump_file)
3797 if (target)
3798 fprintf (dump_file,
3799 "Type inconsistent devirtualization: %s->%s\n",
3800 ie->caller->dump_name (),
3801 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
3802 else
3803 fprintf (dump_file,
3804 "No devirtualization target in %s\n",
3805 ie->caller->dump_name ());
3807 tree new_target = builtin_decl_unreachable ();
3808 cgraph_node::get_create (new_target);
3809 return new_target;
3812 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3813 call based on a formal parameter which is described by jump function JFUNC
3814 and if it can be determined, make it direct and return the direct edge.
3815 Otherwise, return NULL. CTX describes the polymorphic context that the
3816 parameter the call is based on brings along with it. NEW_ROOT and
3817 NEW_ROOT_INFO is the node and its info that JFUNC lattices are relative
3818 to. */
3820 static struct cgraph_edge *
3821 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
3822 struct ipa_jump_func *jfunc,
3823 class ipa_polymorphic_call_context ctx,
3824 struct cgraph_node *new_root,
3825 class ipa_node_params *new_root_info)
3827 tree target = NULL;
3828 bool speculative = false;
3830 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
3831 return NULL;
3833 gcc_assert (!ie->indirect_info->by_ref);
3835 /* Try to do lookup via known virtual table pointer value. */
3836 if (!ie->indirect_info->vptr_changed
3837 || opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively))
3839 tree vtable;
3840 unsigned HOST_WIDE_INT offset;
3841 tree t = NULL_TREE;
3842 if (jfunc->type == IPA_JF_CONST)
3843 t = ipa_find_agg_cst_from_init (ipa_get_jf_constant (jfunc),
3844 ie->indirect_info->offset, true);
3845 if (!t)
3846 t = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3847 new_root,
3848 ie->indirect_info->offset, true);
3849 if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
3851 bool can_refer;
3852 t = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
3853 vtable, offset, &can_refer);
3854 if (can_refer)
3856 if (!t
3857 || fndecl_built_in_p (t, BUILT_IN_UNREACHABLE)
3858 || fndecl_built_in_p (t, BUILT_IN_UNREACHABLE_TRAP)
3859 || !possible_polymorphic_call_target_p
3860 (ie, cgraph_node::get (t)))
3862 /* Do not speculate builtin_unreachable, it is stupid! */
3863 if (!ie->indirect_info->vptr_changed)
3864 target = ipa_impossible_devirt_target (ie, target);
3865 else
3866 target = NULL;
3868 else
3870 target = t;
3871 speculative = ie->indirect_info->vptr_changed;
3877 ipa_polymorphic_call_context ie_context (ie);
3878 vec <cgraph_node *>targets;
3879 bool final;
3881 ctx.offset_by (ie->indirect_info->offset);
3882 if (ie->indirect_info->vptr_changed)
3883 ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3884 ie->indirect_info->otr_type);
3885 ctx.combine_with (ie_context, ie->indirect_info->otr_type);
3886 targets = possible_polymorphic_call_targets
3887 (ie->indirect_info->otr_type,
3888 ie->indirect_info->otr_token,
3889 ctx, &final);
3890 if (final && targets.length () <= 1)
3892 speculative = false;
3893 if (targets.length () == 1)
3894 target = targets[0]->decl;
3895 else
3896 target = ipa_impossible_devirt_target (ie, NULL_TREE);
3898 else if (!target && opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
3899 && !ie->speculative && ie->maybe_hot_p ())
3901 cgraph_node *n;
3902 n = try_speculative_devirtualization (ie->indirect_info->otr_type,
3903 ie->indirect_info->otr_token,
3904 ie->indirect_info->context);
3905 if (n)
3907 target = n->decl;
3908 speculative = true;
3912 if (target)
3914 if (!possible_polymorphic_call_target_p
3915 (ie, cgraph_node::get_create (target)))
3917 if (speculative)
3918 return NULL;
3919 target = ipa_impossible_devirt_target (ie, target);
3921 return ipa_make_edge_direct_to_target (ie, target, speculative);
3923 else
3924 return NULL;
3927 /* Update the param called notes associated with NODE when CS is being inlined,
3928 assuming NODE is (potentially indirectly) inlined into CS->callee.
3929 Moreover, if the callee is discovered to be constant, create a new cgraph
3930 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
3931 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
3933 static bool
3934 update_indirect_edges_after_inlining (struct cgraph_edge *cs,
3935 struct cgraph_node *node,
3936 vec<cgraph_edge *> *new_edges)
3938 class ipa_edge_args *top;
3939 struct cgraph_edge *ie, *next_ie, *new_direct_edge;
3940 struct cgraph_node *new_root;
3941 class ipa_node_params *new_root_info, *inlined_node_info;
3942 bool res = false;
3944 ipa_check_create_edge_args ();
3945 top = ipa_edge_args_sum->get (cs);
3946 new_root = cs->caller->inlined_to
3947 ? cs->caller->inlined_to : cs->caller;
3948 new_root_info = ipa_node_params_sum->get (new_root);
3949 inlined_node_info = ipa_node_params_sum->get (cs->callee->function_symbol ());
3951 for (ie = node->indirect_calls; ie; ie = next_ie)
3953 class cgraph_indirect_call_info *ici = ie->indirect_info;
3954 struct ipa_jump_func *jfunc;
3955 int param_index;
3957 next_ie = ie->next_callee;
3959 if (ici->param_index == -1)
3960 continue;
3962 /* We must check range due to calls with variable number of arguments: */
3963 if (!top || ici->param_index >= ipa_get_cs_argument_count (top))
3965 ici->param_index = -1;
3966 continue;
3969 param_index = ici->param_index;
3970 jfunc = ipa_get_ith_jump_func (top, param_index);
3972 auto_vec<cgraph_node *, 4> spec_targets;
3973 if (ie->speculative)
3974 for (cgraph_edge *direct = ie->first_speculative_call_target ();
3975 direct;
3976 direct = direct->next_speculative_call_target ())
3977 spec_targets.safe_push (direct->callee);
3979 if (!opt_for_fn (node->decl, flag_indirect_inlining))
3980 new_direct_edge = NULL;
3981 else if (ici->polymorphic)
3983 ipa_polymorphic_call_context ctx;
3984 ctx = ipa_context_from_jfunc (new_root_info, cs, param_index, jfunc);
3985 new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx,
3986 new_root,
3987 new_root_info);
3989 else
3991 tree target_type = ipa_get_type (inlined_node_info, param_index);
3992 new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
3993 target_type,
3994 new_root,
3995 new_root_info);
3998 /* If speculation was removed, then we need to do nothing. */
3999 if (new_direct_edge && new_direct_edge != ie
4000 && spec_targets.contains (new_direct_edge->callee))
4002 new_direct_edge->indirect_inlining_edge = 1;
4003 res = true;
4004 if (!new_direct_edge->speculative)
4005 continue;
4007 else if (new_direct_edge)
4009 new_direct_edge->indirect_inlining_edge = 1;
4010 if (new_edges)
4012 new_edges->safe_push (new_direct_edge);
4013 res = true;
4015 /* If speculative edge was introduced we still need to update
4016 call info of the indirect edge. */
4017 if (!new_direct_edge->speculative)
4018 continue;
4020 if (jfunc->type == IPA_JF_PASS_THROUGH
4021 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4023 if (ici->agg_contents
4024 && !ipa_get_jf_pass_through_agg_preserved (jfunc)
4025 && !ici->polymorphic)
4026 ici->param_index = -1;
4027 else
4029 ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
4030 if (ici->polymorphic
4031 && !ipa_get_jf_pass_through_type_preserved (jfunc))
4032 ici->vptr_changed = true;
4033 ipa_set_param_used_by_indirect_call (new_root_info,
4034 ici->param_index, true);
4035 if (ici->polymorphic)
4036 ipa_set_param_used_by_polymorphic_call (new_root_info,
4037 ici->param_index, true);
4040 else if (jfunc->type == IPA_JF_ANCESTOR)
4042 if (ici->agg_contents
4043 && !ipa_get_jf_ancestor_agg_preserved (jfunc)
4044 && !ici->polymorphic)
4045 ici->param_index = -1;
4046 else
4048 ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
4049 ici->offset += ipa_get_jf_ancestor_offset (jfunc);
4050 if (ici->polymorphic
4051 && !ipa_get_jf_ancestor_type_preserved (jfunc))
4052 ici->vptr_changed = true;
4053 ipa_set_param_used_by_indirect_call (new_root_info,
4054 ici->param_index, true);
4055 if (ici->polymorphic)
4056 ipa_set_param_used_by_polymorphic_call (new_root_info,
4057 ici->param_index, true);
4060 else
4061 /* Either we can find a destination for this edge now or never. */
4062 ici->param_index = -1;
4065 return res;
4068 /* Recursively traverse subtree of NODE (including node) made of inlined
4069 cgraph_edges when CS has been inlined and invoke
4070 update_indirect_edges_after_inlining on all nodes and
4071 update_jump_functions_after_inlining on all non-inlined edges that lead out
4072 of this subtree. Newly discovered indirect edges will be added to
4073 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
4074 created. */
4076 static bool
4077 propagate_info_to_inlined_callees (struct cgraph_edge *cs,
4078 struct cgraph_node *node,
4079 vec<cgraph_edge *> *new_edges)
4081 struct cgraph_edge *e;
4082 bool res;
4084 res = update_indirect_edges_after_inlining (cs, node, new_edges);
4086 for (e = node->callees; e; e = e->next_callee)
4087 if (!e->inline_failed)
4088 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
4089 else
4090 update_jump_functions_after_inlining (cs, e);
4091 for (e = node->indirect_calls; e; e = e->next_callee)
4092 update_jump_functions_after_inlining (cs, e);
4094 return res;
4097 /* Combine two controlled uses counts as done during inlining. */
4099 static int
4100 combine_controlled_uses_counters (int c, int d)
4102 if (c == IPA_UNDESCRIBED_USE || d == IPA_UNDESCRIBED_USE)
4103 return IPA_UNDESCRIBED_USE;
4104 else
4105 return c + d - 1;
4108 /* Propagate number of controlled users from CS->caleee to the new root of the
4109 tree of inlined nodes. */
4111 static void
4112 propagate_controlled_uses (struct cgraph_edge *cs)
4114 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4115 if (!args)
4116 return;
4117 struct cgraph_node *new_root = cs->caller->inlined_to
4118 ? cs->caller->inlined_to : cs->caller;
4119 ipa_node_params *new_root_info = ipa_node_params_sum->get (new_root);
4120 ipa_node_params *old_root_info = ipa_node_params_sum->get (cs->callee);
4121 int count, i;
4123 if (!old_root_info)
4124 return;
4126 count = MIN (ipa_get_cs_argument_count (args),
4127 ipa_get_param_count (old_root_info));
4128 for (i = 0; i < count; i++)
4130 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4131 struct ipa_cst_ref_desc *rdesc;
4133 if (jf->type == IPA_JF_PASS_THROUGH)
4135 int src_idx, c, d;
4136 src_idx = ipa_get_jf_pass_through_formal_id (jf);
4137 c = ipa_get_controlled_uses (new_root_info, src_idx);
4138 d = ipa_get_controlled_uses (old_root_info, i);
4140 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf)
4141 == NOP_EXPR || c == IPA_UNDESCRIBED_USE);
4142 c = combine_controlled_uses_counters (c, d);
4143 ipa_set_controlled_uses (new_root_info, src_idx, c);
4144 bool lderef = true;
4145 if (c != IPA_UNDESCRIBED_USE)
4147 lderef = (ipa_get_param_load_dereferenced (new_root_info, src_idx)
4148 || ipa_get_param_load_dereferenced (old_root_info, i));
4149 ipa_set_param_load_dereferenced (new_root_info, src_idx, lderef);
4152 if (c == 0 && !lderef && new_root_info->ipcp_orig_node)
4154 struct cgraph_node *n;
4155 struct ipa_ref *ref;
4156 tree t = new_root_info->known_csts[src_idx];
4158 if (t && TREE_CODE (t) == ADDR_EXPR
4159 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
4160 && (n = cgraph_node::get (TREE_OPERAND (t, 0)))
4161 && (ref = new_root->find_reference (n, NULL, 0)))
4163 if (dump_file)
4164 fprintf (dump_file, "ipa-prop: Removing cloning-created "
4165 "reference from %s to %s.\n",
4166 new_root->dump_name (),
4167 n->dump_name ());
4168 ref->remove_reference ();
4172 else if (jf->type == IPA_JF_CONST
4173 && (rdesc = jfunc_rdesc_usable (jf)))
4175 int d = ipa_get_controlled_uses (old_root_info, i);
4176 int c = rdesc->refcount;
4177 tree cst = ipa_get_jf_constant (jf);
4178 rdesc->refcount = combine_controlled_uses_counters (c, d);
4179 if (rdesc->refcount != IPA_UNDESCRIBED_USE
4180 && ipa_get_param_load_dereferenced (old_root_info, i)
4181 && TREE_CODE (cst) == ADDR_EXPR
4182 && TREE_CODE (TREE_OPERAND (cst, 0)) == VAR_DECL)
4184 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4185 new_root->create_reference (n, IPA_REF_LOAD, NULL);
4186 if (dump_file)
4187 fprintf (dump_file, "ipa-prop: Address IPA constant will reach "
4188 "a load so adding LOAD reference from %s to %s.\n",
4189 new_root->dump_name (), n->dump_name ());
4191 if (rdesc->refcount == 0)
4193 gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
4194 && ((TREE_CODE (TREE_OPERAND (cst, 0))
4195 == FUNCTION_DECL)
4196 || (TREE_CODE (TREE_OPERAND (cst, 0))
4197 == VAR_DECL)));
4199 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4200 if (n)
4202 remove_described_reference (n, rdesc);
4203 cgraph_node *clone = cs->caller;
4204 while (clone->inlined_to
4205 && clone->ipcp_clone
4206 && clone != rdesc->cs->caller)
4208 struct ipa_ref *ref;
4209 ref = clone->find_reference (n, NULL, 0);
4210 if (ref)
4212 if (dump_file)
4213 fprintf (dump_file, "ipa-prop: Removing "
4214 "cloning-created reference "
4215 "from %s to %s.\n",
4216 clone->dump_name (),
4217 n->dump_name ());
4218 ref->remove_reference ();
4220 clone = clone->callers->caller;
4227 for (i = ipa_get_param_count (old_root_info);
4228 i < ipa_get_cs_argument_count (args);
4229 i++)
4231 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4233 if (jf->type == IPA_JF_CONST)
4235 struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
4236 if (rdesc)
4237 rdesc->refcount = IPA_UNDESCRIBED_USE;
4239 else if (jf->type == IPA_JF_PASS_THROUGH)
4240 ipa_set_controlled_uses (new_root_info,
4241 jf->value.pass_through.formal_id,
4242 IPA_UNDESCRIBED_USE);
4246 /* Update jump functions and call note functions on inlining the call site CS.
4247 CS is expected to lead to a node already cloned by
4248 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
4249 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
4250 created. */
4252 bool
4253 ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
4254 vec<cgraph_edge *> *new_edges)
4256 bool changed;
4257 /* Do nothing if the preparation phase has not been carried out yet
4258 (i.e. during early inlining). */
4259 if (!ipa_node_params_sum)
4260 return false;
4261 gcc_assert (ipa_edge_args_sum);
4263 propagate_controlled_uses (cs);
4264 changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
4265 ipa_node_params_sum->remove (cs->callee);
4267 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4268 if (args)
4270 bool ok = true;
4271 if (args->jump_functions)
4273 struct ipa_jump_func *jf;
4274 int i;
4275 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4276 if (jf->type == IPA_JF_CONST
4277 && ipa_get_jf_constant_rdesc (jf))
4279 ok = false;
4280 break;
4283 if (ok)
4284 ipa_edge_args_sum->remove (cs);
4286 if (ipcp_transformation_sum)
4287 ipcp_transformation_sum->remove (cs->callee);
4289 return changed;
4292 /* Ensure that array of edge arguments infos is big enough to accommodate a
4293 structure for all edges and reallocates it if not. Also, allocate
4294 associated hash tables is they do not already exist. */
4296 void
4297 ipa_check_create_edge_args (void)
4299 if (!ipa_edge_args_sum)
4300 ipa_edge_args_sum
4301 = (new (ggc_alloc_no_dtor<ipa_edge_args_sum_t> ())
4302 ipa_edge_args_sum_t (symtab, true));
4303 if (!ipa_bits_hash_table)
4304 ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
4305 if (!ipa_vr_hash_table)
4306 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4309 /* Free all ipa_edge structures. */
4311 void
4312 ipa_free_all_edge_args (void)
4314 if (!ipa_edge_args_sum)
4315 return;
4317 ggc_delete (ipa_edge_args_sum);
4318 ipa_edge_args_sum = NULL;
4321 /* Free all ipa_node_params structures. */
4323 void
4324 ipa_free_all_node_params (void)
4326 if (ipa_node_params_sum)
4327 ggc_delete (ipa_node_params_sum);
4328 ipa_node_params_sum = NULL;
4331 /* Initialize IPA CP transformation summary and also allocate any necessary hash
4332 tables if they do not already exist. */
4334 void
4335 ipcp_transformation_initialize (void)
4337 if (!ipa_bits_hash_table)
4338 ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
4339 if (!ipa_vr_hash_table)
4340 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4341 if (ipcp_transformation_sum == NULL)
4343 ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab);
4344 ipcp_transformation_sum->disable_insertion_hook ();
4348 /* Release the IPA CP transformation summary. */
4350 void
4351 ipcp_free_transformation_sum (void)
4353 if (!ipcp_transformation_sum)
4354 return;
4356 ipcp_transformation_sum->~function_summary<ipcp_transformation *> ();
4357 ggc_free (ipcp_transformation_sum);
4358 ipcp_transformation_sum = NULL;
4361 /* Set the aggregate replacements of NODE to be AGGVALS. */
4363 void
4364 ipa_set_node_agg_value_chain (struct cgraph_node *node,
4365 vec<ipa_argagg_value, va_gc> *aggs)
4367 ipcp_transformation_initialize ();
4368 ipcp_transformation *s = ipcp_transformation_sum->get_create (node);
4369 s->m_agg_values = aggs;
4372 /* Hook that is called by cgraph.cc when an edge is removed. Adjust reference
4373 count data structures accordingly. */
4375 void
4376 ipa_edge_args_sum_t::remove (cgraph_edge *cs, ipa_edge_args *args)
4378 if (args->jump_functions)
4380 struct ipa_jump_func *jf;
4381 int i;
4382 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4384 struct ipa_cst_ref_desc *rdesc;
4385 try_decrement_rdesc_refcount (jf);
4386 if (jf->type == IPA_JF_CONST
4387 && (rdesc = ipa_get_jf_constant_rdesc (jf))
4388 && rdesc->cs == cs)
4389 rdesc->cs = NULL;
4394 /* Method invoked when an edge is duplicated. Copy ipa_edge_args and adjust
4395 reference count data strucutres accordingly. */
4397 void
4398 ipa_edge_args_sum_t::duplicate (cgraph_edge *src, cgraph_edge *dst,
4399 ipa_edge_args *old_args, ipa_edge_args *new_args)
4401 unsigned int i;
4403 new_args->jump_functions = vec_safe_copy (old_args->jump_functions);
4404 if (old_args->polymorphic_call_contexts)
4405 new_args->polymorphic_call_contexts
4406 = vec_safe_copy (old_args->polymorphic_call_contexts);
4408 for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
4410 struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
4411 struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
4413 dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
4415 if (src_jf->type == IPA_JF_CONST)
4417 struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
4419 if (!src_rdesc)
4420 dst_jf->value.constant.rdesc = NULL;
4421 else if (src->caller == dst->caller)
4423 /* Creation of a speculative edge. If the source edge is the one
4424 grabbing a reference, we must create a new (duplicate)
4425 reference description. Otherwise they refer to the same
4426 description corresponding to a reference taken in a function
4427 src->caller is inlined to. In that case we just must
4428 increment the refcount. */
4429 if (src_rdesc->cs == src)
4431 symtab_node *n = symtab_node_for_jfunc (src_jf);
4432 gcc_checking_assert (n);
4433 ipa_ref *ref
4434 = src->caller->find_reference (n, src->call_stmt,
4435 src->lto_stmt_uid);
4436 gcc_checking_assert (ref);
4437 dst->caller->clone_reference (ref, ref->stmt);
4439 ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4440 dst_rdesc->cs = dst;
4441 dst_rdesc->refcount = src_rdesc->refcount;
4442 dst_rdesc->next_duplicate = NULL;
4443 dst_jf->value.constant.rdesc = dst_rdesc;
4445 else
4447 src_rdesc->refcount++;
4448 dst_jf->value.constant.rdesc = src_rdesc;
4451 else if (src_rdesc->cs == src)
4453 struct ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4454 dst_rdesc->cs = dst;
4455 dst_rdesc->refcount = src_rdesc->refcount;
4456 dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
4457 src_rdesc->next_duplicate = dst_rdesc;
4458 dst_jf->value.constant.rdesc = dst_rdesc;
4460 else
4462 struct ipa_cst_ref_desc *dst_rdesc;
4463 /* This can happen during inlining, when a JFUNC can refer to a
4464 reference taken in a function up in the tree of inline clones.
4465 We need to find the duplicate that refers to our tree of
4466 inline clones. */
4468 gcc_assert (dst->caller->inlined_to);
4469 for (dst_rdesc = src_rdesc->next_duplicate;
4470 dst_rdesc;
4471 dst_rdesc = dst_rdesc->next_duplicate)
4473 struct cgraph_node *top;
4474 top = dst_rdesc->cs->caller->inlined_to
4475 ? dst_rdesc->cs->caller->inlined_to
4476 : dst_rdesc->cs->caller;
4477 if (dst->caller->inlined_to == top)
4478 break;
4480 gcc_assert (dst_rdesc);
4481 dst_jf->value.constant.rdesc = dst_rdesc;
4484 else if (dst_jf->type == IPA_JF_PASS_THROUGH
4485 && src->caller == dst->caller)
4487 struct cgraph_node *inline_root = dst->caller->inlined_to
4488 ? dst->caller->inlined_to : dst->caller;
4489 ipa_node_params *root_info = ipa_node_params_sum->get (inline_root);
4490 int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
4492 int c = ipa_get_controlled_uses (root_info, idx);
4493 if (c != IPA_UNDESCRIBED_USE)
4495 c++;
4496 ipa_set_controlled_uses (root_info, idx, c);
4502 /* Analyze newly added function into callgraph. */
4504 static void
4505 ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4507 if (node->has_gimple_body_p ())
4508 ipa_analyze_node (node);
4511 /* Hook that is called by summary when a node is duplicated. */
4513 void
4514 ipa_node_params_t::duplicate(cgraph_node *, cgraph_node *,
4515 ipa_node_params *old_info,
4516 ipa_node_params *new_info)
4518 new_info->descriptors = vec_safe_copy (old_info->descriptors);
4519 new_info->lattices = NULL;
4520 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
4521 new_info->known_csts = old_info->known_csts.copy ();
4522 new_info->known_contexts = old_info->known_contexts.copy ();
4524 new_info->analysis_done = old_info->analysis_done;
4525 new_info->node_enqueued = old_info->node_enqueued;
4526 new_info->versionable = old_info->versionable;
4529 /* Duplication of ipcp transformation summaries. */
4531 void
4532 ipcp_transformation_t::duplicate(cgraph_node *, cgraph_node *dst,
4533 ipcp_transformation *src_trans,
4534 ipcp_transformation *dst_trans)
4536 /* Avoid redundant work of duplicating vectors we will never use. */
4537 if (dst->inlined_to)
4538 return;
4539 dst_trans->m_agg_values = vec_safe_copy (src_trans->m_agg_values);
4540 dst_trans->bits = vec_safe_copy (src_trans->bits);
4541 dst_trans->m_vr = vec_safe_copy (src_trans->m_vr);
4544 /* Register our cgraph hooks if they are not already there. */
4546 void
4547 ipa_register_cgraph_hooks (void)
4549 ipa_check_create_node_params ();
4550 ipa_check_create_edge_args ();
4552 function_insertion_hook_holder =
4553 symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
4556 /* Unregister our cgraph hooks if they are not already there. */
4558 static void
4559 ipa_unregister_cgraph_hooks (void)
4561 if (function_insertion_hook_holder)
4562 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
4563 function_insertion_hook_holder = NULL;
4566 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4567 longer needed after ipa-cp. */
4569 void
4570 ipa_free_all_structures_after_ipa_cp (void)
4572 if (!optimize && !in_lto_p)
4574 ipa_free_all_edge_args ();
4575 ipa_free_all_node_params ();
4576 ipcp_sources_pool.release ();
4577 ipcp_cst_values_pool.release ();
4578 ipcp_poly_ctx_values_pool.release ();
4579 ipcp_agg_lattice_pool.release ();
4580 ipa_unregister_cgraph_hooks ();
4581 ipa_refdesc_pool.release ();
4585 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4586 longer needed after indirect inlining. */
4588 void
4589 ipa_free_all_structures_after_iinln (void)
4591 ipa_free_all_edge_args ();
4592 ipa_free_all_node_params ();
4593 ipa_unregister_cgraph_hooks ();
4594 ipcp_sources_pool.release ();
4595 ipcp_cst_values_pool.release ();
4596 ipcp_poly_ctx_values_pool.release ();
4597 ipcp_agg_lattice_pool.release ();
4598 ipa_refdesc_pool.release ();
4601 /* Print ipa_tree_map data structures of all functions in the
4602 callgraph to F. */
4604 void
4605 ipa_print_node_params (FILE *f, struct cgraph_node *node)
4607 int i, count;
4608 class ipa_node_params *info;
4610 if (!node->definition)
4611 return;
4612 info = ipa_node_params_sum->get (node);
4613 fprintf (f, " function %s parameter descriptors:\n", node->dump_name ());
4614 if (!info)
4616 fprintf (f, " no params return\n");
4617 return;
4619 count = ipa_get_param_count (info);
4620 for (i = 0; i < count; i++)
4622 int c;
4624 fprintf (f, " ");
4625 ipa_dump_param (f, info, i);
4626 if (ipa_is_param_used (info, i))
4627 fprintf (f, " used");
4628 if (ipa_is_param_used_by_ipa_predicates (info, i))
4629 fprintf (f, " used_by_ipa_predicates");
4630 if (ipa_is_param_used_by_indirect_call (info, i))
4631 fprintf (f, " used_by_indirect_call");
4632 if (ipa_is_param_used_by_polymorphic_call (info, i))
4633 fprintf (f, " used_by_polymorphic_call");
4634 c = ipa_get_controlled_uses (info, i);
4635 if (c == IPA_UNDESCRIBED_USE)
4636 fprintf (f, " undescribed_use");
4637 else
4638 fprintf (f, " controlled_uses=%i %s", c,
4639 ipa_get_param_load_dereferenced (info, i)
4640 ? "(load_dereferenced)" : "");
4641 fprintf (f, "\n");
4645 /* Print ipa_tree_map data structures of all functions in the
4646 callgraph to F. */
4648 void
4649 ipa_print_all_params (FILE * f)
4651 struct cgraph_node *node;
4653 fprintf (f, "\nFunction parameters:\n");
4654 FOR_EACH_FUNCTION (node)
4655 ipa_print_node_params (f, node);
4658 /* Stream out jump function JUMP_FUNC to OB. */
4660 static void
4661 ipa_write_jump_function (struct output_block *ob,
4662 struct ipa_jump_func *jump_func)
4664 struct ipa_agg_jf_item *item;
4665 struct bitpack_d bp;
4666 int i, count;
4667 int flag = 0;
4669 /* ADDR_EXPRs are very comon IP invariants; save some streamer data
4670 as well as WPA memory by handling them specially. */
4671 if (jump_func->type == IPA_JF_CONST
4672 && TREE_CODE (jump_func->value.constant.value) == ADDR_EXPR)
4673 flag = 1;
4675 streamer_write_uhwi (ob, jump_func->type * 2 + flag);
4676 switch (jump_func->type)
4678 case IPA_JF_UNKNOWN:
4679 break;
4680 case IPA_JF_CONST:
4681 gcc_assert (
4682 EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
4683 stream_write_tree (ob,
4684 flag
4685 ? TREE_OPERAND (jump_func->value.constant.value, 0)
4686 : jump_func->value.constant.value, true);
4687 break;
4688 case IPA_JF_PASS_THROUGH:
4689 streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
4690 if (jump_func->value.pass_through.operation == NOP_EXPR)
4692 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4693 bp = bitpack_create (ob->main_stream);
4694 bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
4695 streamer_write_bitpack (&bp);
4697 else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation)
4698 == tcc_unary)
4699 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4700 else
4702 stream_write_tree (ob, jump_func->value.pass_through.operand, true);
4703 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4705 break;
4706 case IPA_JF_ANCESTOR:
4707 streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
4708 streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
4709 bp = bitpack_create (ob->main_stream);
4710 bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
4711 bp_pack_value (&bp, jump_func->value.ancestor.keep_null, 1);
4712 streamer_write_bitpack (&bp);
4713 break;
4714 default:
4715 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4718 count = vec_safe_length (jump_func->agg.items);
4719 streamer_write_uhwi (ob, count);
4720 if (count)
4722 bp = bitpack_create (ob->main_stream);
4723 bp_pack_value (&bp, jump_func->agg.by_ref, 1);
4724 streamer_write_bitpack (&bp);
4727 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, i, item)
4729 stream_write_tree (ob, item->type, true);
4730 streamer_write_uhwi (ob, item->offset);
4731 streamer_write_uhwi (ob, item->jftype);
4732 switch (item->jftype)
4734 case IPA_JF_UNKNOWN:
4735 break;
4736 case IPA_JF_CONST:
4737 stream_write_tree (ob, item->value.constant, true);
4738 break;
4739 case IPA_JF_PASS_THROUGH:
4740 case IPA_JF_LOAD_AGG:
4741 streamer_write_uhwi (ob, item->value.pass_through.operation);
4742 streamer_write_uhwi (ob, item->value.pass_through.formal_id);
4743 if (TREE_CODE_CLASS (item->value.pass_through.operation)
4744 != tcc_unary)
4745 stream_write_tree (ob, item->value.pass_through.operand, true);
4746 if (item->jftype == IPA_JF_LOAD_AGG)
4748 stream_write_tree (ob, item->value.load_agg.type, true);
4749 streamer_write_uhwi (ob, item->value.load_agg.offset);
4750 bp = bitpack_create (ob->main_stream);
4751 bp_pack_value (&bp, item->value.load_agg.by_ref, 1);
4752 streamer_write_bitpack (&bp);
4754 break;
4755 default:
4756 fatal_error (UNKNOWN_LOCATION,
4757 "invalid jump function in LTO stream");
4761 bp = bitpack_create (ob->main_stream);
4762 bp_pack_value (&bp, !!jump_func->bits, 1);
4763 streamer_write_bitpack (&bp);
4764 if (jump_func->bits)
4766 streamer_write_widest_int (ob, jump_func->bits->value);
4767 streamer_write_widest_int (ob, jump_func->bits->mask);
4769 bp_pack_value (&bp, !!jump_func->m_vr, 1);
4770 streamer_write_bitpack (&bp);
4771 if (jump_func->m_vr)
4773 streamer_write_enum (ob->main_stream, value_rang_type,
4774 VR_LAST, jump_func->m_vr->kind ());
4775 stream_write_tree (ob, jump_func->m_vr->min (), true);
4776 stream_write_tree (ob, jump_func->m_vr->max (), true);
4780 /* Read in jump function JUMP_FUNC from IB. */
4782 static void
4783 ipa_read_jump_function (class lto_input_block *ib,
4784 struct ipa_jump_func *jump_func,
4785 struct cgraph_edge *cs,
4786 class data_in *data_in,
4787 bool prevails)
4789 enum jump_func_type jftype;
4790 enum tree_code operation;
4791 int i, count;
4792 int val = streamer_read_uhwi (ib);
4793 bool flag = val & 1;
4795 jftype = (enum jump_func_type) (val / 2);
4796 switch (jftype)
4798 case IPA_JF_UNKNOWN:
4799 ipa_set_jf_unknown (jump_func);
4800 break;
4801 case IPA_JF_CONST:
4803 tree t = stream_read_tree (ib, data_in);
4804 if (flag && prevails)
4805 t = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
4806 ipa_set_jf_constant (jump_func, t, cs);
4808 break;
4809 case IPA_JF_PASS_THROUGH:
4810 operation = (enum tree_code) streamer_read_uhwi (ib);
4811 if (operation == NOP_EXPR)
4813 int formal_id = streamer_read_uhwi (ib);
4814 struct bitpack_d bp = streamer_read_bitpack (ib);
4815 bool agg_preserved = bp_unpack_value (&bp, 1);
4816 ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
4818 else if (TREE_CODE_CLASS (operation) == tcc_unary)
4820 int formal_id = streamer_read_uhwi (ib);
4821 ipa_set_jf_unary_pass_through (jump_func, formal_id, operation);
4823 else
4825 tree operand = stream_read_tree (ib, data_in);
4826 int formal_id = streamer_read_uhwi (ib);
4827 ipa_set_jf_arith_pass_through (jump_func, formal_id, operand,
4828 operation);
4830 break;
4831 case IPA_JF_ANCESTOR:
4833 HOST_WIDE_INT offset = streamer_read_uhwi (ib);
4834 int formal_id = streamer_read_uhwi (ib);
4835 struct bitpack_d bp = streamer_read_bitpack (ib);
4836 bool agg_preserved = bp_unpack_value (&bp, 1);
4837 bool keep_null = bp_unpack_value (&bp, 1);
4838 ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved,
4839 keep_null);
4840 break;
4842 default:
4843 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4846 count = streamer_read_uhwi (ib);
4847 if (prevails)
4849 jump_func->agg.items = NULL;
4850 vec_safe_reserve (jump_func->agg.items, count, true);
4852 if (count)
4854 struct bitpack_d bp = streamer_read_bitpack (ib);
4855 jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
4857 for (i = 0; i < count; i++)
4859 struct ipa_agg_jf_item item;
4860 item.type = stream_read_tree (ib, data_in);
4861 item.offset = streamer_read_uhwi (ib);
4862 item.jftype = (enum jump_func_type) streamer_read_uhwi (ib);
4864 switch (item.jftype)
4866 case IPA_JF_UNKNOWN:
4867 break;
4868 case IPA_JF_CONST:
4869 item.value.constant = stream_read_tree (ib, data_in);
4870 break;
4871 case IPA_JF_PASS_THROUGH:
4872 case IPA_JF_LOAD_AGG:
4873 operation = (enum tree_code) streamer_read_uhwi (ib);
4874 item.value.pass_through.operation = operation;
4875 item.value.pass_through.formal_id = streamer_read_uhwi (ib);
4876 if (TREE_CODE_CLASS (operation) == tcc_unary)
4877 item.value.pass_through.operand = NULL_TREE;
4878 else
4879 item.value.pass_through.operand = stream_read_tree (ib, data_in);
4880 if (item.jftype == IPA_JF_LOAD_AGG)
4882 struct bitpack_d bp;
4883 item.value.load_agg.type = stream_read_tree (ib, data_in);
4884 item.value.load_agg.offset = streamer_read_uhwi (ib);
4885 bp = streamer_read_bitpack (ib);
4886 item.value.load_agg.by_ref = bp_unpack_value (&bp, 1);
4888 break;
4889 default:
4890 fatal_error (UNKNOWN_LOCATION,
4891 "invalid jump function in LTO stream");
4893 if (prevails)
4894 jump_func->agg.items->quick_push (item);
4897 struct bitpack_d bp = streamer_read_bitpack (ib);
4898 bool bits_known = bp_unpack_value (&bp, 1);
4899 if (bits_known)
4901 widest_int value = streamer_read_widest_int (ib);
4902 widest_int mask = streamer_read_widest_int (ib);
4903 if (prevails)
4904 ipa_set_jfunc_bits (jump_func, value, mask);
4906 else
4907 jump_func->bits = NULL;
4909 struct bitpack_d vr_bp = streamer_read_bitpack (ib);
4910 bool vr_known = bp_unpack_value (&vr_bp, 1);
4911 if (vr_known)
4913 enum value_range_kind type = streamer_read_enum (ib, value_range_kind,
4914 VR_LAST);
4915 tree min = stream_read_tree (ib, data_in);
4916 tree max = stream_read_tree (ib, data_in);
4917 if (prevails)
4918 ipa_set_jfunc_vr (jump_func, type, min, max);
4920 else
4921 jump_func->m_vr = NULL;
4924 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
4925 relevant to indirect inlining to OB. */
4927 static void
4928 ipa_write_indirect_edge_info (struct output_block *ob,
4929 struct cgraph_edge *cs)
4931 class cgraph_indirect_call_info *ii = cs->indirect_info;
4932 struct bitpack_d bp;
4934 streamer_write_hwi (ob, ii->param_index);
4935 bp = bitpack_create (ob->main_stream);
4936 bp_pack_value (&bp, ii->polymorphic, 1);
4937 bp_pack_value (&bp, ii->agg_contents, 1);
4938 bp_pack_value (&bp, ii->member_ptr, 1);
4939 bp_pack_value (&bp, ii->by_ref, 1);
4940 bp_pack_value (&bp, ii->guaranteed_unmodified, 1);
4941 bp_pack_value (&bp, ii->vptr_changed, 1);
4942 streamer_write_bitpack (&bp);
4943 if (ii->agg_contents || ii->polymorphic)
4944 streamer_write_hwi (ob, ii->offset);
4945 else
4946 gcc_assert (ii->offset == 0);
4948 if (ii->polymorphic)
4950 streamer_write_hwi (ob, ii->otr_token);
4951 stream_write_tree (ob, ii->otr_type, true);
4952 ii->context.stream_out (ob);
4956 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
4957 relevant to indirect inlining from IB. */
4959 static void
4960 ipa_read_indirect_edge_info (class lto_input_block *ib,
4961 class data_in *data_in,
4962 struct cgraph_edge *cs,
4963 class ipa_node_params *info)
4965 class cgraph_indirect_call_info *ii = cs->indirect_info;
4966 struct bitpack_d bp;
4968 ii->param_index = (int) streamer_read_hwi (ib);
4969 bp = streamer_read_bitpack (ib);
4970 ii->polymorphic = bp_unpack_value (&bp, 1);
4971 ii->agg_contents = bp_unpack_value (&bp, 1);
4972 ii->member_ptr = bp_unpack_value (&bp, 1);
4973 ii->by_ref = bp_unpack_value (&bp, 1);
4974 ii->guaranteed_unmodified = bp_unpack_value (&bp, 1);
4975 ii->vptr_changed = bp_unpack_value (&bp, 1);
4976 if (ii->agg_contents || ii->polymorphic)
4977 ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
4978 else
4979 ii->offset = 0;
4980 if (ii->polymorphic)
4982 ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
4983 ii->otr_type = stream_read_tree (ib, data_in);
4984 ii->context.stream_in (ib, data_in);
4986 if (info && ii->param_index >= 0)
4988 if (ii->polymorphic)
4989 ipa_set_param_used_by_polymorphic_call (info,
4990 ii->param_index , true);
4991 ipa_set_param_used_by_indirect_call (info,
4992 ii->param_index, true);
4996 /* Stream out NODE info to OB. */
4998 static void
4999 ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
5001 int node_ref;
5002 lto_symtab_encoder_t encoder;
5003 ipa_node_params *info = ipa_node_params_sum->get (node);
5004 int j;
5005 struct cgraph_edge *e;
5006 struct bitpack_d bp;
5008 encoder = ob->decl_state->symtab_node_encoder;
5009 node_ref = lto_symtab_encoder_encode (encoder, node);
5010 streamer_write_uhwi (ob, node_ref);
5012 streamer_write_uhwi (ob, ipa_get_param_count (info));
5013 for (j = 0; j < ipa_get_param_count (info); j++)
5014 streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
5015 bp = bitpack_create (ob->main_stream);
5016 gcc_assert (info->analysis_done
5017 || ipa_get_param_count (info) == 0);
5018 gcc_assert (!info->node_enqueued);
5019 gcc_assert (!info->ipcp_orig_node);
5020 for (j = 0; j < ipa_get_param_count (info); j++)
5022 /* TODO: We could just not stream the bit in the undescribed case. */
5023 bool d = (ipa_get_controlled_uses (info, j) != IPA_UNDESCRIBED_USE)
5024 ? ipa_get_param_load_dereferenced (info, j) : true;
5025 bp_pack_value (&bp, d, 1);
5026 bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
5028 streamer_write_bitpack (&bp);
5029 for (j = 0; j < ipa_get_param_count (info); j++)
5031 streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
5032 stream_write_tree (ob, ipa_get_type (info, j), true);
5034 for (e = node->callees; e; e = e->next_callee)
5036 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5038 if (!args)
5040 streamer_write_uhwi (ob, 0);
5041 continue;
5044 streamer_write_uhwi (ob,
5045 ipa_get_cs_argument_count (args) * 2
5046 + (args->polymorphic_call_contexts != NULL));
5047 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5049 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5050 if (args->polymorphic_call_contexts != NULL)
5051 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5054 for (e = node->indirect_calls; e; e = e->next_callee)
5056 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5057 if (!args)
5058 streamer_write_uhwi (ob, 0);
5059 else
5061 streamer_write_uhwi (ob,
5062 ipa_get_cs_argument_count (args) * 2
5063 + (args->polymorphic_call_contexts != NULL));
5064 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5066 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5067 if (args->polymorphic_call_contexts != NULL)
5068 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5071 ipa_write_indirect_edge_info (ob, e);
5075 /* Stream in edge E from IB. */
5077 static void
5078 ipa_read_edge_info (class lto_input_block *ib,
5079 class data_in *data_in,
5080 struct cgraph_edge *e, bool prevails)
5082 int count = streamer_read_uhwi (ib);
5083 bool contexts_computed = count & 1;
5085 count /= 2;
5086 if (!count)
5087 return;
5088 if (prevails
5089 && (e->possibly_call_in_translation_unit_p ()
5090 /* Also stream in jump functions to builtins in hope that they
5091 will get fnspecs. */
5092 || fndecl_built_in_p (e->callee->decl, BUILT_IN_NORMAL)))
5094 ipa_edge_args *args = ipa_edge_args_sum->get_create (e);
5095 vec_safe_grow_cleared (args->jump_functions, count, true);
5096 if (contexts_computed)
5097 vec_safe_grow_cleared (args->polymorphic_call_contexts, count, true);
5098 for (int k = 0; k < count; k++)
5100 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
5101 data_in, prevails);
5102 if (contexts_computed)
5103 ipa_get_ith_polymorhic_call_context (args, k)->stream_in
5104 (ib, data_in);
5107 else
5109 for (int k = 0; k < count; k++)
5111 struct ipa_jump_func dummy;
5112 ipa_read_jump_function (ib, &dummy, e,
5113 data_in, prevails);
5114 if (contexts_computed)
5116 class ipa_polymorphic_call_context ctx;
5117 ctx.stream_in (ib, data_in);
5123 /* Stream in NODE info from IB. */
5125 static void
5126 ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node,
5127 class data_in *data_in)
5129 int k;
5130 struct cgraph_edge *e;
5131 struct bitpack_d bp;
5132 bool prevails = node->prevailing_p ();
5133 ipa_node_params *info
5134 = prevails ? ipa_node_params_sum->get_create (node) : NULL;
5136 int param_count = streamer_read_uhwi (ib);
5137 if (prevails)
5139 ipa_alloc_node_params (node, param_count);
5140 for (k = 0; k < param_count; k++)
5141 (*info->descriptors)[k].move_cost = streamer_read_uhwi (ib);
5142 if (ipa_get_param_count (info) != 0)
5143 info->analysis_done = true;
5144 info->node_enqueued = false;
5146 else
5147 for (k = 0; k < param_count; k++)
5148 streamer_read_uhwi (ib);
5150 bp = streamer_read_bitpack (ib);
5151 for (k = 0; k < param_count; k++)
5153 bool load_dereferenced = bp_unpack_value (&bp, 1);
5154 bool used = bp_unpack_value (&bp, 1);
5156 if (prevails)
5158 ipa_set_param_load_dereferenced (info, k, load_dereferenced);
5159 ipa_set_param_used (info, k, used);
5162 for (k = 0; k < param_count; k++)
5164 int nuses = streamer_read_hwi (ib);
5165 tree type = stream_read_tree (ib, data_in);
5167 if (prevails)
5169 ipa_set_controlled_uses (info, k, nuses);
5170 (*info->descriptors)[k].decl_or_type = type;
5173 for (e = node->callees; e; e = e->next_callee)
5174 ipa_read_edge_info (ib, data_in, e, prevails);
5175 for (e = node->indirect_calls; e; e = e->next_callee)
5177 ipa_read_edge_info (ib, data_in, e, prevails);
5178 ipa_read_indirect_edge_info (ib, data_in, e, info);
5182 /* Write jump functions for nodes in SET. */
5184 void
5185 ipa_prop_write_jump_functions (void)
5187 struct output_block *ob;
5188 unsigned int count = 0;
5189 lto_symtab_encoder_iterator lsei;
5190 lto_symtab_encoder_t encoder;
5192 if (!ipa_node_params_sum || !ipa_edge_args_sum)
5193 return;
5195 ob = create_output_block (LTO_section_jump_functions);
5196 encoder = ob->decl_state->symtab_node_encoder;
5197 ob->symbol = NULL;
5198 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5199 lsei_next_function_in_partition (&lsei))
5201 cgraph_node *node = lsei_cgraph_node (lsei);
5202 if (node->has_gimple_body_p ()
5203 && ipa_node_params_sum->get (node) != NULL)
5204 count++;
5207 streamer_write_uhwi (ob, count);
5209 /* Process all of the functions. */
5210 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5211 lsei_next_function_in_partition (&lsei))
5213 cgraph_node *node = lsei_cgraph_node (lsei);
5214 if (node->has_gimple_body_p ()
5215 && ipa_node_params_sum->get (node) != NULL)
5216 ipa_write_node_info (ob, node);
5218 streamer_write_char_stream (ob->main_stream, 0);
5219 produce_asm (ob, NULL);
5220 destroy_output_block (ob);
5223 /* Read section in file FILE_DATA of length LEN with data DATA. */
5225 static void
5226 ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
5227 size_t len)
5229 const struct lto_function_header *header =
5230 (const struct lto_function_header *) data;
5231 const int cfg_offset = sizeof (struct lto_function_header);
5232 const int main_offset = cfg_offset + header->cfg_size;
5233 const int string_offset = main_offset + header->main_size;
5234 class data_in *data_in;
5235 unsigned int i;
5236 unsigned int count;
5238 lto_input_block ib_main ((const char *) data + main_offset,
5239 header->main_size, file_data->mode_table);
5241 data_in =
5242 lto_data_in_create (file_data, (const char *) data + string_offset,
5243 header->string_size, vNULL);
5244 count = streamer_read_uhwi (&ib_main);
5246 for (i = 0; i < count; i++)
5248 unsigned int index;
5249 struct cgraph_node *node;
5250 lto_symtab_encoder_t encoder;
5252 index = streamer_read_uhwi (&ib_main);
5253 encoder = file_data->symtab_node_encoder;
5254 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5255 index));
5256 gcc_assert (node->definition);
5257 ipa_read_node_info (&ib_main, node, data_in);
5259 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5260 len);
5261 lto_data_in_delete (data_in);
5264 /* Read ipcp jump functions. */
5266 void
5267 ipa_prop_read_jump_functions (void)
5269 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5270 struct lto_file_decl_data *file_data;
5271 unsigned int j = 0;
5273 ipa_check_create_node_params ();
5274 ipa_check_create_edge_args ();
5275 ipa_register_cgraph_hooks ();
5277 while ((file_data = file_data_vec[j++]))
5279 size_t len;
5280 const char *data
5281 = lto_get_summary_section_data (file_data, LTO_section_jump_functions,
5282 &len);
5283 if (data)
5284 ipa_prop_read_section (file_data, data, len);
5288 /* Return true if the IPA-CP transformation summary TS is non-NULL and contains
5289 useful info. */
5290 static bool
5291 useful_ipcp_transformation_info_p (ipcp_transformation *ts)
5293 if (!ts)
5294 return false;
5295 if (!vec_safe_is_empty (ts->m_agg_values)
5296 || !vec_safe_is_empty (ts->bits)
5297 || !vec_safe_is_empty (ts->m_vr))
5298 return true;
5299 return false;
5302 /* Write into OB IPA-CP transfromation summary TS describing NODE. */
5304 void
5305 write_ipcp_transformation_info (output_block *ob, cgraph_node *node,
5306 ipcp_transformation *ts)
5308 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
5309 int node_ref = lto_symtab_encoder_encode (encoder, node);
5310 streamer_write_uhwi (ob, node_ref);
5312 streamer_write_uhwi (ob, vec_safe_length (ts->m_agg_values));
5313 for (const ipa_argagg_value &av : ts->m_agg_values)
5315 struct bitpack_d bp;
5317 stream_write_tree (ob, av.value, true);
5318 streamer_write_uhwi (ob, av.unit_offset);
5319 streamer_write_uhwi (ob, av.index);
5321 bp = bitpack_create (ob->main_stream);
5322 bp_pack_value (&bp, av.by_ref, 1);
5323 streamer_write_bitpack (&bp);
5326 streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
5327 for (const ipa_vr &parm_vr : ts->m_vr)
5329 struct bitpack_d bp;
5330 bp = bitpack_create (ob->main_stream);
5331 bp_pack_value (&bp, parm_vr.known, 1);
5332 streamer_write_bitpack (&bp);
5333 if (parm_vr.known)
5335 streamer_write_enum (ob->main_stream, value_rang_type,
5336 VR_LAST, parm_vr.type);
5337 streamer_write_wide_int (ob, parm_vr.min);
5338 streamer_write_wide_int (ob, parm_vr.max);
5342 streamer_write_uhwi (ob, vec_safe_length (ts->bits));
5343 for (const ipa_bits *bits_jfunc : ts->bits)
5345 struct bitpack_d bp = bitpack_create (ob->main_stream);
5346 bp_pack_value (&bp, !!bits_jfunc, 1);
5347 streamer_write_bitpack (&bp);
5348 if (bits_jfunc)
5350 streamer_write_widest_int (ob, bits_jfunc->value);
5351 streamer_write_widest_int (ob, bits_jfunc->mask);
5356 /* Stream in the aggregate value replacement chain for NODE from IB. */
5358 static void
5359 read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
5360 data_in *data_in)
5362 unsigned int count, i;
5363 ipcp_transformation_initialize ();
5364 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5366 count = streamer_read_uhwi (ib);
5367 if (count > 0)
5369 vec_safe_grow_cleared (ts->m_agg_values, count, true);
5370 for (i = 0; i <count; i++)
5372 ipa_argagg_value *av = &(*ts->m_agg_values)[i];;
5374 av->value = stream_read_tree (ib, data_in);
5375 av->unit_offset = streamer_read_uhwi (ib);
5376 av->index = streamer_read_uhwi (ib);
5378 bitpack_d bp = streamer_read_bitpack (ib);
5379 av->by_ref = bp_unpack_value (&bp, 1);
5383 count = streamer_read_uhwi (ib);
5384 if (count > 0)
5386 vec_safe_grow_cleared (ts->m_vr, count, true);
5387 for (i = 0; i < count; i++)
5389 ipa_vr *parm_vr;
5390 parm_vr = &(*ts->m_vr)[i];
5391 struct bitpack_d bp;
5392 bp = streamer_read_bitpack (ib);
5393 parm_vr->known = bp_unpack_value (&bp, 1);
5394 if (parm_vr->known)
5396 parm_vr->type = streamer_read_enum (ib, value_range_kind,
5397 VR_LAST);
5398 parm_vr->min = streamer_read_wide_int (ib);
5399 parm_vr->max = streamer_read_wide_int (ib);
5403 count = streamer_read_uhwi (ib);
5404 if (count > 0)
5406 vec_safe_grow_cleared (ts->bits, count, true);
5407 for (i = 0; i < count; i++)
5409 struct bitpack_d bp = streamer_read_bitpack (ib);
5410 bool known = bp_unpack_value (&bp, 1);
5411 if (known)
5413 const widest_int value = streamer_read_widest_int (ib);
5414 const widest_int mask = streamer_read_widest_int (ib);
5415 ipa_bits *bits
5416 = ipa_get_ipa_bits_for_value (value, mask);
5417 (*ts->bits)[i] = bits;
5423 /* Write all aggregate replacement for nodes in set. */
5425 void
5426 ipcp_write_transformation_summaries (void)
5428 struct output_block *ob;
5429 unsigned int count = 0;
5430 lto_symtab_encoder_t encoder;
5432 ob = create_output_block (LTO_section_ipcp_transform);
5433 encoder = ob->decl_state->symtab_node_encoder;
5434 ob->symbol = NULL;
5436 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5438 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5439 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5440 if (!cnode)
5441 continue;
5442 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5443 if (useful_ipcp_transformation_info_p (ts)
5444 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5445 count++;
5448 streamer_write_uhwi (ob, count);
5450 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5452 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5453 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5454 if (!cnode)
5455 continue;
5456 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5457 if (useful_ipcp_transformation_info_p (ts)
5458 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5459 write_ipcp_transformation_info (ob, cnode, ts);
5461 streamer_write_char_stream (ob->main_stream, 0);
5462 produce_asm (ob, NULL);
5463 destroy_output_block (ob);
5466 /* Read replacements section in file FILE_DATA of length LEN with data
5467 DATA. */
5469 static void
5470 read_replacements_section (struct lto_file_decl_data *file_data,
5471 const char *data,
5472 size_t len)
5474 const struct lto_function_header *header =
5475 (const struct lto_function_header *) data;
5476 const int cfg_offset = sizeof (struct lto_function_header);
5477 const int main_offset = cfg_offset + header->cfg_size;
5478 const int string_offset = main_offset + header->main_size;
5479 class data_in *data_in;
5480 unsigned int i;
5481 unsigned int count;
5483 lto_input_block ib_main ((const char *) data + main_offset,
5484 header->main_size, file_data->mode_table);
5486 data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
5487 header->string_size, vNULL);
5488 count = streamer_read_uhwi (&ib_main);
5490 for (i = 0; i < count; i++)
5492 unsigned int index;
5493 struct cgraph_node *node;
5494 lto_symtab_encoder_t encoder;
5496 index = streamer_read_uhwi (&ib_main);
5497 encoder = file_data->symtab_node_encoder;
5498 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5499 index));
5500 read_ipcp_transformation_info (&ib_main, node, data_in);
5502 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5503 len);
5504 lto_data_in_delete (data_in);
5507 /* Read IPA-CP aggregate replacements. */
5509 void
5510 ipcp_read_transformation_summaries (void)
5512 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5513 struct lto_file_decl_data *file_data;
5514 unsigned int j = 0;
5516 while ((file_data = file_data_vec[j++]))
5518 size_t len;
5519 const char *data
5520 = lto_get_summary_section_data (file_data, LTO_section_ipcp_transform,
5521 &len);
5522 if (data)
5523 read_replacements_section (file_data, data, len);
5527 /* Adjust the aggregate replacements in TS to reflect any parameter removals
5528 which might have already taken place. If after adjustments there are no
5529 aggregate replacements left, the m_agg_values will be set to NULL. In other
5530 cases, it may be shrunk. */
5532 static void
5533 adjust_agg_replacement_values (cgraph_node *node, ipcp_transformation *ts)
5535 clone_info *cinfo = clone_info::get (node);
5536 if (!cinfo || !cinfo->param_adjustments)
5537 return;
5539 auto_vec<int, 16> new_indices;
5540 cinfo->param_adjustments->get_updated_indices (&new_indices);
5541 bool removed_item = false;
5542 unsigned dst_index = 0;
5543 unsigned count = ts->m_agg_values->length ();
5544 for (unsigned i = 0; i < count; i++)
5546 ipa_argagg_value *v = &(*ts->m_agg_values)[i];
5547 gcc_checking_assert (v->index >= 0);
5549 int new_idx = -1;
5550 if ((unsigned) v->index < new_indices.length ())
5551 new_idx = new_indices[v->index];
5553 if (new_idx >= 0)
5555 v->index = new_idx;
5556 if (removed_item)
5557 (*ts->m_agg_values)[dst_index] = *v;
5558 dst_index++;
5560 else
5561 removed_item = true;
5564 if (dst_index == 0)
5566 ggc_free (ts->m_agg_values);
5567 ts->m_agg_values = NULL;
5569 else if (removed_item)
5570 ts->m_agg_values->truncate (dst_index);
5572 return;
5575 /* Dominator walker driving the ipcp modification phase. */
5577 class ipcp_modif_dom_walker : public dom_walker
5579 public:
5580 ipcp_modif_dom_walker (struct ipa_func_body_info *fbi,
5581 vec<ipa_param_descriptor, va_gc> *descs,
5582 ipcp_transformation *ts, bool *sc)
5583 : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
5584 m_ts (ts), m_something_changed (sc) {}
5586 edge before_dom_children (basic_block) final override;
5587 bool cleanup_eh ()
5588 { return gimple_purge_all_dead_eh_edges (m_need_eh_cleanup); }
5590 private:
5591 struct ipa_func_body_info *m_fbi;
5592 vec<ipa_param_descriptor, va_gc> *m_descriptors;
5593 ipcp_transformation *m_ts;
5594 bool *m_something_changed;
5595 auto_bitmap m_need_eh_cleanup;
5598 edge
5599 ipcp_modif_dom_walker::before_dom_children (basic_block bb)
5601 gimple_stmt_iterator gsi;
5602 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5604 gimple *stmt = gsi_stmt (gsi);
5605 tree rhs, val, t;
5606 HOST_WIDE_INT bit_offset;
5607 poly_int64 size;
5608 int index;
5609 bool by_ref, vce;
5611 if (!gimple_assign_load_p (stmt))
5612 continue;
5613 rhs = gimple_assign_rhs1 (stmt);
5614 if (!is_gimple_reg_type (TREE_TYPE (rhs)))
5615 continue;
5617 vce = false;
5618 t = rhs;
5619 while (handled_component_p (t))
5621 /* V_C_E can do things like convert an array of integers to one
5622 bigger integer and similar things we do not handle below. */
5623 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
5625 vce = true;
5626 break;
5628 t = TREE_OPERAND (t, 0);
5630 if (vce)
5631 continue;
5633 if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index,
5634 &bit_offset, &size, &by_ref))
5635 continue;
5636 unsigned unit_offset = bit_offset / BITS_PER_UNIT;
5637 ipa_argagg_value_list avl (m_ts);
5638 tree v = avl.get_value (index, unit_offset, by_ref);
5640 if (!v
5641 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), size))
5642 continue;
5644 gcc_checking_assert (is_gimple_ip_invariant (v));
5645 if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v)))
5647 if (fold_convertible_p (TREE_TYPE (rhs), v))
5648 val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v);
5649 else if (TYPE_SIZE (TREE_TYPE (rhs))
5650 == TYPE_SIZE (TREE_TYPE (v)))
5651 val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v);
5652 else
5654 if (dump_file)
5656 fprintf (dump_file, " const ");
5657 print_generic_expr (dump_file, v);
5658 fprintf (dump_file, " can't be converted to type of ");
5659 print_generic_expr (dump_file, rhs);
5660 fprintf (dump_file, "\n");
5662 continue;
5665 else
5666 val = v;
5668 if (dump_file && (dump_flags & TDF_DETAILS))
5670 fprintf (dump_file, "Modifying stmt:\n ");
5671 print_gimple_stmt (dump_file, stmt, 0);
5673 gimple_assign_set_rhs_from_tree (&gsi, val);
5674 update_stmt (stmt);
5676 if (dump_file && (dump_flags & TDF_DETAILS))
5678 fprintf (dump_file, "into:\n ");
5679 print_gimple_stmt (dump_file, stmt, 0);
5680 fprintf (dump_file, "\n");
5683 *m_something_changed = true;
5684 if (maybe_clean_eh_stmt (stmt))
5685 bitmap_set_bit (m_need_eh_cleanup, bb->index);
5687 return NULL;
5690 /* Return true if we have recorded VALUE and MASK about PARM.
5691 Set VALUE and MASk accordingly. */
5693 bool
5694 ipcp_get_parm_bits (tree parm, tree *value, widest_int *mask)
5696 cgraph_node *cnode = cgraph_node::get (current_function_decl);
5697 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5698 if (!ts || vec_safe_length (ts->bits) == 0)
5699 return false;
5701 int i = 0;
5702 for (tree p = DECL_ARGUMENTS (current_function_decl);
5703 p != parm; p = DECL_CHAIN (p))
5705 i++;
5706 /* Ignore static chain. */
5707 if (!p)
5708 return false;
5711 clone_info *cinfo = clone_info::get (cnode);
5712 if (cinfo && cinfo->param_adjustments)
5714 i = cinfo->param_adjustments->get_original_index (i);
5715 if (i < 0)
5716 return false;
5719 vec<ipa_bits *, va_gc> &bits = *ts->bits;
5720 if (!bits[i])
5721 return false;
5722 *mask = bits[i]->mask;
5723 *value = wide_int_to_tree (TREE_TYPE (parm), bits[i]->value);
5724 return true;
5728 /* Update bits info of formal parameters as described in
5729 ipcp_transformation. */
5731 static void
5732 ipcp_update_bits (struct cgraph_node *node)
5734 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5736 if (!ts || vec_safe_length (ts->bits) == 0)
5737 return;
5738 vec<ipa_bits *, va_gc> &bits = *ts->bits;
5739 unsigned count = bits.length ();
5740 if (!count)
5741 return;
5743 auto_vec<int, 16> new_indices;
5744 bool need_remapping = false;
5745 clone_info *cinfo = clone_info::get (node);
5746 if (cinfo && cinfo->param_adjustments)
5748 cinfo->param_adjustments->get_updated_indices (&new_indices);
5749 need_remapping = true;
5751 auto_vec <tree, 16> parm_decls;
5752 push_function_arg_decls (&parm_decls, node->decl);
5754 for (unsigned i = 0; i < count; ++i)
5756 tree parm;
5757 if (need_remapping)
5759 if (i >= new_indices.length ())
5760 continue;
5761 int idx = new_indices[i];
5762 if (idx < 0)
5763 continue;
5764 parm = parm_decls[idx];
5766 else
5767 parm = parm_decls[i];
5768 gcc_checking_assert (parm);
5771 if (!bits[i]
5772 || !(INTEGRAL_TYPE_P (TREE_TYPE (parm))
5773 || POINTER_TYPE_P (TREE_TYPE (parm)))
5774 || !is_gimple_reg (parm))
5775 continue;
5777 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5778 if (!ddef)
5779 continue;
5781 if (dump_file)
5783 fprintf (dump_file, "Adjusting mask for param %u to ", i);
5784 print_hex (bits[i]->mask, dump_file);
5785 fprintf (dump_file, "\n");
5788 if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
5790 unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef));
5791 signop sgn = TYPE_SIGN (TREE_TYPE (ddef));
5793 wide_int nonzero_bits = wide_int::from (bits[i]->mask, prec, UNSIGNED)
5794 | wide_int::from (bits[i]->value, prec, sgn);
5795 set_nonzero_bits (ddef, nonzero_bits);
5797 else
5799 unsigned tem = bits[i]->mask.to_uhwi ();
5800 unsigned HOST_WIDE_INT bitpos = bits[i]->value.to_uhwi ();
5801 unsigned align = tem & -tem;
5802 unsigned misalign = bitpos & (align - 1);
5804 if (align > 1)
5806 if (dump_file)
5807 fprintf (dump_file, "Adjusting align: %u, misalign: %u\n", align, misalign);
5809 unsigned old_align, old_misalign;
5810 struct ptr_info_def *pi = get_ptr_info (ddef);
5811 bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign);
5813 if (old_known
5814 && old_align > align)
5816 if (dump_file)
5818 fprintf (dump_file, "But alignment was already %u.\n", old_align);
5819 if ((old_misalign & (align - 1)) != misalign)
5820 fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
5821 old_misalign, misalign);
5823 continue;
5826 if (old_known
5827 && ((misalign & (old_align - 1)) != old_misalign)
5828 && dump_file)
5829 fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
5830 old_misalign, misalign);
5832 set_ptr_info_alignment (pi, align, misalign);
5838 bool
5839 ipa_vr::nonzero_p (tree expr_type) const
5841 if (type == VR_ANTI_RANGE && wi::eq_p (min, 0) && wi::eq_p (max, 0))
5842 return true;
5844 unsigned prec = TYPE_PRECISION (expr_type);
5845 return (type == VR_RANGE
5846 && TYPE_UNSIGNED (expr_type)
5847 && wi::eq_p (min, wi::one (prec))
5848 && wi::eq_p (max, wi::max_value (prec, TYPE_SIGN (expr_type))));
5851 /* Update value range of formal parameters as described in
5852 ipcp_transformation. */
5854 static void
5855 ipcp_update_vr (struct cgraph_node *node)
5857 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5858 if (!ts || vec_safe_length (ts->m_vr) == 0)
5859 return;
5860 const vec<ipa_vr, va_gc> &vr = *ts->m_vr;
5861 unsigned count = vr.length ();
5862 if (!count)
5863 return;
5865 auto_vec<int, 16> new_indices;
5866 bool need_remapping = false;
5867 clone_info *cinfo = clone_info::get (node);
5868 if (cinfo && cinfo->param_adjustments)
5870 cinfo->param_adjustments->get_updated_indices (&new_indices);
5871 need_remapping = true;
5873 auto_vec <tree, 16> parm_decls;
5874 push_function_arg_decls (&parm_decls, node->decl);
5876 for (unsigned i = 0; i < count; ++i)
5878 tree parm;
5879 int remapped_idx;
5880 if (need_remapping)
5882 if (i >= new_indices.length ())
5883 continue;
5884 remapped_idx = new_indices[i];
5885 if (remapped_idx < 0)
5886 continue;
5888 else
5889 remapped_idx = i;
5891 parm = parm_decls[remapped_idx];
5893 gcc_checking_assert (parm);
5894 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5896 if (!ddef || !is_gimple_reg (parm))
5897 continue;
5899 if (vr[i].known
5900 && (vr[i].type == VR_RANGE || vr[i].type == VR_ANTI_RANGE))
5902 tree type = TREE_TYPE (ddef);
5903 unsigned prec = TYPE_PRECISION (type);
5904 if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
5906 if (dump_file)
5908 fprintf (dump_file, "Setting value range of param %u "
5909 "(now %i) ", i, remapped_idx);
5910 fprintf (dump_file, "%s[",
5911 (vr[i].type == VR_ANTI_RANGE) ? "~" : "");
5912 print_decs (vr[i].min, dump_file);
5913 fprintf (dump_file, ", ");
5914 print_decs (vr[i].max, dump_file);
5915 fprintf (dump_file, "]\n");
5917 value_range v (type,
5918 wide_int_storage::from (vr[i].min, prec,
5919 TYPE_SIGN (type)),
5920 wide_int_storage::from (vr[i].max, prec,
5921 TYPE_SIGN (type)),
5922 vr[i].type);
5923 set_range_info (ddef, v);
5925 else if (POINTER_TYPE_P (TREE_TYPE (ddef))
5926 && vr[i].nonzero_p (TREE_TYPE (ddef)))
5928 if (dump_file)
5929 fprintf (dump_file, "Setting nonnull for %u\n", i);
5930 set_ptr_nonnull (ddef);
5936 /* IPCP transformation phase doing propagation of aggregate values. */
5938 unsigned int
5939 ipcp_transform_function (struct cgraph_node *node)
5941 struct ipa_func_body_info fbi;
5942 int param_count;
5944 gcc_checking_assert (cfun);
5945 gcc_checking_assert (current_function_decl);
5947 if (dump_file)
5948 fprintf (dump_file, "Modification phase of node %s\n",
5949 node->dump_name ());
5951 ipcp_update_bits (node);
5952 ipcp_update_vr (node);
5953 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5954 if (!ts || vec_safe_is_empty (ts->m_agg_values))
5955 return 0;
5956 param_count = count_formal_params (node->decl);
5957 if (param_count == 0)
5958 return 0;
5960 adjust_agg_replacement_values (node, ts);
5961 if (vec_safe_is_empty (ts->m_agg_values))
5963 if (dump_file)
5964 fprintf (dump_file, " All affected aggregate parameters were either "
5965 "removed or converted into scalars, phase done.\n");
5966 return 0;
5968 if (dump_file)
5970 fprintf (dump_file, " Aggregate replacements:");
5971 ipa_argagg_value_list avs (ts);
5972 avs.dump (dump_file);
5975 fbi.node = node;
5976 fbi.info = NULL;
5977 fbi.bb_infos = vNULL;
5978 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
5979 fbi.param_count = param_count;
5980 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
5982 vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
5983 vec_safe_grow_cleared (descriptors, param_count, true);
5984 ipa_populate_param_decls (node, *descriptors);
5985 bool modified_mem_access = false;
5986 calculate_dominance_info (CDI_DOMINATORS);
5987 ipcp_modif_dom_walker walker (&fbi, descriptors, ts, &modified_mem_access);
5988 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
5989 free_dominance_info (CDI_DOMINATORS);
5990 bool cfg_changed = walker.cleanup_eh ();
5992 int i;
5993 struct ipa_bb_info *bi;
5994 FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
5995 free_ipa_bb_info (bi);
5996 fbi.bb_infos.release ();
5998 ipcp_transformation *s = ipcp_transformation_sum->get (node);
5999 s->m_agg_values = NULL;
6000 s->bits = NULL;
6001 s->m_vr = NULL;
6003 vec_free (descriptors);
6004 if (cfg_changed)
6005 delete_unreachable_blocks_update_callgraph (node, false);
6007 return modified_mem_access ? TODO_update_ssa_only_virtuals : 0;
6011 #include "gt-ipa-prop.h"