RISC-V: Fix snafu in SI mode splitters patch
[official-gcc.git] / gcc / ipa-prop.cc
blob99ebd6229ec425240d866813d065f226896b270d
1 /* Interprocedural analyses.
2 Copyright (C) 2005-2024 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
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 "sreal.h"
45 #include "ipa-cp.h"
46 #include "ipa-prop.h"
47 #include "tree-cfg.h"
48 #include "tree-dfa.h"
49 #include "tree-inline.h"
50 #include "ipa-fnsummary.h"
51 #include "gimple-pretty-print.h"
52 #include "ipa-utils.h"
53 #include "dbgcnt.h"
54 #include "domwalk.h"
55 #include "builtins.h"
56 #include "tree-cfgcleanup.h"
57 #include "options.h"
58 #include "symtab-clones.h"
59 #include "attr-fnspec.h"
60 #include "gimple-range.h"
61 #include "value-range-storage.h"
63 /* Function summary where the parameter infos are actually stored. */
64 ipa_node_params_t *ipa_node_params_sum = NULL;
66 function_summary <ipcp_transformation *> *ipcp_transformation_sum = NULL;
68 /* Edge summary for IPA-CP edge information. */
69 ipa_edge_args_sum_t *ipa_edge_args_sum;
71 /* Traits for a hash table for reusing ranges. */
73 struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <ipa_vr *>
75 typedef ipa_vr *value_type;
76 typedef const vrange *compare_type;
77 static hashval_t
78 hash (const ipa_vr *p)
80 // This never get called, except in the verification code, as
81 // ipa_get_value_range() calculates the hash itself. This
82 // function is mostly here for completness' sake.
83 value_range vr;
84 p->get_vrange (vr);
85 inchash::hash hstate;
86 add_vrange (vr, hstate);
87 return hstate.end ();
89 static bool
90 equal (const ipa_vr *a, const vrange *b)
92 return a->equal_p (*b);
94 static const bool empty_zero_p = true;
95 static void
96 mark_empty (ipa_vr *&p)
98 p = NULL;
100 static bool
101 is_empty (const ipa_vr *p)
103 return p == NULL;
105 static bool
106 is_deleted (const ipa_vr *p)
108 return p == reinterpret_cast<const ipa_vr *> (1);
110 static void
111 mark_deleted (ipa_vr *&p)
113 p = reinterpret_cast<ipa_vr *> (1);
117 /* Hash table for avoid repeated allocations of equal ranges. */
118 static GTY ((cache)) hash_table<ipa_vr_ggc_hash_traits> *ipa_vr_hash_table;
120 /* Holders of ipa cgraph hooks: */
121 static struct cgraph_node_hook_list *function_insertion_hook_holder;
123 /* Description of a reference to an IPA constant. */
124 struct ipa_cst_ref_desc
126 /* Edge that corresponds to the statement which took the reference. */
127 struct cgraph_edge *cs;
128 /* Linked list of duplicates created when call graph edges are cloned. */
129 struct ipa_cst_ref_desc *next_duplicate;
130 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
131 if out of control. */
132 int refcount;
135 /* Allocation pool for reference descriptions. */
137 static object_allocator<ipa_cst_ref_desc> ipa_refdesc_pool
138 ("IPA-PROP ref descriptions");
140 ipa_vr::ipa_vr ()
141 : m_storage (NULL),
142 m_type (NULL)
146 ipa_vr::ipa_vr (const vrange &r)
147 : m_storage (ggc_alloc_vrange_storage (r)),
148 m_type (r.type ())
152 bool
153 ipa_vr::equal_p (const vrange &r) const
155 gcc_checking_assert (!r.undefined_p ());
156 return (types_compatible_p (m_type, r.type ()) && m_storage->equal_p (r));
159 bool
160 ipa_vr::equal_p (const ipa_vr &o) const
162 if (!known_p ())
163 return !o.known_p ();
165 if (!types_compatible_p (m_type, o.m_type))
166 return false;
168 value_range r;
169 o.get_vrange (r);
170 return m_storage->equal_p (r);
173 void
174 ipa_vr::get_vrange (value_range &r) const
176 r.set_type (m_type);
177 m_storage->get_vrange (r, m_type);
180 void
181 ipa_vr::set_unknown ()
183 if (m_storage)
184 ggc_free (m_storage);
186 m_storage = NULL;
189 void
190 ipa_vr::streamer_read (lto_input_block *ib, data_in *data_in)
192 struct bitpack_d bp = streamer_read_bitpack (ib);
193 bool known = bp_unpack_value (&bp, 1);
194 if (known)
196 value_range vr;
197 streamer_read_value_range (ib, data_in, vr);
198 if (!m_storage || !m_storage->fits_p (vr))
200 if (m_storage)
201 ggc_free (m_storage);
202 m_storage = ggc_alloc_vrange_storage (vr);
204 m_storage->set_vrange (vr);
205 m_type = vr.type ();
207 else
209 m_storage = NULL;
210 m_type = NULL;
214 void
215 ipa_vr::streamer_write (output_block *ob) const
217 struct bitpack_d bp = bitpack_create (ob->main_stream);
218 bp_pack_value (&bp, !!m_storage, 1);
219 streamer_write_bitpack (&bp);
220 if (m_storage)
222 value_range vr (m_type);
223 m_storage->get_vrange (vr, m_type);
224 streamer_write_vrange (ob, vr);
228 void
229 ipa_vr::dump (FILE *out) const
231 if (known_p ())
233 value_range vr (m_type);
234 m_storage->get_vrange (vr, m_type);
235 vr.dump (out);
237 else
238 fprintf (out, "NO RANGE");
241 // These stubs are because we use an ipa_vr in a hash_traits and
242 // hash-traits.h defines an extern of gt_ggc_mx (T &) instead of
243 // picking up the gt_ggc_mx (T *) version.
244 void
245 gt_pch_nx (ipa_vr *&x)
247 return gt_pch_nx ((ipa_vr *) x);
250 void
251 gt_ggc_mx (ipa_vr *&x)
253 return gt_ggc_mx ((ipa_vr *) x);
256 /* Analysis summery of function call return value. */
257 struct GTY(()) ipa_return_value_summary
259 /* Known value range.
260 This needs to be wrapped in struccture due to specific way
261 we allocate ipa_vr. */
262 ipa_vr *vr;
265 /* Function summary for return values. */
266 class ipa_return_value_sum_t : public function_summary <ipa_return_value_summary *>
268 public:
269 ipa_return_value_sum_t (symbol_table *table, bool ggc):
270 function_summary <ipa_return_value_summary *> (table, ggc) { }
272 /* Hook that is called by summary when a node is duplicated. */
273 void duplicate (cgraph_node *,
274 cgraph_node *,
275 ipa_return_value_summary *data,
276 ipa_return_value_summary *data2) final override
278 *data2=*data;
282 /* Variable hoding the return value summary. */
283 static GTY(()) function_summary <ipa_return_value_summary *> *ipa_return_value_sum;
286 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
287 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
289 static bool
290 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
292 tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
294 if (!fs_opts)
295 return false;
296 return !opt_for_fn (node->decl, optimize) || !opt_for_fn (node->decl, flag_ipa_cp);
299 /* Return index of the formal whose tree is PTREE in function which corresponds
300 to INFO. */
302 static int
303 ipa_get_param_decl_index_1 (vec<ipa_param_descriptor, va_gc> *descriptors,
304 tree ptree)
306 int i, count;
308 count = vec_safe_length (descriptors);
309 for (i = 0; i < count; i++)
310 if ((*descriptors)[i].decl_or_type == ptree)
311 return i;
313 return -1;
316 /* Return index of the formal whose tree is PTREE in function which corresponds
317 to INFO. */
320 ipa_get_param_decl_index (class ipa_node_params *info, tree ptree)
322 return ipa_get_param_decl_index_1 (info->descriptors, ptree);
325 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
326 NODE. */
328 static void
329 ipa_populate_param_decls (struct cgraph_node *node,
330 vec<ipa_param_descriptor, va_gc> &descriptors)
332 tree fndecl;
333 tree fnargs;
334 tree parm;
335 int param_num;
337 fndecl = node->decl;
338 gcc_assert (gimple_has_body_p (fndecl));
339 fnargs = DECL_ARGUMENTS (fndecl);
340 param_num = 0;
341 for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
343 descriptors[param_num].decl_or_type = parm;
344 unsigned int cost = estimate_move_cost (TREE_TYPE (parm), true);
345 descriptors[param_num].move_cost = cost;
346 /* Watch overflow, move_cost is a bitfield. */
347 gcc_checking_assert (cost == descriptors[param_num].move_cost);
348 param_num++;
352 /* Return how many formal parameters FNDECL has. */
355 count_formal_params (tree fndecl)
357 tree parm;
358 int count = 0;
359 gcc_assert (gimple_has_body_p (fndecl));
361 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
362 count++;
364 return count;
367 /* Return the declaration of Ith formal parameter of the function corresponding
368 to INFO. Note there is no setter function as this array is built just once
369 using ipa_initialize_node_params. */
371 void
372 ipa_dump_param (FILE *file, class ipa_node_params *info, int i)
374 fprintf (file, "param #%i", i);
375 if ((*info->descriptors)[i].decl_or_type)
377 fprintf (file, " ");
378 print_generic_expr (file, (*info->descriptors)[i].decl_or_type);
382 /* If necessary, allocate vector of parameter descriptors in info of NODE.
383 Return true if they were allocated, false if not. */
385 static bool
386 ipa_alloc_node_params (struct cgraph_node *node, int param_count)
388 ipa_node_params *info = ipa_node_params_sum->get_create (node);
390 if (!info->descriptors && param_count)
392 vec_safe_grow_cleared (info->descriptors, param_count, true);
393 return true;
395 else
396 return false;
399 /* Initialize the ipa_node_params structure associated with NODE by counting
400 the function parameters, creating the descriptors and populating their
401 param_decls. */
403 void
404 ipa_initialize_node_params (struct cgraph_node *node)
406 ipa_node_params *info = ipa_node_params_sum->get_create (node);
408 if (!info->descriptors
409 && ipa_alloc_node_params (node, count_formal_params (node->decl)))
410 ipa_populate_param_decls (node, *info->descriptors);
413 /* Print VAL which is extracted from a jump function to F. */
415 static void
416 ipa_print_constant_value (FILE *f, tree val)
418 print_generic_expr (f, val);
420 /* This is in keeping with values_equal_for_ipcp_p. */
421 if (TREE_CODE (val) == ADDR_EXPR
422 && (TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL
423 || (TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL
424 && DECL_IN_CONSTANT_POOL (TREE_OPERAND (val, 0)))))
426 fputs (" -> ", f);
427 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)));
431 /* Print the jump functions associated with call graph edge CS to file F. */
433 static void
434 ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
436 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
437 int count = ipa_get_cs_argument_count (args);
439 for (int i = 0; i < count; i++)
441 struct ipa_jump_func *jump_func;
442 enum jump_func_type type;
444 jump_func = ipa_get_ith_jump_func (args, i);
445 type = jump_func->type;
447 fprintf (f, " param %d: ", i);
448 if (type == IPA_JF_UNKNOWN)
449 fprintf (f, "UNKNOWN\n");
450 else if (type == IPA_JF_CONST)
452 fprintf (f, "CONST: ");
453 ipa_print_constant_value (f, jump_func->value.constant.value);
454 fprintf (f, "\n");
456 else if (type == IPA_JF_PASS_THROUGH)
458 fprintf (f, "PASS THROUGH: ");
459 fprintf (f, "%d, op %s",
460 jump_func->value.pass_through.formal_id,
461 get_tree_code_name(jump_func->value.pass_through.operation));
462 if (jump_func->value.pass_through.operation != NOP_EXPR)
464 fprintf (f, " ");
465 print_generic_expr (f, jump_func->value.pass_through.operand);
467 if (jump_func->value.pass_through.agg_preserved)
468 fprintf (f, ", agg_preserved");
469 if (jump_func->value.pass_through.refdesc_decremented)
470 fprintf (f, ", refdesc_decremented");
471 fprintf (f, "\n");
473 else if (type == IPA_JF_ANCESTOR)
475 fprintf (f, "ANCESTOR: ");
476 fprintf (f, "%d, offset " HOST_WIDE_INT_PRINT_DEC,
477 jump_func->value.ancestor.formal_id,
478 jump_func->value.ancestor.offset);
479 if (jump_func->value.ancestor.agg_preserved)
480 fprintf (f, ", agg_preserved");
481 if (jump_func->value.ancestor.keep_null)
482 fprintf (f, ", keep_null");
483 fprintf (f, "\n");
486 if (jump_func->agg.items)
488 struct ipa_agg_jf_item *item;
489 int j;
491 fprintf (f, " Aggregate passed by %s:\n",
492 jump_func->agg.by_ref ? "reference" : "value");
493 FOR_EACH_VEC_ELT (*jump_func->agg.items, j, item)
495 fprintf (f, " offset: " HOST_WIDE_INT_PRINT_DEC ", ",
496 item->offset);
497 fprintf (f, "type: ");
498 print_generic_expr (f, item->type);
499 fprintf (f, ", ");
500 if (item->jftype == IPA_JF_PASS_THROUGH)
501 fprintf (f, "PASS THROUGH: %d,",
502 item->value.pass_through.formal_id);
503 else if (item->jftype == IPA_JF_LOAD_AGG)
505 fprintf (f, "LOAD AGG: %d",
506 item->value.pass_through.formal_id);
507 fprintf (f, " [offset: " HOST_WIDE_INT_PRINT_DEC ", by %s],",
508 item->value.load_agg.offset,
509 item->value.load_agg.by_ref ? "reference"
510 : "value");
513 if (item->jftype == IPA_JF_PASS_THROUGH
514 || item->jftype == IPA_JF_LOAD_AGG)
516 fprintf (f, " op %s",
517 get_tree_code_name (item->value.pass_through.operation));
518 if (item->value.pass_through.operation != NOP_EXPR)
520 fprintf (f, " ");
521 print_generic_expr (f, item->value.pass_through.operand);
524 else if (item->jftype == IPA_JF_CONST)
526 fprintf (f, "CONST: ");
527 ipa_print_constant_value (f, item->value.constant);
529 else if (item->jftype == IPA_JF_UNKNOWN)
530 fprintf (f, "UNKNOWN: " HOST_WIDE_INT_PRINT_DEC " bits",
531 tree_to_uhwi (TYPE_SIZE (item->type)));
532 fprintf (f, "\n");
536 class ipa_polymorphic_call_context *ctx
537 = ipa_get_ith_polymorhic_call_context (args, i);
538 if (ctx && !ctx->useless_p ())
540 fprintf (f, " Context: ");
541 ctx->dump (dump_file);
544 if (jump_func->m_vr)
546 jump_func->m_vr->dump (f);
547 fprintf (f, "\n");
549 else
550 fprintf (f, " Unknown VR\n");
555 /* Print the jump functions of all arguments on all call graph edges going from
556 NODE to file F. */
558 void
559 ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
561 struct cgraph_edge *cs;
563 fprintf (f, " Jump functions of caller %s:\n", node->dump_name ());
564 for (cs = node->callees; cs; cs = cs->next_callee)
567 fprintf (f, " callsite %s -> %s : \n",
568 node->dump_name (),
569 cs->callee->dump_name ());
570 if (!ipa_edge_args_info_available_for_edge_p (cs))
571 fprintf (f, " no arg info\n");
572 else
573 ipa_print_node_jump_functions_for_edge (f, cs);
576 for (cs = node->indirect_calls; cs; cs = cs->next_callee)
578 class cgraph_indirect_call_info *ii;
580 ii = cs->indirect_info;
581 if (ii->agg_contents)
582 fprintf (f, " indirect %s callsite, calling param %i, "
583 "offset " HOST_WIDE_INT_PRINT_DEC ", %s",
584 ii->member_ptr ? "member ptr" : "aggregate",
585 ii->param_index, ii->offset,
586 ii->by_ref ? "by reference" : "by_value");
587 else
588 fprintf (f, " indirect %s callsite, calling param %i, "
589 "offset " HOST_WIDE_INT_PRINT_DEC,
590 ii->polymorphic ? "polymorphic" : "simple", ii->param_index,
591 ii->offset);
593 if (cs->call_stmt)
595 fprintf (f, ", for stmt ");
596 print_gimple_stmt (f, cs->call_stmt, 0, TDF_SLIM);
598 else
599 fprintf (f, "\n");
600 if (ii->polymorphic)
601 ii->context.dump (f);
602 if (!ipa_edge_args_info_available_for_edge_p (cs))
603 fprintf (f, " no arg info\n");
604 else
605 ipa_print_node_jump_functions_for_edge (f, cs);
609 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
611 void
612 ipa_print_all_jump_functions (FILE *f)
614 struct cgraph_node *node;
616 fprintf (f, "\nJump functions:\n");
617 FOR_EACH_FUNCTION (node)
619 ipa_print_node_jump_functions (f, node);
623 /* Set jfunc to be a know-really nothing jump function. */
625 static void
626 ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
628 jfunc->type = IPA_JF_UNKNOWN;
631 /* Set JFUNC to be a copy of another jmp (to be used by jump function
632 combination code). The two functions will share their rdesc. */
634 static void
635 ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
636 struct ipa_jump_func *src)
639 gcc_checking_assert (src->type == IPA_JF_CONST);
640 dst->type = IPA_JF_CONST;
641 dst->value.constant = src->value.constant;
644 /* Set JFUNC to be a constant jmp function. */
646 static void
647 ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
648 struct cgraph_edge *cs)
650 jfunc->type = IPA_JF_CONST;
651 jfunc->value.constant.value = unshare_expr_without_location (constant);
653 if (TREE_CODE (constant) == ADDR_EXPR
654 && (TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL
655 || (VAR_P (TREE_OPERAND (constant, 0))
656 && TREE_STATIC (TREE_OPERAND (constant, 0)))))
658 struct ipa_cst_ref_desc *rdesc;
660 rdesc = ipa_refdesc_pool.allocate ();
661 rdesc->cs = cs;
662 rdesc->next_duplicate = NULL;
663 rdesc->refcount = 1;
664 jfunc->value.constant.rdesc = rdesc;
666 else
667 jfunc->value.constant.rdesc = NULL;
670 /* Set JFUNC to be a simple pass-through jump function. */
671 static void
672 ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
673 bool agg_preserved)
675 jfunc->type = IPA_JF_PASS_THROUGH;
676 jfunc->value.pass_through.operand = NULL_TREE;
677 jfunc->value.pass_through.formal_id = formal_id;
678 jfunc->value.pass_through.operation = NOP_EXPR;
679 jfunc->value.pass_through.agg_preserved = agg_preserved;
680 jfunc->value.pass_through.refdesc_decremented = false;
683 /* Set JFUNC to be an unary pass through jump function. */
685 static void
686 ipa_set_jf_unary_pass_through (struct ipa_jump_func *jfunc, int formal_id,
687 enum tree_code operation)
689 jfunc->type = IPA_JF_PASS_THROUGH;
690 jfunc->value.pass_through.operand = NULL_TREE;
691 jfunc->value.pass_through.formal_id = formal_id;
692 jfunc->value.pass_through.operation = operation;
693 jfunc->value.pass_through.agg_preserved = false;
694 jfunc->value.pass_through.refdesc_decremented = false;
696 /* Set JFUNC to be an arithmetic pass through jump function. */
698 static void
699 ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
700 tree operand, enum tree_code operation)
702 jfunc->type = IPA_JF_PASS_THROUGH;
703 jfunc->value.pass_through.operand = unshare_expr_without_location (operand);
704 jfunc->value.pass_through.formal_id = formal_id;
705 jfunc->value.pass_through.operation = operation;
706 jfunc->value.pass_through.agg_preserved = false;
707 jfunc->value.pass_through.refdesc_decremented = false;
710 /* Set JFUNC to be an ancestor jump function. */
712 static void
713 ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
714 int formal_id, bool agg_preserved, bool keep_null)
716 jfunc->type = IPA_JF_ANCESTOR;
717 jfunc->value.ancestor.formal_id = formal_id;
718 jfunc->value.ancestor.offset = offset;
719 jfunc->value.ancestor.agg_preserved = agg_preserved;
720 jfunc->value.ancestor.keep_null = keep_null;
723 /* Get IPA BB information about the given BB. FBI is the context of analyzis
724 of this function body. */
726 static struct ipa_bb_info *
727 ipa_get_bb_info (struct ipa_func_body_info *fbi, basic_block bb)
729 gcc_checking_assert (fbi);
730 return &fbi->bb_infos[bb->index];
733 /* Structure to be passed in between detect_type_change and
734 check_stmt_for_type_change. */
736 struct prop_type_change_info
738 /* Offset into the object where there is the virtual method pointer we are
739 looking for. */
740 HOST_WIDE_INT offset;
741 /* The declaration or SSA_NAME pointer of the base that we are checking for
742 type change. */
743 tree object;
744 /* Set to true if dynamic type change has been detected. */
745 bool type_maybe_changed;
748 /* Return true if STMT can modify a virtual method table pointer.
750 This function makes special assumptions about both constructors and
751 destructors which are all the functions that are allowed to alter the VMT
752 pointers. It assumes that destructors begin with assignment into all VMT
753 pointers and that constructors essentially look in the following way:
755 1) The very first thing they do is that they call constructors of ancestor
756 sub-objects that have them.
758 2) Then VMT pointers of this and all its ancestors is set to new values
759 corresponding to the type corresponding to the constructor.
761 3) Only afterwards, other stuff such as constructor of member sub-objects
762 and the code written by the user is run. Only this may include calling
763 virtual functions, directly or indirectly.
765 There is no way to call a constructor of an ancestor sub-object in any
766 other way.
768 This means that we do not have to care whether constructors get the correct
769 type information because they will always change it (in fact, if we define
770 the type to be given by the VMT pointer, it is undefined).
772 The most important fact to derive from the above is that if, for some
773 statement in the section 3, we try to detect whether the dynamic type has
774 changed, we can safely ignore all calls as we examine the function body
775 backwards until we reach statements in section 2 because these calls cannot
776 be ancestor constructors or destructors (if the input is not bogus) and so
777 do not change the dynamic type (this holds true only for automatically
778 allocated objects but at the moment we devirtualize only these). We then
779 must detect that statements in section 2 change the dynamic type and can try
780 to derive the new type. That is enough and we can stop, we will never see
781 the calls into constructors of sub-objects in this code. Therefore we can
782 safely ignore all call statements that we traverse.
785 static bool
786 stmt_may_be_vtbl_ptr_store (gimple *stmt)
788 if (is_gimple_call (stmt))
789 return false;
790 if (gimple_clobber_p (stmt))
791 return false;
792 else if (is_gimple_assign (stmt))
794 tree lhs = gimple_assign_lhs (stmt);
796 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
798 if (flag_strict_aliasing
799 && !POINTER_TYPE_P (TREE_TYPE (lhs)))
800 return false;
802 if (TREE_CODE (lhs) == COMPONENT_REF
803 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
804 return false;
805 /* In the future we might want to use get_ref_base_and_extent to find
806 if there is a field corresponding to the offset and if so, proceed
807 almost like if it was a component ref. */
810 return true;
813 /* Callback of walk_aliased_vdefs and a helper function for detect_type_change
814 to check whether a particular statement may modify the virtual table
815 pointerIt stores its result into DATA, which points to a
816 prop_type_change_info structure. */
818 static bool
819 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
821 gimple *stmt = SSA_NAME_DEF_STMT (vdef);
822 struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
824 if (stmt_may_be_vtbl_ptr_store (stmt))
826 tci->type_maybe_changed = true;
827 return true;
829 else
830 return false;
833 /* See if ARG is PARAM_DECl describing instance passed by pointer
834 or reference in FUNCTION. Return false if the dynamic type may change
835 in between beggining of the function until CALL is invoked.
837 Generally functions are not allowed to change type of such instances,
838 but they call destructors. We assume that methods cannot destroy the THIS
839 pointer. Also as a special cases, constructor and destructors may change
840 type of the THIS pointer. */
842 static bool
843 param_type_may_change_p (tree function, tree arg, gimple *call)
845 /* Pure functions cannot do any changes on the dynamic type;
846 that require writting to memory. */
847 if (flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
848 return false;
849 /* We need to check if we are within inlined consturctor
850 or destructor (ideally we would have way to check that the
851 inline cdtor is actually working on ARG, but we don't have
852 easy tie on this, so punt on all non-pure cdtors.
853 We may also record the types of cdtors and once we know type
854 of the instance match them.
856 Also code unification optimizations may merge calls from
857 different blocks making return values unreliable. So
858 do nothing during late optimization. */
859 if (DECL_STRUCT_FUNCTION (function)->after_inlining)
860 return true;
861 if (TREE_CODE (arg) == SSA_NAME
862 && SSA_NAME_IS_DEFAULT_DEF (arg)
863 && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
865 /* Normal (non-THIS) argument. */
866 if ((SSA_NAME_VAR (arg) != DECL_ARGUMENTS (function)
867 || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE)
868 /* THIS pointer of an method - here we want to watch constructors
869 and destructors as those definitely may change the dynamic
870 type. */
871 || (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE
872 && !DECL_CXX_CONSTRUCTOR_P (function)
873 && !DECL_CXX_DESTRUCTOR_P (function)
874 && (SSA_NAME_VAR (arg) == DECL_ARGUMENTS (function))))
876 /* Walk the inline stack and watch out for ctors/dtors. */
877 for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
878 block = BLOCK_SUPERCONTEXT (block))
879 if (inlined_polymorphic_ctor_dtor_block_p (block, false))
880 return true;
881 return false;
884 return true;
887 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
888 callsite CALL) by looking for assignments to its virtual table pointer. If
889 it is, return true. ARG is the object itself (not a pointer
890 to it, unless dereferenced). BASE is the base of the memory access as
891 returned by get_ref_base_and_extent, as is the offset.
893 This is helper function for detect_type_change and detect_type_change_ssa
894 that does the heavy work which is usually unnecesary. */
896 static bool
897 detect_type_change_from_memory_writes (ipa_func_body_info *fbi, tree arg,
898 tree base, tree comp_type, gcall *call,
899 HOST_WIDE_INT offset)
901 struct prop_type_change_info tci;
902 ao_ref ao;
904 gcc_checking_assert (DECL_P (arg)
905 || TREE_CODE (arg) == MEM_REF
906 || handled_component_p (arg));
908 comp_type = TYPE_MAIN_VARIANT (comp_type);
910 /* Const calls cannot call virtual methods through VMT and so type changes do
911 not matter. */
912 if (!flag_devirtualize || !gimple_vuse (call)
913 /* Be sure expected_type is polymorphic. */
914 || !comp_type
915 || TREE_CODE (comp_type) != RECORD_TYPE
916 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))
917 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))))
918 return true;
920 if (fbi->aa_walk_budget == 0)
921 return false;
923 ao_ref_init (&ao, arg);
924 ao.base = base;
925 ao.offset = offset;
926 ao.size = POINTER_SIZE;
927 ao.max_size = ao.size;
929 tci.offset = offset;
930 tci.object = get_base_address (arg);
931 tci.type_maybe_changed = false;
933 int walked
934 = walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
935 &tci, NULL, NULL, fbi->aa_walk_budget);
936 if (walked >= 0)
937 fbi->aa_walk_budget -= walked;
938 else
939 fbi->aa_walk_budget = 0;
941 if (walked >= 0 && !tci.type_maybe_changed)
942 return false;
944 return true;
947 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
948 If it is, return true. ARG is the object itself (not a pointer
949 to it, unless dereferenced). BASE is the base of the memory access as
950 returned by get_ref_base_and_extent, as is the offset. */
952 static bool
953 detect_type_change (ipa_func_body_info *fbi, tree arg, tree base,
954 tree comp_type, gcall *call,
955 HOST_WIDE_INT offset)
957 if (!flag_devirtualize)
958 return false;
960 if (TREE_CODE (base) == MEM_REF
961 && !param_type_may_change_p (current_function_decl,
962 TREE_OPERAND (base, 0),
963 call))
964 return false;
965 return detect_type_change_from_memory_writes (fbi, arg, base, comp_type,
966 call, offset);
969 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
970 SSA name (its dereference will become the base and the offset is assumed to
971 be zero). */
973 static bool
974 detect_type_change_ssa (ipa_func_body_info *fbi, tree arg, tree comp_type,
975 gcall *call)
977 gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
978 if (!flag_devirtualize
979 || !POINTER_TYPE_P (TREE_TYPE (arg)))
980 return false;
982 if (!param_type_may_change_p (current_function_decl, arg, call))
983 return false;
985 arg = build2 (MEM_REF, ptr_type_node, arg,
986 build_int_cst (ptr_type_node, 0));
988 return detect_type_change_from_memory_writes (fbi, arg, arg, comp_type,
989 call, 0);
992 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
993 boolean variable pointed to by DATA. */
995 static bool
996 mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
997 void *data)
999 bool *b = (bool *) data;
1000 *b = true;
1001 return true;
1004 /* Find the nearest valid aa status for parameter specified by INDEX that
1005 dominates BB. */
1007 static struct ipa_param_aa_status *
1008 find_dominating_aa_status (struct ipa_func_body_info *fbi, basic_block bb,
1009 int index)
1011 while (true)
1013 bb = get_immediate_dominator (CDI_DOMINATORS, bb);
1014 if (!bb)
1015 return NULL;
1016 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
1017 if (!bi->param_aa_statuses.is_empty ()
1018 && bi->param_aa_statuses[index].valid)
1019 return &bi->param_aa_statuses[index];
1023 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
1024 structures and/or intialize the result with a dominating description as
1025 necessary. */
1027 static struct ipa_param_aa_status *
1028 parm_bb_aa_status_for_bb (struct ipa_func_body_info *fbi, basic_block bb,
1029 int index)
1031 gcc_checking_assert (fbi);
1032 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
1033 if (bi->param_aa_statuses.is_empty ())
1034 bi->param_aa_statuses.safe_grow_cleared (fbi->param_count, true);
1035 struct ipa_param_aa_status *paa = &bi->param_aa_statuses[index];
1036 if (!paa->valid)
1038 gcc_checking_assert (!paa->parm_modified
1039 && !paa->ref_modified
1040 && !paa->pt_modified);
1041 struct ipa_param_aa_status *dom_paa;
1042 dom_paa = find_dominating_aa_status (fbi, bb, index);
1043 if (dom_paa)
1044 *paa = *dom_paa;
1045 else
1046 paa->valid = true;
1049 return paa;
1052 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
1053 a value known not to be modified in this function before reaching the
1054 statement STMT. FBI holds information about the function we have so far
1055 gathered but do not survive the summary building stage. */
1057 static bool
1058 parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index,
1059 gimple *stmt, tree parm_load)
1061 struct ipa_param_aa_status *paa;
1062 bool modified = false;
1063 ao_ref refd;
1065 tree base = get_base_address (parm_load);
1066 gcc_assert (TREE_CODE (base) == PARM_DECL);
1067 if (TREE_READONLY (base))
1068 return true;
1070 gcc_checking_assert (fbi);
1071 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
1072 if (paa->parm_modified || fbi->aa_walk_budget == 0)
1073 return false;
1075 gcc_checking_assert (gimple_vuse (stmt) != NULL_TREE);
1076 ao_ref_init (&refd, parm_load);
1077 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
1078 &modified, NULL, NULL,
1079 fbi->aa_walk_budget);
1080 if (walked < 0)
1082 modified = true;
1083 fbi->aa_walk_budget = 0;
1085 else
1086 fbi->aa_walk_budget -= walked;
1087 if (paa && modified)
1088 paa->parm_modified = true;
1089 return !modified;
1092 /* If STMT is an assignment that loads a value from an parameter declaration,
1093 return the index of the parameter in ipa_node_params which has not been
1094 modified. Otherwise return -1. */
1096 static int
1097 load_from_unmodified_param (struct ipa_func_body_info *fbi,
1098 vec<ipa_param_descriptor, va_gc> *descriptors,
1099 gimple *stmt)
1101 int index;
1102 tree op1;
1104 if (!gimple_assign_single_p (stmt))
1105 return -1;
1107 op1 = gimple_assign_rhs1 (stmt);
1108 if (TREE_CODE (op1) != PARM_DECL)
1109 return -1;
1111 index = ipa_get_param_decl_index_1 (descriptors, op1);
1112 if (index < 0
1113 || !parm_preserved_before_stmt_p (fbi, index, stmt, op1))
1114 return -1;
1116 return index;
1119 /* Return true if memory reference REF (which must be a load through parameter
1120 with INDEX) loads data that are known to be unmodified in this function
1121 before reaching statement STMT. */
1123 static bool
1124 parm_ref_data_preserved_p (struct ipa_func_body_info *fbi,
1125 int index, gimple *stmt, tree ref)
1127 struct ipa_param_aa_status *paa;
1128 bool modified = false;
1129 ao_ref refd;
1131 gcc_checking_assert (fbi);
1132 paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
1133 if (paa->ref_modified || fbi->aa_walk_budget == 0)
1134 return false;
1136 gcc_checking_assert (gimple_vuse (stmt));
1137 ao_ref_init (&refd, ref);
1138 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
1139 &modified, NULL, NULL,
1140 fbi->aa_walk_budget);
1141 if (walked < 0)
1143 modified = true;
1144 fbi->aa_walk_budget = 0;
1146 else
1147 fbi->aa_walk_budget -= walked;
1148 if (modified)
1149 paa->ref_modified = true;
1150 return !modified;
1153 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
1154 is known to be unmodified in this function before reaching call statement
1155 CALL into which it is passed. FBI describes the function body. */
1157 static bool
1158 parm_ref_data_pass_through_p (struct ipa_func_body_info *fbi, int index,
1159 gimple *call, tree parm)
1161 bool modified = false;
1162 ao_ref refd;
1164 /* It's unnecessary to calculate anything about memory contnets for a const
1165 function because it is not goin to use it. But do not cache the result
1166 either. Also, no such calculations for non-pointers. */
1167 if (!gimple_vuse (call)
1168 || !POINTER_TYPE_P (TREE_TYPE (parm)))
1169 return false;
1171 struct ipa_param_aa_status *paa = parm_bb_aa_status_for_bb (fbi,
1172 gimple_bb (call),
1173 index);
1174 if (paa->pt_modified || fbi->aa_walk_budget == 0)
1175 return false;
1177 ao_ref_init_from_ptr_and_size (&refd, parm, NULL_TREE);
1178 int walked = walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified,
1179 &modified, NULL, NULL,
1180 fbi->aa_walk_budget);
1181 if (walked < 0)
1183 fbi->aa_walk_budget = 0;
1184 modified = true;
1186 else
1187 fbi->aa_walk_budget -= walked;
1188 if (modified)
1189 paa->pt_modified = true;
1190 return !modified;
1193 /* Return true if we can prove that OP is a memory reference loading
1194 data from an aggregate passed as a parameter.
1196 The function works in two modes. If GUARANTEED_UNMODIFIED is NULL, it return
1197 false if it cannot prove that the value has not been modified before the
1198 load in STMT. If GUARANTEED_UNMODIFIED is not NULL, it will return true even
1199 if it cannot prove the value has not been modified, in that case it will
1200 store false to *GUARANTEED_UNMODIFIED, otherwise it will store true there.
1202 INFO and PARMS_AINFO describe parameters of the current function (but the
1203 latter can be NULL), STMT is the load statement. If function returns true,
1204 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1205 within the aggregate and whether it is a load from a value passed by
1206 reference respectively.
1208 Return false if the offset divided by BITS_PER_UNIT would not fit into an
1209 unsigned int. */
1211 bool
1212 ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
1213 vec<ipa_param_descriptor, va_gc> *descriptors,
1214 gimple *stmt, tree op, int *index_p,
1215 HOST_WIDE_INT *offset_p, poly_int64 *size_p,
1216 bool *by_ref_p, bool *guaranteed_unmodified)
1218 int index;
1219 HOST_WIDE_INT size;
1220 bool reverse;
1221 tree base = get_ref_base_and_extent_hwi (op, offset_p, &size, &reverse);
1223 if (!base
1224 || (*offset_p / BITS_PER_UNIT) > UINT_MAX)
1225 return false;
1227 /* We can not propagate across volatile loads. */
1228 if (TREE_THIS_VOLATILE (op))
1229 return false;
1231 if (DECL_P (base))
1233 int index = ipa_get_param_decl_index_1 (descriptors, base);
1234 if (index >= 0
1235 && parm_preserved_before_stmt_p (fbi, index, stmt, op))
1237 *index_p = index;
1238 *by_ref_p = false;
1239 if (size_p)
1240 *size_p = size;
1241 if (guaranteed_unmodified)
1242 *guaranteed_unmodified = true;
1243 return true;
1245 return false;
1248 if (TREE_CODE (base) != MEM_REF
1249 || TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME
1250 || !integer_zerop (TREE_OPERAND (base, 1)))
1251 return false;
1253 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0)))
1255 tree parm = SSA_NAME_VAR (TREE_OPERAND (base, 0));
1256 index = ipa_get_param_decl_index_1 (descriptors, parm);
1258 else
1260 /* This branch catches situations where a pointer parameter is not a
1261 gimple register, for example:
1263 void hip7(S*) (struct S * p)
1265 void (*<T2e4>) (struct S *) D.1867;
1266 struct S * p.1;
1268 <bb 2>:
1269 p.1_1 = p;
1270 D.1867_2 = p.1_1->f;
1271 D.1867_2 ();
1272 gdp = &p;
1275 gimple *def = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0));
1276 index = load_from_unmodified_param (fbi, descriptors, def);
1279 if (index >= 0)
1281 bool data_preserved = parm_ref_data_preserved_p (fbi, index, stmt, op);
1282 if (!data_preserved && !guaranteed_unmodified)
1283 return false;
1285 *index_p = index;
1286 *by_ref_p = true;
1287 if (size_p)
1288 *size_p = size;
1289 if (guaranteed_unmodified)
1290 *guaranteed_unmodified = data_preserved;
1291 return true;
1293 return false;
1296 /* If STMT is an assignment that loads a value from a parameter declaration,
1297 or from an aggregate passed as the parameter either by value or reference,
1298 return the index of the parameter in ipa_node_params. Otherwise return -1.
1300 FBI holds gathered information about the function. INFO describes
1301 parameters of the function, STMT is the assignment statement. If it is a
1302 memory load from an aggregate, *OFFSET_P is filled with offset within the
1303 aggregate, and *BY_REF_P specifies whether the aggregate is passed by
1304 reference. */
1306 static int
1307 load_from_unmodified_param_or_agg (struct ipa_func_body_info *fbi,
1308 class ipa_node_params *info,
1309 gimple *stmt,
1310 HOST_WIDE_INT *offset_p,
1311 bool *by_ref_p)
1313 int index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1314 poly_int64 size;
1316 /* Load value from a parameter declaration. */
1317 if (index >= 0)
1319 *offset_p = -1;
1320 return index;
1323 if (!gimple_assign_load_p (stmt))
1324 return -1;
1326 tree rhs = gimple_assign_rhs1 (stmt);
1328 /* Skip memory reference containing VIEW_CONVERT_EXPR. */
1329 for (tree t = rhs; handled_component_p (t); t = TREE_OPERAND (t, 0))
1330 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
1331 return -1;
1333 /* Skip memory reference containing bit-field. */
1334 if (TREE_CODE (rhs) == BIT_FIELD_REF
1335 || contains_bitfld_component_ref_p (rhs))
1336 return -1;
1338 if (!ipa_load_from_parm_agg (fbi, info->descriptors, stmt, rhs, &index,
1339 offset_p, &size, by_ref_p))
1340 return -1;
1342 gcc_assert (!maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (rhs))),
1343 size));
1344 if (!*by_ref_p)
1346 tree param_type = ipa_get_type (info, index);
1348 if (!param_type || !AGGREGATE_TYPE_P (param_type))
1349 return -1;
1351 else if (TREE_THIS_VOLATILE (rhs))
1352 return -1;
1354 return index;
1357 /* Walk pointer adjustemnts from OP (such as POINTER_PLUS and ADDR_EXPR)
1358 to find original pointer. Initialize RET to the pointer which results from
1359 the walk.
1360 If offset is known return true and initialize OFFSET_RET. */
1362 bool
1363 unadjusted_ptr_and_unit_offset (tree op, tree *ret, poly_int64 *offset_ret)
1365 poly_int64 offset = 0;
1366 bool offset_known = true;
1367 int i;
1369 for (i = 0; i < param_ipa_jump_function_lookups; i++)
1371 if (TREE_CODE (op) == ADDR_EXPR)
1373 poly_int64 extra_offset;
1374 tree base = get_addr_base_and_unit_offset (TREE_OPERAND (op, 0),
1375 &extra_offset);
1376 if (!base)
1378 base = get_base_address (TREE_OPERAND (op, 0));
1379 if (TREE_CODE (base) != MEM_REF)
1380 break;
1381 offset_known = false;
1383 else
1385 if (TREE_CODE (base) != MEM_REF)
1386 break;
1387 offset += extra_offset;
1389 op = TREE_OPERAND (base, 0);
1390 if (mem_ref_offset (base).to_shwi (&extra_offset))
1391 offset += extra_offset;
1392 else
1393 offset_known = false;
1395 else if (TREE_CODE (op) == SSA_NAME
1396 && !SSA_NAME_IS_DEFAULT_DEF (op))
1398 gimple *pstmt = SSA_NAME_DEF_STMT (op);
1400 if (gimple_assign_single_p (pstmt))
1401 op = gimple_assign_rhs1 (pstmt);
1402 else if (is_gimple_assign (pstmt)
1403 && gimple_assign_rhs_code (pstmt) == POINTER_PLUS_EXPR)
1405 poly_int64 extra_offset = 0;
1406 if (ptrdiff_tree_p (gimple_assign_rhs2 (pstmt),
1407 &extra_offset))
1408 offset += extra_offset;
1409 else
1410 offset_known = false;
1411 op = gimple_assign_rhs1 (pstmt);
1413 else
1414 break;
1416 else
1417 break;
1419 *ret = op;
1420 *offset_ret = offset;
1421 return offset_known;
1424 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1425 of an assignment statement STMT, try to determine whether we are actually
1426 handling any of the following cases and construct an appropriate jump
1427 function into JFUNC if so:
1429 1) The passed value is loaded from a formal parameter which is not a gimple
1430 register (most probably because it is addressable, the value has to be
1431 scalar) and we can guarantee the value has not changed. This case can
1432 therefore be described by a simple pass-through jump function. For example:
1434 foo (int a)
1436 int a.0;
1438 a.0_2 = a;
1439 bar (a.0_2);
1441 2) The passed value can be described by a simple arithmetic pass-through
1442 jump function. E.g.
1444 foo (int a)
1446 int D.2064;
1448 D.2064_4 = a.1(D) + 4;
1449 bar (D.2064_4);
1451 This case can also occur in combination of the previous one, e.g.:
1453 foo (int a, int z)
1455 int a.0;
1456 int D.2064;
1458 a.0_3 = a;
1459 D.2064_4 = a.0_3 + 4;
1460 foo (D.2064_4);
1462 3) The passed value is an address of an object within another one (which
1463 also passed by reference). Such situations are described by an ancestor
1464 jump function and describe situations such as:
1466 B::foo() (struct B * const this)
1468 struct A * D.1845;
1470 D.1845_2 = &this_1(D)->D.1748;
1471 A::bar (D.1845_2);
1473 INFO is the structure describing individual parameters access different
1474 stages of IPA optimizations. PARMS_AINFO contains the information that is
1475 only needed for intraprocedural analysis. */
1477 static void
1478 compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
1479 class ipa_node_params *info,
1480 struct ipa_jump_func *jfunc,
1481 gcall *call, gimple *stmt, tree name,
1482 tree param_type)
1484 HOST_WIDE_INT offset, size;
1485 tree op1, tc_ssa, base, ssa;
1486 bool reverse;
1487 int index;
1489 op1 = gimple_assign_rhs1 (stmt);
1491 if (TREE_CODE (op1) == SSA_NAME)
1493 if (SSA_NAME_IS_DEFAULT_DEF (op1))
1494 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
1495 else
1496 index = load_from_unmodified_param (fbi, info->descriptors,
1497 SSA_NAME_DEF_STMT (op1));
1498 tc_ssa = op1;
1500 else
1502 index = load_from_unmodified_param (fbi, info->descriptors, stmt);
1503 tc_ssa = gimple_assign_lhs (stmt);
1506 if (index >= 0)
1508 switch (gimple_assign_rhs_class (stmt))
1510 case GIMPLE_BINARY_RHS:
1512 tree op2 = gimple_assign_rhs2 (stmt);
1513 if (!is_gimple_ip_invariant (op2)
1514 || ((TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
1515 != tcc_comparison)
1516 && !useless_type_conversion_p (TREE_TYPE (name),
1517 TREE_TYPE (op1))))
1518 return;
1520 ipa_set_jf_arith_pass_through (jfunc, index, op2,
1521 gimple_assign_rhs_code (stmt));
1522 break;
1524 case GIMPLE_SINGLE_RHS:
1526 bool agg_p = parm_ref_data_pass_through_p (fbi, index, call,
1527 tc_ssa);
1528 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
1529 break;
1531 case GIMPLE_UNARY_RHS:
1532 if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)))
1533 ipa_set_jf_unary_pass_through (jfunc, index,
1534 gimple_assign_rhs_code (stmt));
1535 default:;
1537 return;
1540 if (TREE_CODE (op1) != ADDR_EXPR)
1541 return;
1542 op1 = TREE_OPERAND (op1, 0);
1543 base = get_ref_base_and_extent_hwi (op1, &offset, &size, &reverse);
1544 offset_int mem_offset;
1545 if (!base
1546 || TREE_CODE (base) != MEM_REF
1547 || !mem_ref_offset (base).is_constant (&mem_offset))
1548 return;
1549 offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
1550 ssa = TREE_OPERAND (base, 0);
1551 if (TREE_CODE (ssa) != SSA_NAME
1552 || !SSA_NAME_IS_DEFAULT_DEF (ssa)
1553 || offset < 0)
1554 return;
1556 /* Dynamic types are changed in constructors and destructors. */
1557 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
1558 if (index >= 0 && param_type && POINTER_TYPE_P (param_type))
1559 ipa_set_ancestor_jf (jfunc, offset, index,
1560 parm_ref_data_pass_through_p (fbi, index, call, ssa),
1561 false);
1564 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1565 it looks like:
1567 iftmp.1_3 = &obj_2(D)->D.1762;
1569 The base of the MEM_REF must be a default definition SSA NAME of a
1570 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1571 whole MEM_REF expression is returned and the offset calculated from any
1572 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1573 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1575 static tree
1576 get_ancestor_addr_info (gimple *assign, tree *obj_p, HOST_WIDE_INT *offset)
1578 HOST_WIDE_INT size;
1579 tree expr, parm, obj;
1580 bool reverse;
1582 if (!gimple_assign_single_p (assign))
1583 return NULL_TREE;
1584 expr = gimple_assign_rhs1 (assign);
1586 if (TREE_CODE (expr) != ADDR_EXPR)
1587 return NULL_TREE;
1588 expr = TREE_OPERAND (expr, 0);
1589 obj = expr;
1590 expr = get_ref_base_and_extent_hwi (expr, offset, &size, &reverse);
1592 offset_int mem_offset;
1593 if (!expr
1594 || TREE_CODE (expr) != MEM_REF
1595 || !mem_ref_offset (expr).is_constant (&mem_offset))
1596 return NULL_TREE;
1597 parm = TREE_OPERAND (expr, 0);
1598 if (TREE_CODE (parm) != SSA_NAME
1599 || !SSA_NAME_IS_DEFAULT_DEF (parm)
1600 || TREE_CODE (SSA_NAME_VAR (parm)) != PARM_DECL)
1601 return NULL_TREE;
1603 *offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
1604 *obj_p = obj;
1605 return expr;
1609 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1610 statement PHI, try to find out whether NAME is in fact a
1611 multiple-inheritance typecast from a descendant into an ancestor of a formal
1612 parameter and thus can be described by an ancestor jump function and if so,
1613 write the appropriate function into JFUNC.
1615 Essentially we want to match the following pattern:
1617 if (obj_2(D) != 0B)
1618 goto <bb 3>;
1619 else
1620 goto <bb 4>;
1622 <bb 3>:
1623 iftmp.1_3 = &obj_2(D)->D.1762;
1625 <bb 4>:
1626 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1627 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1628 return D.1879_6; */
1630 static void
1631 compute_complex_ancestor_jump_func (struct ipa_func_body_info *fbi,
1632 class ipa_node_params *info,
1633 struct ipa_jump_func *jfunc,
1634 gcall *call, gphi *phi)
1636 HOST_WIDE_INT offset;
1637 gimple *assign;
1638 basic_block phi_bb, assign_bb, cond_bb;
1639 tree tmp, parm, expr, obj;
1640 int index, i;
1642 if (gimple_phi_num_args (phi) != 2)
1643 return;
1645 if (integer_zerop (PHI_ARG_DEF (phi, 1)))
1646 tmp = PHI_ARG_DEF (phi, 0);
1647 else if (integer_zerop (PHI_ARG_DEF (phi, 0)))
1648 tmp = PHI_ARG_DEF (phi, 1);
1649 else
1650 return;
1651 if (TREE_CODE (tmp) != SSA_NAME
1652 || SSA_NAME_IS_DEFAULT_DEF (tmp)
1653 || !POINTER_TYPE_P (TREE_TYPE (tmp))
1654 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) != RECORD_TYPE)
1655 return;
1657 assign = SSA_NAME_DEF_STMT (tmp);
1658 assign_bb = gimple_bb (assign);
1659 if (!single_pred_p (assign_bb))
1660 return;
1661 expr = get_ancestor_addr_info (assign, &obj, &offset);
1662 if (!expr)
1663 return;
1664 parm = TREE_OPERAND (expr, 0);
1665 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (parm));
1666 if (index < 0)
1667 return;
1669 cond_bb = single_pred (assign_bb);
1670 gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
1671 if (!cond
1672 || gimple_cond_code (cond) != NE_EXPR
1673 || gimple_cond_lhs (cond) != parm
1674 || !integer_zerop (gimple_cond_rhs (cond)))
1675 return;
1677 phi_bb = gimple_bb (phi);
1678 for (i = 0; i < 2; i++)
1680 basic_block pred = EDGE_PRED (phi_bb, i)->src;
1681 if (pred != assign_bb && pred != cond_bb)
1682 return;
1685 ipa_set_ancestor_jf (jfunc, offset, index,
1686 parm_ref_data_pass_through_p (fbi, index, call, parm),
1687 true);
1690 /* Inspect the given TYPE and return true iff it has the same structure (the
1691 same number of fields of the same types) as a C++ member pointer. If
1692 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1693 corresponding fields there. */
1695 static bool
1696 type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
1698 tree fld;
1700 if (TREE_CODE (type) != RECORD_TYPE)
1701 return false;
1703 fld = TYPE_FIELDS (type);
1704 if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
1705 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE
1706 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1707 return false;
1709 if (method_ptr)
1710 *method_ptr = fld;
1712 fld = DECL_CHAIN (fld);
1713 if (!fld || INTEGRAL_TYPE_P (fld)
1714 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
1715 return false;
1716 if (delta)
1717 *delta = fld;
1719 if (DECL_CHAIN (fld))
1720 return false;
1722 return true;
1725 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1726 return the rhs of its defining statement, and this statement is stored in
1727 *RHS_STMT. Otherwise return RHS as it is. */
1729 static inline tree
1730 get_ssa_def_if_simple_copy (tree rhs, gimple **rhs_stmt)
1732 while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
1734 gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
1736 if (gimple_assign_single_p (def_stmt))
1737 rhs = gimple_assign_rhs1 (def_stmt);
1738 else
1739 break;
1740 *rhs_stmt = def_stmt;
1742 return rhs;
1745 /* Simple linked list, describing contents of an aggregate before call. */
1747 struct ipa_known_agg_contents_list
1749 /* Offset and size of the described part of the aggregate. */
1750 HOST_WIDE_INT offset, size;
1752 /* Type of the described part of the aggregate. */
1753 tree type;
1755 /* Known constant value or jump function data describing contents. */
1756 struct ipa_load_agg_data value;
1758 /* Pointer to the next structure in the list. */
1759 struct ipa_known_agg_contents_list *next;
1762 /* Add an aggregate content item into a linked list of
1763 ipa_known_agg_contents_list structure, in which all elements
1764 are sorted ascendingly by offset. */
1766 static inline void
1767 add_to_agg_contents_list (struct ipa_known_agg_contents_list **plist,
1768 struct ipa_known_agg_contents_list *item)
1770 struct ipa_known_agg_contents_list *list = *plist;
1772 for (; list; list = list->next)
1774 if (list->offset >= item->offset)
1775 break;
1777 plist = &list->next;
1780 item->next = list;
1781 *plist = item;
1784 /* Check whether a given aggregate content is clobbered by certain element in
1785 a linked list of ipa_known_agg_contents_list. */
1787 static inline bool
1788 clobber_by_agg_contents_list_p (struct ipa_known_agg_contents_list *list,
1789 struct ipa_known_agg_contents_list *item)
1791 for (; list; list = list->next)
1793 if (list->offset >= item->offset)
1794 return list->offset < item->offset + item->size;
1796 if (list->offset + list->size > item->offset)
1797 return true;
1800 return false;
1803 /* Build aggregate jump function from LIST, assuming there are exactly
1804 VALUE_COUNT entries there and that offset of the passed argument
1805 is ARG_OFFSET and store it into JFUNC. */
1807 static void
1808 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
1809 int value_count, HOST_WIDE_INT arg_offset,
1810 struct ipa_jump_func *jfunc)
1812 vec_safe_reserve (jfunc->agg.items, value_count, true);
1813 for (; list; list = list->next)
1815 struct ipa_agg_jf_item item;
1816 tree operand = list->value.pass_through.operand;
1818 if (list->value.pass_through.formal_id >= 0)
1820 /* Content value is derived from some formal paramerter. */
1821 if (list->value.offset >= 0)
1822 item.jftype = IPA_JF_LOAD_AGG;
1823 else
1824 item.jftype = IPA_JF_PASS_THROUGH;
1826 item.value.load_agg = list->value;
1827 if (operand)
1828 item.value.pass_through.operand
1829 = unshare_expr_without_location (operand);
1831 else if (operand)
1833 /* Content value is known constant. */
1834 item.jftype = IPA_JF_CONST;
1835 item.value.constant = unshare_expr_without_location (operand);
1837 else
1838 continue;
1840 item.type = list->type;
1841 gcc_assert (tree_to_shwi (TYPE_SIZE (list->type)) == list->size);
1843 item.offset = list->offset - arg_offset;
1844 gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
1846 jfunc->agg.items->quick_push (item);
1850 /* Given an assignment statement STMT, try to collect information into
1851 AGG_VALUE that will be used to construct jump function for RHS of the
1852 assignment, from which content value of an aggregate part comes.
1854 Besides constant and simple pass-through jump functions, also try to
1855 identify whether it matches the following pattern that can be described by
1856 a load-value-from-aggregate jump function, which is a derivative of simple
1857 pass-through jump function.
1859 foo (int *p)
1863 *(q_5 + 4) = *(p_3(D) + 28) op 1;
1864 bar (q_5);
1867 Here IPA_LOAD_AGG_DATA data structure is informative enough to describe
1868 constant, simple pass-through and load-vale-from-aggregate. If value
1869 is constant, it will be kept in field OPERAND, and field FORMAL_ID is
1870 set to -1. For simple pass-through and load-value-from-aggregate, field
1871 FORMAL_ID specifies the related formal parameter index, and field
1872 OFFSET can be used to distinguish them, -1 means simple pass-through,
1873 otherwise means load-value-from-aggregate. */
1875 static void
1876 analyze_agg_content_value (struct ipa_func_body_info *fbi,
1877 struct ipa_load_agg_data *agg_value,
1878 gimple *stmt)
1880 tree lhs = gimple_assign_lhs (stmt);
1881 tree rhs1 = gimple_assign_rhs1 (stmt);
1882 enum tree_code code;
1883 int index = -1;
1885 /* Initialize jump function data for the aggregate part. */
1886 memset (agg_value, 0, sizeof (*agg_value));
1887 agg_value->pass_through.operation = NOP_EXPR;
1888 agg_value->pass_through.formal_id = -1;
1889 agg_value->offset = -1;
1891 if (AGGREGATE_TYPE_P (TREE_TYPE (lhs)) /* TODO: Support aggregate type. */
1892 || TREE_THIS_VOLATILE (lhs)
1893 || TREE_CODE (lhs) == BIT_FIELD_REF
1894 || contains_bitfld_component_ref_p (lhs))
1895 return;
1897 /* Skip SSA copies. */
1898 while (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
1900 if (TREE_CODE (rhs1) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (rhs1))
1901 break;
1903 stmt = SSA_NAME_DEF_STMT (rhs1);
1904 if (!is_gimple_assign (stmt))
1905 break;
1907 rhs1 = gimple_assign_rhs1 (stmt);
1910 if (gphi *phi = dyn_cast<gphi *> (stmt))
1912 /* Also special case like the following (a is a formal parameter):
1914 _12 = *a_11(D).dim[0].stride;
1916 # iftmp.22_9 = PHI <_12(2), 1(3)>
1918 parm.6.dim[0].stride = iftmp.22_9;
1920 __x_MOD_foo (&parm.6, b_31(D));
1922 The aggregate function describing parm.6.dim[0].stride is encoded as a
1923 PASS-THROUGH jump function with ASSERT_EXPR operation whith operand 1
1924 (the constant from the PHI node). */
1926 if (gimple_phi_num_args (phi) != 2)
1927 return;
1928 tree arg0 = gimple_phi_arg_def (phi, 0);
1929 tree arg1 = gimple_phi_arg_def (phi, 1);
1930 tree operand;
1932 if (is_gimple_ip_invariant (arg1))
1934 operand = arg1;
1935 rhs1 = arg0;
1937 else if (is_gimple_ip_invariant (arg0))
1939 operand = arg0;
1940 rhs1 = arg1;
1942 else
1943 return;
1945 rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
1946 if (!is_gimple_assign (stmt))
1947 return;
1949 code = ASSERT_EXPR;
1950 agg_value->pass_through.operand = operand;
1952 else if (is_gimple_assign (stmt))
1954 code = gimple_assign_rhs_code (stmt);
1955 switch (gimple_assign_rhs_class (stmt))
1957 case GIMPLE_SINGLE_RHS:
1958 if (is_gimple_ip_invariant (rhs1))
1960 agg_value->pass_through.operand = rhs1;
1961 return;
1963 code = NOP_EXPR;
1964 break;
1966 case GIMPLE_UNARY_RHS:
1967 /* NOTE: A GIMPLE_UNARY_RHS operation might not be tcc_unary
1968 (truth_not_expr is example), GIMPLE_BINARY_RHS does not imply
1969 tcc_binary, this subtleness is somewhat misleading.
1971 Since tcc_unary is widely used in IPA-CP code to check an operation
1972 with one operand, here we only allow tc_unary operation to avoid
1973 possible problem. Then we can use (opclass == tc_unary) or not to
1974 distinguish unary and binary. */
1975 if (TREE_CODE_CLASS (code) != tcc_unary || CONVERT_EXPR_CODE_P (code))
1976 return;
1978 rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
1979 break;
1981 case GIMPLE_BINARY_RHS:
1983 gimple *rhs1_stmt = stmt;
1984 gimple *rhs2_stmt = stmt;
1985 tree rhs2 = gimple_assign_rhs2 (stmt);
1987 rhs1 = get_ssa_def_if_simple_copy (rhs1, &rhs1_stmt);
1988 rhs2 = get_ssa_def_if_simple_copy (rhs2, &rhs2_stmt);
1990 if (is_gimple_ip_invariant (rhs2))
1992 agg_value->pass_through.operand = rhs2;
1993 stmt = rhs1_stmt;
1995 else if (is_gimple_ip_invariant (rhs1))
1997 if (TREE_CODE_CLASS (code) == tcc_comparison)
1998 code = swap_tree_comparison (code);
1999 else if (!commutative_tree_code (code))
2000 return;
2002 agg_value->pass_through.operand = rhs1;
2003 stmt = rhs2_stmt;
2004 rhs1 = rhs2;
2006 else
2007 return;
2009 if (TREE_CODE_CLASS (code) != tcc_comparison
2010 && !useless_type_conversion_p (TREE_TYPE (lhs),
2011 TREE_TYPE (rhs1)))
2012 return;
2014 break;
2016 default:
2017 return;
2020 else
2021 return;
2023 if (TREE_CODE (rhs1) != SSA_NAME)
2024 index = load_from_unmodified_param_or_agg (fbi, fbi->info, stmt,
2025 &agg_value->offset,
2026 &agg_value->by_ref);
2027 else if (SSA_NAME_IS_DEFAULT_DEF (rhs1))
2028 index = ipa_get_param_decl_index (fbi->info, SSA_NAME_VAR (rhs1));
2030 if (index >= 0)
2032 if (agg_value->offset >= 0)
2033 agg_value->type = TREE_TYPE (rhs1);
2034 agg_value->pass_through.formal_id = index;
2035 agg_value->pass_through.operation = code;
2037 else
2038 agg_value->pass_through.operand = NULL_TREE;
2041 /* If STMT is a memory store to the object whose address is BASE, extract
2042 information (offset, size, and value) into CONTENT, and return true,
2043 otherwise we conservatively assume the whole object is modified with
2044 unknown content, and return false. CHECK_REF means that access to object
2045 is expected to be in form of MEM_REF expression. */
2047 static bool
2048 extract_mem_content (struct ipa_func_body_info *fbi,
2049 gimple *stmt, tree base, bool check_ref,
2050 struct ipa_known_agg_contents_list *content)
2052 HOST_WIDE_INT lhs_offset, lhs_size;
2053 bool reverse;
2055 if (!is_gimple_assign (stmt))
2056 return false;
2058 tree lhs = gimple_assign_lhs (stmt);
2059 tree lhs_base = get_ref_base_and_extent_hwi (lhs, &lhs_offset, &lhs_size,
2060 &reverse);
2061 if (!lhs_base)
2062 return false;
2064 if (check_ref)
2066 if (TREE_CODE (lhs_base) != MEM_REF
2067 || TREE_OPERAND (lhs_base, 0) != base
2068 || !integer_zerop (TREE_OPERAND (lhs_base, 1)))
2069 return false;
2071 else if (lhs_base != base)
2072 return false;
2074 content->offset = lhs_offset;
2075 content->size = lhs_size;
2076 content->type = TREE_TYPE (lhs);
2077 content->next = NULL;
2079 analyze_agg_content_value (fbi, &content->value, stmt);
2080 return true;
2083 /* Traverse statements from CALL backwards, scanning whether an aggregate given
2084 in ARG is filled in constants or values that are derived from caller's
2085 formal parameter in the way described by some kinds of jump functions. FBI
2086 is the context of the caller function for interprocedural analysis. ARG can
2087 either be an aggregate expression or a pointer to an aggregate. ARG_TYPE is
2088 the type of the aggregate, JFUNC is the jump function for the aggregate. */
2090 static void
2091 determine_known_aggregate_parts (struct ipa_func_body_info *fbi,
2092 gcall *call, tree arg,
2093 tree arg_type,
2094 struct ipa_jump_func *jfunc)
2096 struct ipa_known_agg_contents_list *list = NULL, *all_list = NULL;
2097 bitmap visited = NULL;
2098 int item_count = 0, value_count = 0;
2099 HOST_WIDE_INT arg_offset, arg_size;
2100 tree arg_base;
2101 bool check_ref, by_ref;
2102 ao_ref r;
2103 int max_agg_items = opt_for_fn (fbi->node->decl, param_ipa_max_agg_items);
2105 if (max_agg_items == 0)
2106 return;
2108 /* The function operates in three stages. First, we prepare check_ref, r,
2109 arg_base and arg_offset based on what is actually passed as an actual
2110 argument. */
2112 if (POINTER_TYPE_P (arg_type))
2114 by_ref = true;
2115 if (TREE_CODE (arg) == SSA_NAME)
2117 tree type_size;
2118 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type)))
2119 || !POINTER_TYPE_P (TREE_TYPE (arg)))
2120 return;
2121 check_ref = true;
2122 arg_base = arg;
2123 arg_offset = 0;
2124 type_size = TYPE_SIZE (TREE_TYPE (arg_type));
2125 arg_size = tree_to_uhwi (type_size);
2126 ao_ref_init_from_ptr_and_size (&r, arg_base, NULL_TREE);
2128 else if (TREE_CODE (arg) == ADDR_EXPR)
2130 bool reverse;
2132 arg = TREE_OPERAND (arg, 0);
2133 arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
2134 &arg_size, &reverse);
2135 if (!arg_base)
2136 return;
2137 if (DECL_P (arg_base))
2139 check_ref = false;
2140 ao_ref_init (&r, arg_base);
2142 else
2143 return;
2145 else
2146 return;
2148 else
2150 bool reverse;
2152 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg)));
2154 by_ref = false;
2155 check_ref = false;
2156 arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
2157 &arg_size, &reverse);
2158 if (!arg_base)
2159 return;
2161 ao_ref_init (&r, arg);
2164 /* Second stage traverses virtual SSA web backwards starting from the call
2165 statement, only looks at individual dominating virtual operand (its
2166 definition dominates the call), as long as it is confident that content
2167 of the aggregate is affected by definition of the virtual operand, it
2168 builds a sorted linked list of ipa_agg_jf_list describing that. */
2170 for (tree dom_vuse = gimple_vuse (call);
2171 dom_vuse && fbi->aa_walk_budget > 0;)
2173 gimple *stmt = SSA_NAME_DEF_STMT (dom_vuse);
2175 if (gimple_code (stmt) == GIMPLE_PHI)
2177 dom_vuse = get_continuation_for_phi (stmt, &r, true,
2178 fbi->aa_walk_budget,
2179 &visited, false, NULL, NULL);
2180 continue;
2183 fbi->aa_walk_budget--;
2184 if (stmt_may_clobber_ref_p_1 (stmt, &r))
2186 struct ipa_known_agg_contents_list *content
2187 = XALLOCA (struct ipa_known_agg_contents_list);
2189 if (!extract_mem_content (fbi, stmt, arg_base, check_ref, content))
2190 break;
2192 /* Now we get a dominating virtual operand, and need to check
2193 whether its value is clobbered any other dominating one. */
2194 if ((content->value.pass_through.formal_id >= 0
2195 || content->value.pass_through.operand)
2196 && !clobber_by_agg_contents_list_p (all_list, content)
2197 /* Since IPA-CP stores results with unsigned int offsets, we can
2198 discard those which would not fit now before we stream them to
2199 WPA. */
2200 && (content->offset + content->size - arg_offset
2201 <= (HOST_WIDE_INT) UINT_MAX * BITS_PER_UNIT))
2203 struct ipa_known_agg_contents_list *copy
2204 = XALLOCA (struct ipa_known_agg_contents_list);
2206 /* Add to the list consisting of only dominating virtual
2207 operands, whose definitions can finally reach the call. */
2208 add_to_agg_contents_list (&list, (*copy = *content, copy));
2210 if (++value_count == max_agg_items)
2211 break;
2214 /* Add to the list consisting of all dominating virtual operands. */
2215 add_to_agg_contents_list (&all_list, content);
2217 if (++item_count == 2 * max_agg_items)
2218 break;
2220 dom_vuse = gimple_vuse (stmt);
2223 if (visited)
2224 BITMAP_FREE (visited);
2226 /* Third stage just goes over the list and creates an appropriate vector of
2227 ipa_agg_jf_item structures out of it, of course only if there are
2228 any meaningful items to begin with. */
2230 if (value_count)
2232 jfunc->agg.by_ref = by_ref;
2233 build_agg_jump_func_from_list (list, value_count, arg_offset, jfunc);
2238 /* Return the Ith param type of callee associated with call graph
2239 edge E. */
2241 tree
2242 ipa_get_callee_param_type (struct cgraph_edge *e, int i)
2244 int n;
2245 tree type = (e->callee
2246 ? TREE_TYPE (e->callee->decl)
2247 : gimple_call_fntype (e->call_stmt));
2248 tree t = TYPE_ARG_TYPES (type);
2250 for (n = 0; n < i; n++)
2252 if (!t)
2253 break;
2254 t = TREE_CHAIN (t);
2256 if (t && t != void_list_node)
2257 return TREE_VALUE (t);
2258 if (!e->callee)
2259 return NULL;
2260 t = DECL_ARGUMENTS (e->callee->decl);
2261 for (n = 0; n < i; n++)
2263 if (!t)
2264 return NULL;
2265 t = TREE_CHAIN (t);
2267 if (t)
2268 return TREE_TYPE (t);
2269 return NULL;
2272 /* Return a pointer to an ipa_vr just like TMP, but either find it in
2273 ipa_vr_hash_table or allocate it in GC memory. */
2275 static ipa_vr *
2276 ipa_get_value_range (const vrange &tmp)
2278 inchash::hash hstate;
2279 inchash::add_vrange (tmp, hstate);
2280 hashval_t hash = hstate.end ();
2281 ipa_vr **slot = ipa_vr_hash_table->find_slot_with_hash (&tmp, hash, INSERT);
2282 if (*slot)
2283 return *slot;
2285 ipa_vr *vr = new (ggc_alloc<ipa_vr> ()) ipa_vr (tmp);
2286 *slot = vr;
2287 return vr;
2290 /* Assign to JF a pointer to a range just like TMP but either fetch a
2291 copy from ipa_vr_hash_table or allocate a new on in GC memory. */
2293 static void
2294 ipa_set_jfunc_vr (ipa_jump_func *jf, const vrange &tmp)
2296 jf->m_vr = ipa_get_value_range (tmp);
2299 static void
2300 ipa_set_jfunc_vr (ipa_jump_func *jf, const ipa_vr &vr)
2302 value_range tmp;
2303 vr.get_vrange (tmp);
2304 ipa_set_jfunc_vr (jf, tmp);
2307 /* Compute jump function for all arguments of callsite CS and insert the
2308 information in the jump_functions array in the ipa_edge_args corresponding
2309 to this callsite. */
2311 static void
2312 ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
2313 struct cgraph_edge *cs)
2315 ipa_node_params *info = ipa_node_params_sum->get (cs->caller);
2316 ipa_edge_args *args = ipa_edge_args_sum->get_create (cs);
2317 gcall *call = cs->call_stmt;
2318 int n, arg_num = gimple_call_num_args (call);
2319 bool useful_context = false;
2321 if (arg_num == 0 || args->jump_functions)
2322 return;
2323 vec_safe_grow_cleared (args->jump_functions, arg_num, true);
2324 if (flag_devirtualize)
2325 vec_safe_grow_cleared (args->polymorphic_call_contexts, arg_num, true);
2327 if (gimple_call_internal_p (call))
2328 return;
2329 if (ipa_func_spec_opts_forbid_analysis_p (cs->caller))
2330 return;
2332 for (n = 0; n < arg_num; n++)
2334 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
2335 tree arg = gimple_call_arg (call, n);
2336 tree param_type = ipa_get_callee_param_type (cs, n);
2337 if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
2339 tree instance;
2340 class ipa_polymorphic_call_context context (cs->caller->decl,
2341 arg, cs->call_stmt,
2342 &instance);
2343 context.get_dynamic_type (instance, arg, NULL, cs->call_stmt,
2344 &fbi->aa_walk_budget);
2345 *ipa_get_ith_polymorhic_call_context (args, n) = context;
2346 if (!context.useless_p ())
2347 useful_context = true;
2350 value_range vr (TREE_TYPE (arg));
2351 if (POINTER_TYPE_P (TREE_TYPE (arg)))
2353 bool addr_nonzero = false;
2354 bool strict_overflow = false;
2356 if (TREE_CODE (arg) == SSA_NAME
2357 && param_type
2358 && get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt)
2359 && vr.nonzero_p ())
2360 addr_nonzero = true;
2361 else if (tree_single_nonzero_warnv_p (arg, &strict_overflow))
2362 addr_nonzero = true;
2364 if (addr_nonzero)
2365 vr.set_nonzero (TREE_TYPE (arg));
2367 unsigned HOST_WIDE_INT bitpos;
2368 unsigned align, prec = TYPE_PRECISION (TREE_TYPE (arg));
2370 get_pointer_alignment_1 (arg, &align, &bitpos);
2372 if (align > BITS_PER_UNIT
2373 && opt_for_fn (cs->caller->decl, flag_ipa_bit_cp))
2375 wide_int mask
2376 = wi::bit_and_not (wi::mask (prec, false, prec),
2377 wide_int::from (align / BITS_PER_UNIT - 1,
2378 prec, UNSIGNED));
2379 wide_int value = wide_int::from (bitpos / BITS_PER_UNIT, prec,
2380 UNSIGNED);
2381 irange_bitmask bm (value, mask);
2382 if (!addr_nonzero)
2383 vr.set_varying (TREE_TYPE (arg));
2384 vr.update_bitmask (bm);
2385 ipa_set_jfunc_vr (jfunc, vr);
2387 else if (addr_nonzero)
2388 ipa_set_jfunc_vr (jfunc, vr);
2389 else
2390 gcc_assert (!jfunc->m_vr);
2392 else
2394 if (param_type
2395 && ipa_supports_p (TREE_TYPE (arg))
2396 && ipa_supports_p (param_type)
2397 && get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt)
2398 && !vr.undefined_p ())
2400 value_range resvr (vr);
2401 range_cast (resvr, param_type);
2402 if (!resvr.undefined_p () && !resvr.varying_p ())
2403 ipa_set_jfunc_vr (jfunc, resvr);
2404 else
2405 gcc_assert (!jfunc->m_vr);
2407 else
2408 gcc_assert (!jfunc->m_vr);
2411 if (is_gimple_ip_invariant (arg)
2412 || (VAR_P (arg)
2413 && is_global_var (arg)
2414 && TREE_READONLY (arg)))
2415 ipa_set_jf_constant (jfunc, arg, cs);
2416 else if (!is_gimple_reg_type (TREE_TYPE (arg))
2417 && TREE_CODE (arg) == PARM_DECL)
2419 int index = ipa_get_param_decl_index (info, arg);
2421 gcc_assert (index >=0);
2422 /* Aggregate passed by value, check for pass-through, otherwise we
2423 will attempt to fill in aggregate contents later in this
2424 for cycle. */
2425 if (parm_preserved_before_stmt_p (fbi, index, call, arg))
2427 ipa_set_jf_simple_pass_through (jfunc, index, false);
2428 continue;
2431 else if (TREE_CODE (arg) == SSA_NAME)
2433 if (SSA_NAME_IS_DEFAULT_DEF (arg))
2435 int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
2436 if (index >= 0)
2438 bool agg_p;
2439 agg_p = parm_ref_data_pass_through_p (fbi, index, call, arg);
2440 ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
2443 else
2445 gimple *stmt = SSA_NAME_DEF_STMT (arg);
2446 if (is_gimple_assign (stmt))
2447 compute_complex_assign_jump_func (fbi, info, jfunc,
2448 call, stmt, arg, param_type);
2449 else if (gimple_code (stmt) == GIMPLE_PHI)
2450 compute_complex_ancestor_jump_func (fbi, info, jfunc,
2451 call,
2452 as_a <gphi *> (stmt));
2456 /* If ARG is pointer, we cannot use its type to determine the type of aggregate
2457 passed (because type conversions are ignored in gimple). Usually we can
2458 safely get type from function declaration, but in case of K&R prototypes or
2459 variadic functions we can try our luck with type of the pointer passed.
2460 TODO: Since we look for actual initialization of the memory object, we may better
2461 work out the type based on the memory stores we find. */
2462 if (!param_type)
2463 param_type = TREE_TYPE (arg);
2465 if ((jfunc->type != IPA_JF_PASS_THROUGH
2466 || !ipa_get_jf_pass_through_agg_preserved (jfunc))
2467 && (jfunc->type != IPA_JF_ANCESTOR
2468 || !ipa_get_jf_ancestor_agg_preserved (jfunc))
2469 && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
2470 || POINTER_TYPE_P (param_type)))
2471 determine_known_aggregate_parts (fbi, call, arg, param_type, jfunc);
2473 if (!useful_context)
2474 vec_free (args->polymorphic_call_contexts);
2477 /* Compute jump functions for all edges - both direct and indirect - outgoing
2478 from BB. */
2480 static void
2481 ipa_compute_jump_functions_for_bb (struct ipa_func_body_info *fbi, basic_block bb)
2483 struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
2484 int i;
2485 struct cgraph_edge *cs;
2487 FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
2489 struct cgraph_node *callee = cs->callee;
2491 if (callee)
2493 callee = callee->ultimate_alias_target ();
2494 /* We do not need to bother analyzing calls to unknown functions
2495 unless they may become known during lto/whopr. */
2496 if (!callee->definition && !flag_lto
2497 && !gimple_call_fnspec (cs->call_stmt).known_p ())
2498 continue;
2500 ipa_compute_jump_functions_for_edge (fbi, cs);
2504 /* If STMT looks like a statement loading a value from a member pointer formal
2505 parameter, return that parameter and store the offset of the field to
2506 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
2507 might be clobbered). If USE_DELTA, then we look for a use of the delta
2508 field rather than the pfn. */
2510 static tree
2511 ipa_get_stmt_member_ptr_load_param (gimple *stmt, bool use_delta,
2512 HOST_WIDE_INT *offset_p)
2514 tree rhs, fld, ptr_field, delta_field;
2515 tree ref_field = NULL_TREE;
2516 tree ref_offset = NULL_TREE;
2518 if (!gimple_assign_single_p (stmt))
2519 return NULL_TREE;
2521 rhs = gimple_assign_rhs1 (stmt);
2522 if (TREE_CODE (rhs) == COMPONENT_REF)
2524 ref_field = TREE_OPERAND (rhs, 1);
2525 rhs = TREE_OPERAND (rhs, 0);
2528 if (TREE_CODE (rhs) == MEM_REF)
2530 ref_offset = TREE_OPERAND (rhs, 1);
2531 if (ref_field && integer_nonzerop (ref_offset))
2532 return NULL_TREE;
2534 else if (!ref_field)
2535 return NULL_TREE;
2537 if (TREE_CODE (rhs) == MEM_REF
2538 && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
2539 && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (rhs, 0)))
2541 rhs = TREE_OPERAND (rhs, 0);
2542 if (TREE_CODE (SSA_NAME_VAR (rhs)) != PARM_DECL
2543 || !type_like_member_ptr_p (TREE_TYPE (TREE_TYPE (rhs)), &ptr_field,
2544 &delta_field))
2545 return NULL_TREE;
2547 else
2549 if (TREE_CODE (rhs) == MEM_REF
2550 && TREE_CODE (TREE_OPERAND (rhs, 0)) == ADDR_EXPR)
2551 rhs = TREE_OPERAND (TREE_OPERAND (rhs, 0), 0);
2552 if (TREE_CODE (rhs) != PARM_DECL
2553 || !type_like_member_ptr_p (TREE_TYPE (rhs), &ptr_field,
2554 &delta_field))
2555 return NULL_TREE;
2558 if (use_delta)
2559 fld = delta_field;
2560 else
2561 fld = ptr_field;
2563 if (ref_field)
2565 if (ref_field != fld)
2566 return NULL_TREE;
2568 else if (!tree_int_cst_equal (byte_position (fld), ref_offset))
2569 return NULL_TREE;
2571 if (offset_p)
2572 *offset_p = int_bit_position (fld);
2573 return rhs;
2576 /* Returns true iff T is an SSA_NAME defined by a statement. */
2578 static bool
2579 ipa_is_ssa_with_stmt_def (tree t)
2581 if (TREE_CODE (t) == SSA_NAME
2582 && !SSA_NAME_IS_DEFAULT_DEF (t))
2583 return true;
2584 else
2585 return false;
2588 /* Find the indirect call graph edge corresponding to STMT and mark it as a
2589 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
2590 indirect call graph edge.
2591 If POLYMORPHIC is true record is as a destination of polymorphic call. */
2593 static struct cgraph_edge *
2594 ipa_note_param_call (struct cgraph_node *node, int param_index,
2595 gcall *stmt, bool polymorphic)
2597 struct cgraph_edge *cs;
2599 cs = node->get_edge (stmt);
2600 cs->indirect_info->param_index = param_index;
2601 cs->indirect_info->agg_contents = 0;
2602 cs->indirect_info->member_ptr = 0;
2603 cs->indirect_info->guaranteed_unmodified = 0;
2604 ipa_node_params *info = ipa_node_params_sum->get (node);
2605 ipa_set_param_used_by_indirect_call (info, param_index, true);
2606 if (cs->indirect_info->polymorphic || polymorphic)
2607 ipa_set_param_used_by_polymorphic_call (info, param_index, true);
2608 return cs;
2611 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
2612 (described by INFO). PARMS_AINFO is a pointer to a vector containing
2613 intermediate information about each formal parameter. Currently it checks
2614 whether the call calls a pointer that is a formal parameter and if so, the
2615 parameter is marked with the called flag and an indirect call graph edge
2616 describing the call is created. This is very simple for ordinary pointers
2617 represented in SSA but not-so-nice when it comes to member pointers. The
2618 ugly part of this function does nothing more than trying to match the
2619 pattern of such a call. Look up the documentation of macro
2620 TARGET_PTRMEMFUNC_VBIT_LOCATION for details. An example of such a pattern
2621 is the gimple dump below, the call is on the last line:
2623 <bb 2>:
2624 f$__delta_5 = f.__delta;
2625 f$__pfn_24 = f.__pfn;
2628 <bb 2>:
2629 f$__delta_5 = MEM[(struct *)&f];
2630 f$__pfn_24 = MEM[(struct *)&f + 4B];
2632 and a few lines below:
2634 <bb 5>
2635 D.2496_3 = (int) f$__pfn_24;
2636 D.2497_4 = D.2496_3 & 1;
2637 if (D.2497_4 != 0)
2638 goto <bb 3>;
2639 else
2640 goto <bb 4>;
2642 <bb 6>:
2643 D.2500_7 = (unsigned int) f$__delta_5;
2644 D.2501_8 = &S + D.2500_7;
2645 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
2646 D.2503_10 = *D.2502_9;
2647 D.2504_12 = f$__pfn_24 + -1;
2648 D.2505_13 = (unsigned int) D.2504_12;
2649 D.2506_14 = D.2503_10 + D.2505_13;
2650 D.2507_15 = *D.2506_14;
2651 iftmp.11_16 = (String:: *) D.2507_15;
2653 <bb 7>:
2654 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
2655 D.2500_19 = (unsigned int) f$__delta_5;
2656 D.2508_20 = &S + D.2500_19;
2657 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
2659 Such patterns are results of simple calls to a member pointer:
2661 int doprinting (int (MyString::* f)(int) const)
2663 MyString S ("somestring");
2665 return (S.*f)(4);
2668 Moreover, the function also looks for called pointers loaded from aggregates
2669 passed by value or reference. */
2671 static void
2672 ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
2673 tree target)
2675 class ipa_node_params *info = fbi->info;
2676 HOST_WIDE_INT offset;
2677 bool by_ref;
2679 if (SSA_NAME_IS_DEFAULT_DEF (target))
2681 tree var = SSA_NAME_VAR (target);
2682 int index = ipa_get_param_decl_index (info, var);
2683 if (index >= 0)
2684 ipa_note_param_call (fbi->node, index, call, false);
2685 return;
2688 int index;
2689 gimple *def = SSA_NAME_DEF_STMT (target);
2690 bool guaranteed_unmodified;
2691 if (gimple_assign_single_p (def)
2692 && ipa_load_from_parm_agg (fbi, info->descriptors, def,
2693 gimple_assign_rhs1 (def), &index, &offset,
2694 NULL, &by_ref, &guaranteed_unmodified))
2696 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2697 call, false);
2698 cs->indirect_info->offset = offset;
2699 cs->indirect_info->agg_contents = 1;
2700 cs->indirect_info->by_ref = by_ref;
2701 cs->indirect_info->guaranteed_unmodified = guaranteed_unmodified;
2702 return;
2705 /* Now we need to try to match the complex pattern of calling a member
2706 pointer. */
2707 if (gimple_code (def) != GIMPLE_PHI
2708 || gimple_phi_num_args (def) != 2
2709 || !POINTER_TYPE_P (TREE_TYPE (target))
2710 || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
2711 return;
2713 /* First, we need to check whether one of these is a load from a member
2714 pointer that is a parameter to this function. */
2715 tree n1 = PHI_ARG_DEF (def, 0);
2716 tree n2 = PHI_ARG_DEF (def, 1);
2717 if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
2718 return;
2719 gimple *d1 = SSA_NAME_DEF_STMT (n1);
2720 gimple *d2 = SSA_NAME_DEF_STMT (n2);
2722 tree rec;
2723 basic_block bb, virt_bb;
2724 basic_block join = gimple_bb (def);
2725 if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false, &offset)))
2727 if (ipa_get_stmt_member_ptr_load_param (d2, false, NULL))
2728 return;
2730 bb = EDGE_PRED (join, 0)->src;
2731 virt_bb = gimple_bb (d2);
2733 else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false, &offset)))
2735 bb = EDGE_PRED (join, 1)->src;
2736 virt_bb = gimple_bb (d1);
2738 else
2739 return;
2741 /* Second, we need to check that the basic blocks are laid out in the way
2742 corresponding to the pattern. */
2744 if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
2745 || single_succ (virt_bb) != join)
2746 return;
2749 if (single_pred (virt_bb) != bb)
2751 /* In cases when the distinction between a normal and a virtual
2752 function is encoded in the delta field, the load of the
2753 actual non-virtual function pointer can be in its own BB. */
2755 if (!single_pred_p (bb) || !single_succ_p (bb))
2756 return;
2757 bb = single_pred (bb);
2758 if (bb != single_pred (virt_bb))
2759 return;
2762 /* Third, let's see that the branching is done depending on the least
2763 significant bit of the pfn. */
2765 gcond *branch = safe_dyn_cast <gcond *> (*gsi_last_bb (bb));
2766 if (!branch)
2767 return;
2769 if ((gimple_cond_code (branch) != NE_EXPR
2770 && gimple_cond_code (branch) != EQ_EXPR)
2771 || !integer_zerop (gimple_cond_rhs (branch)))
2772 return;
2774 tree cond = gimple_cond_lhs (branch);
2775 if (!ipa_is_ssa_with_stmt_def (cond))
2776 return;
2778 def = SSA_NAME_DEF_STMT (cond);
2779 if (!is_gimple_assign (def)
2780 || gimple_assign_rhs_code (def) != BIT_AND_EXPR
2781 || !integer_onep (gimple_assign_rhs2 (def)))
2782 return;
2784 cond = gimple_assign_rhs1 (def);
2785 if (!ipa_is_ssa_with_stmt_def (cond))
2786 return;
2788 def = SSA_NAME_DEF_STMT (cond);
2790 if (is_gimple_assign (def)
2791 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
2793 cond = gimple_assign_rhs1 (def);
2794 if (!ipa_is_ssa_with_stmt_def (cond))
2795 return;
2796 def = SSA_NAME_DEF_STMT (cond);
2799 tree rec2;
2800 rec2 = ipa_get_stmt_member_ptr_load_param (def,
2801 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2802 == ptrmemfunc_vbit_in_delta),
2803 NULL);
2804 if (rec != rec2)
2805 return;
2807 if (TREE_CODE (rec) == SSA_NAME)
2809 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (rec));
2810 if (index < 0
2811 || !parm_ref_data_preserved_p (fbi, index, call,
2812 gimple_assign_rhs1 (def)))
2813 return;
2814 by_ref = true;
2816 else
2818 index = ipa_get_param_decl_index (info, rec);
2819 if (index < 0
2820 || !parm_preserved_before_stmt_p (fbi, index, call, rec))
2821 return;
2822 by_ref = false;
2825 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2826 call, false);
2827 cs->indirect_info->offset = offset;
2828 cs->indirect_info->agg_contents = 1;
2829 cs->indirect_info->member_ptr = 1;
2830 cs->indirect_info->by_ref = by_ref;
2831 cs->indirect_info->guaranteed_unmodified = 1;
2833 return;
2836 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2837 object referenced in the expression is a formal parameter of the caller
2838 FBI->node (described by FBI->info), create a call note for the
2839 statement. */
2841 static void
2842 ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
2843 gcall *call, tree target)
2845 tree obj = OBJ_TYPE_REF_OBJECT (target);
2846 int index;
2847 HOST_WIDE_INT anc_offset;
2849 if (!flag_devirtualize)
2850 return;
2852 if (TREE_CODE (obj) != SSA_NAME)
2853 return;
2855 class ipa_node_params *info = fbi->info;
2856 if (SSA_NAME_IS_DEFAULT_DEF (obj))
2858 if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
2859 return;
2861 anc_offset = 0;
2862 index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
2863 gcc_assert (index >= 0);
2864 if (detect_type_change_ssa (fbi, obj, obj_type_ref_class (target),
2865 call))
2866 return;
2868 else
2870 gimple *stmt = SSA_NAME_DEF_STMT (obj);
2871 tree expr;
2873 expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
2874 if (!expr)
2875 return;
2876 index = ipa_get_param_decl_index (info,
2877 SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
2878 gcc_assert (index >= 0);
2879 if (detect_type_change (fbi, obj, expr, obj_type_ref_class (target),
2880 call, anc_offset))
2881 return;
2884 struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
2885 call, true);
2886 class cgraph_indirect_call_info *ii = cs->indirect_info;
2887 ii->offset = anc_offset;
2888 ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
2889 ii->otr_type = obj_type_ref_class (target);
2890 ii->polymorphic = 1;
2893 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2894 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2895 containing intermediate information about each formal parameter. */
2897 static void
2898 ipa_analyze_call_uses (struct ipa_func_body_info *fbi, gcall *call)
2900 tree target = gimple_call_fn (call);
2902 if (!target
2903 || (TREE_CODE (target) != SSA_NAME
2904 && !virtual_method_call_p (target)))
2905 return;
2907 struct cgraph_edge *cs = fbi->node->get_edge (call);
2908 /* If we previously turned the call into a direct call, there is
2909 no need to analyze. */
2910 if (cs && !cs->indirect_unknown_callee)
2911 return;
2913 if (cs->indirect_info->polymorphic && flag_devirtualize)
2915 tree instance;
2916 tree target = gimple_call_fn (call);
2917 ipa_polymorphic_call_context context (current_function_decl,
2918 target, call, &instance);
2920 gcc_checking_assert (cs->indirect_info->otr_type
2921 == obj_type_ref_class (target));
2922 gcc_checking_assert (cs->indirect_info->otr_token
2923 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
2925 cs->indirect_info->vptr_changed
2926 = !context.get_dynamic_type (instance,
2927 OBJ_TYPE_REF_OBJECT (target),
2928 obj_type_ref_class (target), call,
2929 &fbi->aa_walk_budget);
2930 cs->indirect_info->context = context;
2933 if (TREE_CODE (target) == SSA_NAME)
2934 ipa_analyze_indirect_call_uses (fbi, call, target);
2935 else if (virtual_method_call_p (target))
2936 ipa_analyze_virtual_call_uses (fbi, call, target);
2940 /* Analyze the call statement STMT with respect to formal parameters (described
2941 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2942 formal parameters are called. */
2944 static void
2945 ipa_analyze_stmt_uses (struct ipa_func_body_info *fbi, gimple *stmt)
2947 if (is_gimple_call (stmt))
2948 ipa_analyze_call_uses (fbi, as_a <gcall *> (stmt));
2951 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2952 If OP is a parameter declaration, mark it as used in the info structure
2953 passed in DATA. */
2955 static bool
2956 visit_ref_for_mod_analysis (gimple *, tree op, tree, void *data)
2958 class ipa_node_params *info = (class ipa_node_params *) data;
2960 op = get_base_address (op);
2961 if (op
2962 && TREE_CODE (op) == PARM_DECL)
2964 int index = ipa_get_param_decl_index (info, op);
2965 gcc_assert (index >= 0);
2966 ipa_set_param_used (info, index, true);
2969 return false;
2972 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2973 the findings in various structures of the associated ipa_node_params
2974 structure, such as parameter flags, notes etc. FBI holds various data about
2975 the function being analyzed. */
2977 static void
2978 ipa_analyze_params_uses_in_bb (struct ipa_func_body_info *fbi, basic_block bb)
2980 gimple_stmt_iterator gsi;
2981 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2983 gimple *stmt = gsi_stmt (gsi);
2985 if (is_gimple_debug (stmt))
2986 continue;
2988 ipa_analyze_stmt_uses (fbi, stmt);
2989 walk_stmt_load_store_addr_ops (stmt, fbi->info,
2990 visit_ref_for_mod_analysis,
2991 visit_ref_for_mod_analysis,
2992 visit_ref_for_mod_analysis);
2994 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2995 walk_stmt_load_store_addr_ops (gsi_stmt (gsi), fbi->info,
2996 visit_ref_for_mod_analysis,
2997 visit_ref_for_mod_analysis,
2998 visit_ref_for_mod_analysis);
3001 /* Return true EXPR is a load from a dereference of SSA_NAME NAME. */
3003 static bool
3004 load_from_dereferenced_name (tree expr, tree name)
3006 tree base = get_base_address (expr);
3007 return (TREE_CODE (base) == MEM_REF
3008 && TREE_OPERAND (base, 0) == name);
3011 /* Calculate controlled uses of parameters of NODE. */
3013 static void
3014 ipa_analyze_controlled_uses (struct cgraph_node *node)
3016 ipa_node_params *info = ipa_node_params_sum->get (node);
3018 for (int i = 0; i < ipa_get_param_count (info); i++)
3020 tree parm = ipa_get_param (info, i);
3021 int call_uses = 0;
3022 bool load_dereferenced = false;
3024 /* For SSA regs see if parameter is used. For non-SSA we compute
3025 the flag during modification analysis. */
3026 if (is_gimple_reg (parm))
3028 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl),
3029 parm);
3030 if (ddef && !has_zero_uses (ddef))
3032 imm_use_iterator imm_iter;
3033 gimple *stmt;
3035 ipa_set_param_used (info, i, true);
3036 FOR_EACH_IMM_USE_STMT (stmt, imm_iter, ddef)
3038 if (is_gimple_debug (stmt))
3039 continue;
3041 int all_stmt_uses = 0;
3042 use_operand_p use_p;
3043 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
3044 all_stmt_uses++;
3046 if (is_gimple_call (stmt))
3048 if (gimple_call_internal_p (stmt))
3050 call_uses = IPA_UNDESCRIBED_USE;
3051 break;
3053 int recognized_stmt_uses;
3054 if (gimple_call_fn (stmt) == ddef)
3055 recognized_stmt_uses = 1;
3056 else
3057 recognized_stmt_uses = 0;
3058 unsigned arg_count = gimple_call_num_args (stmt);
3059 for (unsigned i = 0; i < arg_count; i++)
3061 tree arg = gimple_call_arg (stmt, i);
3062 if (arg == ddef)
3063 recognized_stmt_uses++;
3064 else if (load_from_dereferenced_name (arg, ddef))
3066 load_dereferenced = true;
3067 recognized_stmt_uses++;
3071 if (recognized_stmt_uses != all_stmt_uses)
3073 call_uses = IPA_UNDESCRIBED_USE;
3074 break;
3076 if (call_uses >= 0)
3077 call_uses += all_stmt_uses;
3079 else if (gimple_assign_single_p (stmt))
3081 tree rhs = gimple_assign_rhs1 (stmt);
3082 if (all_stmt_uses != 1
3083 || !load_from_dereferenced_name (rhs, ddef))
3085 call_uses = IPA_UNDESCRIBED_USE;
3086 break;
3088 load_dereferenced = true;
3090 else
3092 call_uses = IPA_UNDESCRIBED_USE;
3093 break;
3097 else
3098 call_uses = 0;
3100 else
3101 call_uses = IPA_UNDESCRIBED_USE;
3102 ipa_set_controlled_uses (info, i, call_uses);
3103 ipa_set_param_load_dereferenced (info, i, load_dereferenced);
3107 /* Free stuff in BI. */
3109 static void
3110 free_ipa_bb_info (struct ipa_bb_info *bi)
3112 bi->cg_edges.release ();
3113 bi->param_aa_statuses.release ();
3116 /* Dominator walker driving the analysis. */
3118 class analysis_dom_walker : public dom_walker
3120 public:
3121 analysis_dom_walker (struct ipa_func_body_info *fbi)
3122 : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
3124 edge before_dom_children (basic_block) final override;
3126 private:
3127 struct ipa_func_body_info *m_fbi;
3130 edge
3131 analysis_dom_walker::before_dom_children (basic_block bb)
3133 ipa_analyze_params_uses_in_bb (m_fbi, bb);
3134 ipa_compute_jump_functions_for_bb (m_fbi, bb);
3135 return NULL;
3138 /* Release body info FBI. */
3140 void
3141 ipa_release_body_info (struct ipa_func_body_info *fbi)
3143 int i;
3144 struct ipa_bb_info *bi;
3146 FOR_EACH_VEC_ELT (fbi->bb_infos, i, bi)
3147 free_ipa_bb_info (bi);
3148 fbi->bb_infos.release ();
3151 /* Initialize the array describing properties of formal parameters
3152 of NODE, analyze their uses and compute jump functions associated
3153 with actual arguments of calls from within NODE. */
3155 void
3156 ipa_analyze_node (struct cgraph_node *node)
3158 struct ipa_func_body_info fbi;
3159 class ipa_node_params *info;
3161 ipa_check_create_node_params ();
3162 ipa_check_create_edge_args ();
3163 info = ipa_node_params_sum->get_create (node);
3165 if (info->analysis_done)
3166 return;
3167 info->analysis_done = 1;
3169 if (ipa_func_spec_opts_forbid_analysis_p (node)
3170 || (count_formal_params (node->decl)
3171 >= (1 << IPA_PROP_ARG_INDEX_LIMIT_BITS)))
3173 gcc_assert (!ipa_get_param_count (info));
3174 return;
3177 struct function *func = DECL_STRUCT_FUNCTION (node->decl);
3178 push_cfun (func);
3179 calculate_dominance_info (CDI_DOMINATORS);
3180 ipa_initialize_node_params (node);
3181 ipa_analyze_controlled_uses (node);
3183 fbi.node = node;
3184 fbi.info = info;
3185 fbi.bb_infos = vNULL;
3186 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
3187 fbi.param_count = ipa_get_param_count (info);
3188 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
3190 for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
3192 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3193 bi->cg_edges.safe_push (cs);
3196 for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
3198 ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
3199 bi->cg_edges.safe_push (cs);
3202 enable_ranger (cfun, false);
3203 analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
3204 disable_ranger (cfun);
3206 ipa_release_body_info (&fbi);
3207 free_dominance_info (CDI_DOMINATORS);
3208 pop_cfun ();
3211 /* Update the jump functions associated with call graph edge E when the call
3212 graph edge CS is being inlined, assuming that E->caller is already (possibly
3213 indirectly) inlined into CS->callee and that E has not been inlined. */
3215 static void
3216 update_jump_functions_after_inlining (struct cgraph_edge *cs,
3217 struct cgraph_edge *e)
3219 ipa_edge_args *top = ipa_edge_args_sum->get (cs);
3220 ipa_edge_args *args = ipa_edge_args_sum->get (e);
3221 if (!args)
3222 return;
3223 int count = ipa_get_cs_argument_count (args);
3224 int i;
3226 for (i = 0; i < count; i++)
3228 struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
3229 class ipa_polymorphic_call_context *dst_ctx
3230 = ipa_get_ith_polymorhic_call_context (args, i);
3232 if (dst->agg.items)
3234 struct ipa_agg_jf_item *item;
3235 int j;
3237 FOR_EACH_VEC_ELT (*dst->agg.items, j, item)
3239 int dst_fid;
3240 struct ipa_jump_func *src;
3242 if (item->jftype != IPA_JF_PASS_THROUGH
3243 && item->jftype != IPA_JF_LOAD_AGG)
3244 continue;
3246 dst_fid = item->value.pass_through.formal_id;
3247 if (!top || dst_fid >= ipa_get_cs_argument_count (top))
3249 item->jftype = IPA_JF_UNKNOWN;
3250 continue;
3253 item->value.pass_through.formal_id = -1;
3254 src = ipa_get_ith_jump_func (top, dst_fid);
3255 if (src->type == IPA_JF_CONST)
3257 if (item->jftype == IPA_JF_PASS_THROUGH
3258 && item->value.pass_through.operation == NOP_EXPR)
3260 item->jftype = IPA_JF_CONST;
3261 item->value.constant = src->value.constant.value;
3262 continue;
3265 else if (src->type == IPA_JF_PASS_THROUGH
3266 && src->value.pass_through.operation == NOP_EXPR)
3268 if (item->jftype == IPA_JF_PASS_THROUGH
3269 || !item->value.load_agg.by_ref
3270 || src->value.pass_through.agg_preserved)
3271 item->value.pass_through.formal_id
3272 = src->value.pass_through.formal_id;
3274 else if (src->type == IPA_JF_ANCESTOR)
3276 if (item->jftype == IPA_JF_PASS_THROUGH)
3278 if (!src->value.ancestor.offset)
3279 item->value.pass_through.formal_id
3280 = src->value.ancestor.formal_id;
3282 else if (src->value.ancestor.agg_preserved)
3284 gcc_checking_assert (item->value.load_agg.by_ref);
3286 item->value.pass_through.formal_id
3287 = src->value.ancestor.formal_id;
3288 item->value.load_agg.offset
3289 += src->value.ancestor.offset;
3293 if (item->value.pass_through.formal_id < 0)
3294 item->jftype = IPA_JF_UNKNOWN;
3298 if (!top)
3300 ipa_set_jf_unknown (dst);
3301 continue;
3304 if (dst->type == IPA_JF_ANCESTOR)
3306 struct ipa_jump_func *src;
3307 int dst_fid = dst->value.ancestor.formal_id;
3308 class ipa_polymorphic_call_context *src_ctx
3309 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3311 /* Variable number of arguments can cause havoc if we try to access
3312 one that does not exist in the inlined edge. So make sure we
3313 don't. */
3314 if (dst_fid >= ipa_get_cs_argument_count (top))
3316 ipa_set_jf_unknown (dst);
3317 continue;
3320 src = ipa_get_ith_jump_func (top, dst_fid);
3322 if (src_ctx && !src_ctx->useless_p ())
3324 class ipa_polymorphic_call_context ctx = *src_ctx;
3326 /* TODO: Make type preserved safe WRT contexts. */
3327 if (!ipa_get_jf_ancestor_type_preserved (dst))
3328 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3329 ctx.offset_by (dst->value.ancestor.offset);
3330 if (!ctx.useless_p ())
3332 if (!dst_ctx)
3334 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3335 count, true);
3336 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3339 dst_ctx->combine_with (ctx);
3343 /* Parameter and argument in ancestor jump function must be pointer
3344 type, which means access to aggregate must be by-reference. */
3345 gcc_assert (!src->agg.items || src->agg.by_ref);
3347 if (src->agg.items && dst->value.ancestor.agg_preserved)
3349 struct ipa_agg_jf_item *item;
3350 int j;
3352 /* Currently we do not produce clobber aggregate jump functions,
3353 replace with merging when we do. */
3354 gcc_assert (!dst->agg.items);
3356 dst->agg.items = vec_safe_copy (src->agg.items);
3357 dst->agg.by_ref = src->agg.by_ref;
3358 FOR_EACH_VEC_SAFE_ELT (dst->agg.items, j, item)
3359 item->offset -= dst->value.ancestor.offset;
3362 if (src->type == IPA_JF_PASS_THROUGH
3363 && src->value.pass_through.operation == NOP_EXPR)
3365 dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
3366 dst->value.ancestor.agg_preserved &=
3367 src->value.pass_through.agg_preserved;
3369 else if (src->type == IPA_JF_ANCESTOR)
3371 dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
3372 dst->value.ancestor.offset += src->value.ancestor.offset;
3373 dst->value.ancestor.agg_preserved &=
3374 src->value.ancestor.agg_preserved;
3375 dst->value.ancestor.keep_null |= src->value.ancestor.keep_null;
3377 else
3378 ipa_set_jf_unknown (dst);
3380 else if (dst->type == IPA_JF_PASS_THROUGH)
3382 struct ipa_jump_func *src;
3383 /* We must check range due to calls with variable number of arguments
3384 and we cannot combine jump functions with operations. */
3385 if (dst->value.pass_through.operation == NOP_EXPR
3386 && (top && dst->value.pass_through.formal_id
3387 < ipa_get_cs_argument_count (top)))
3389 int dst_fid = dst->value.pass_through.formal_id;
3390 src = ipa_get_ith_jump_func (top, dst_fid);
3391 bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
3392 class ipa_polymorphic_call_context *src_ctx
3393 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
3395 if (src_ctx && !src_ctx->useless_p ())
3397 class ipa_polymorphic_call_context ctx = *src_ctx;
3399 /* TODO: Make type preserved safe WRT contexts. */
3400 if (!ipa_get_jf_pass_through_type_preserved (dst))
3401 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
3402 if (!ctx.useless_p ())
3404 if (!dst_ctx)
3406 vec_safe_grow_cleared (args->polymorphic_call_contexts,
3407 count, true);
3408 dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
3410 dst_ctx->combine_with (ctx);
3413 switch (src->type)
3415 case IPA_JF_UNKNOWN:
3416 ipa_set_jf_unknown (dst);
3417 break;
3418 case IPA_JF_CONST:
3420 bool rd = ipa_get_jf_pass_through_refdesc_decremented (dst);
3421 ipa_set_jf_cst_copy (dst, src);
3422 if (rd)
3423 ipa_zap_jf_refdesc (dst);
3426 break;
3428 case IPA_JF_PASS_THROUGH:
3430 int formal_id = ipa_get_jf_pass_through_formal_id (src);
3431 enum tree_code operation;
3432 operation = ipa_get_jf_pass_through_operation (src);
3434 if (operation == NOP_EXPR)
3436 bool agg_p;
3437 agg_p = dst_agg_p
3438 && ipa_get_jf_pass_through_agg_preserved (src);
3439 ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
3441 else if (TREE_CODE_CLASS (operation) == tcc_unary)
3442 ipa_set_jf_unary_pass_through (dst, formal_id, operation);
3443 else
3445 tree operand = ipa_get_jf_pass_through_operand (src);
3446 ipa_set_jf_arith_pass_through (dst, formal_id, operand,
3447 operation);
3449 break;
3451 case IPA_JF_ANCESTOR:
3453 bool agg_p;
3454 agg_p = dst_agg_p
3455 && ipa_get_jf_ancestor_agg_preserved (src);
3456 ipa_set_ancestor_jf (dst,
3457 ipa_get_jf_ancestor_offset (src),
3458 ipa_get_jf_ancestor_formal_id (src),
3459 agg_p,
3460 ipa_get_jf_ancestor_keep_null (src));
3461 break;
3463 default:
3464 gcc_unreachable ();
3467 if (src->agg.items
3468 && (dst_agg_p || !src->agg.by_ref))
3470 /* Currently we do not produce clobber aggregate jump
3471 functions, replace with merging when we do. */
3472 gcc_assert (!dst->agg.items);
3474 dst->agg.by_ref = src->agg.by_ref;
3475 dst->agg.items = vec_safe_copy (src->agg.items);
3478 else
3479 ipa_set_jf_unknown (dst);
3484 /* If TARGET is an addr_expr of a function declaration, make it the
3485 (SPECULATIVE)destination of an indirect edge IE and return the edge.
3486 Otherwise, return NULL. */
3488 struct cgraph_edge *
3489 ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
3490 bool speculative)
3492 struct cgraph_node *callee;
3493 bool unreachable = false;
3495 if (TREE_CODE (target) == ADDR_EXPR)
3496 target = TREE_OPERAND (target, 0);
3497 if (TREE_CODE (target) != FUNCTION_DECL)
3499 target = canonicalize_constructor_val (target, NULL);
3500 if (!target || TREE_CODE (target) != FUNCTION_DECL)
3502 /* Member pointer call that goes through a VMT lookup. */
3503 if (ie->indirect_info->member_ptr
3504 /* Or if target is not an invariant expression and we do not
3505 know if it will evaulate to function at runtime.
3506 This can happen when folding through &VAR, where &VAR
3507 is IP invariant, but VAR itself is not.
3509 TODO: Revisit this when GCC 5 is branched. It seems that
3510 member_ptr check is not needed and that we may try to fold
3511 the expression and see if VAR is readonly. */
3512 || !is_gimple_ip_invariant (target))
3514 if (dump_enabled_p ())
3516 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3517 "discovered direct call non-invariant %s\n",
3518 ie->caller->dump_name ());
3520 return NULL;
3524 if (dump_enabled_p ())
3526 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3527 "discovered direct call to non-function in %s, "
3528 "making it __builtin_unreachable\n",
3529 ie->caller->dump_name ());
3532 target = builtin_decl_unreachable ();
3533 callee = cgraph_node::get_create (target);
3534 unreachable = true;
3536 else
3537 callee = cgraph_node::get (target);
3539 else
3540 callee = cgraph_node::get (target);
3542 /* Because may-edges are not explicitely represented and vtable may be external,
3543 we may create the first reference to the object in the unit. */
3544 if (!callee || callee->inlined_to)
3547 /* We are better to ensure we can refer to it.
3548 In the case of static functions we are out of luck, since we already
3549 removed its body. In the case of public functions we may or may
3550 not introduce the reference. */
3551 if (!canonicalize_constructor_val (target, NULL)
3552 || !TREE_PUBLIC (target))
3554 if (dump_file)
3555 fprintf (dump_file, "ipa-prop: Discovered call to a known target "
3556 "(%s -> %s) but cannot refer to it. Giving up.\n",
3557 ie->caller->dump_name (),
3558 ie->callee->dump_name ());
3559 return NULL;
3561 callee = cgraph_node::get_create (target);
3564 /* If the edge is already speculated. */
3565 if (speculative && ie->speculative)
3567 if (dump_file)
3569 cgraph_edge *e2 = ie->speculative_call_for_target (callee);
3570 if (!e2)
3572 if (dump_file)
3573 fprintf (dump_file, "ipa-prop: Discovered call to a "
3574 "speculative target (%s -> %s) but the call is "
3575 "already speculated to different target. "
3576 "Giving up.\n",
3577 ie->caller->dump_name (), callee->dump_name ());
3579 else
3581 if (dump_file)
3582 fprintf (dump_file,
3583 "ipa-prop: Discovered call to a speculative target "
3584 "(%s -> %s) this agree with previous speculation.\n",
3585 ie->caller->dump_name (), callee->dump_name ());
3588 return NULL;
3591 if (!dbg_cnt (devirt))
3592 return NULL;
3594 ipa_check_create_node_params ();
3596 /* We cannot make edges to inline clones. It is bug that someone removed
3597 the cgraph node too early. */
3598 gcc_assert (!callee->inlined_to);
3600 if (dump_file && !unreachable)
3602 fprintf (dump_file, "ipa-prop: Discovered %s call to a %s target "
3603 "(%s -> %s), for stmt ",
3604 ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
3605 speculative ? "speculative" : "known",
3606 ie->caller->dump_name (),
3607 callee->dump_name ());
3608 if (ie->call_stmt)
3609 print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
3610 else
3611 fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
3613 if (dump_enabled_p ())
3615 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
3616 "converting indirect call in %s to direct call to %s\n",
3617 ie->caller->dump_name (), callee->dump_name ());
3619 if (!speculative)
3621 struct cgraph_edge *orig = ie;
3622 ie = cgraph_edge::make_direct (ie, callee);
3623 /* If we resolved speculative edge the cost is already up to date
3624 for direct call (adjusted by inline_edge_duplication_hook). */
3625 if (ie == orig)
3627 ipa_call_summary *es = ipa_call_summaries->get (ie);
3628 es->call_stmt_size -= (eni_size_weights.indirect_call_cost
3629 - eni_size_weights.call_cost);
3630 es->call_stmt_time -= (eni_time_weights.indirect_call_cost
3631 - eni_time_weights.call_cost);
3634 else
3636 if (!callee->can_be_discarded_p ())
3638 cgraph_node *alias;
3639 alias = dyn_cast<cgraph_node *> (callee->noninterposable_alias ());
3640 if (alias)
3641 callee = alias;
3643 /* make_speculative will update ie's cost to direct call cost. */
3644 ie = ie->make_speculative
3645 (callee, ie->count.apply_scale (8, 10));
3648 return ie;
3651 /* Attempt to locate an interprocedural constant at a given REQ_OFFSET in
3652 CONSTRUCTOR and return it. Return NULL if the search fails for some
3653 reason. */
3655 static tree
3656 find_constructor_constant_at_offset (tree constructor, HOST_WIDE_INT req_offset)
3658 tree type = TREE_TYPE (constructor);
3659 if (TREE_CODE (type) != ARRAY_TYPE
3660 && TREE_CODE (type) != RECORD_TYPE)
3661 return NULL;
3663 unsigned ix;
3664 tree index, val;
3665 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (constructor), ix, index, val)
3667 HOST_WIDE_INT elt_offset;
3668 if (TREE_CODE (type) == ARRAY_TYPE)
3670 offset_int off;
3671 tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
3672 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3674 if (index)
3676 if (TREE_CODE (index) == RANGE_EXPR)
3677 off = wi::to_offset (TREE_OPERAND (index, 0));
3678 else
3679 off = wi::to_offset (index);
3680 if (TYPE_DOMAIN (type) && TYPE_MIN_VALUE (TYPE_DOMAIN (type)))
3682 tree low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
3683 gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
3684 off = wi::sext (off - wi::to_offset (low_bound),
3685 TYPE_PRECISION (TREE_TYPE (index)));
3687 off *= wi::to_offset (unit_size);
3688 /* ??? Handle more than just the first index of a
3689 RANGE_EXPR. */
3691 else
3692 off = wi::to_offset (unit_size) * ix;
3694 off = wi::lshift (off, LOG2_BITS_PER_UNIT);
3695 if (!wi::fits_shwi_p (off) || wi::neg_p (off))
3696 continue;
3697 elt_offset = off.to_shwi ();
3699 else if (TREE_CODE (type) == RECORD_TYPE)
3701 gcc_checking_assert (index && TREE_CODE (index) == FIELD_DECL);
3702 if (DECL_BIT_FIELD (index))
3703 continue;
3704 elt_offset = int_bit_position (index);
3706 else
3707 gcc_unreachable ();
3709 if (elt_offset > req_offset)
3710 return NULL;
3712 if (TREE_CODE (val) == CONSTRUCTOR)
3713 return find_constructor_constant_at_offset (val,
3714 req_offset - elt_offset);
3716 if (elt_offset == req_offset
3717 && is_gimple_reg_type (TREE_TYPE (val))
3718 && is_gimple_ip_invariant (val))
3719 return val;
3721 return NULL;
3724 /* Check whether SCALAR could be used to look up an aggregate interprocedural
3725 invariant from a static constructor and if so, return it. Otherwise return
3726 NULL. */
3728 tree
3729 ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset, bool by_ref)
3731 if (by_ref)
3733 if (TREE_CODE (scalar) != ADDR_EXPR)
3734 return NULL;
3735 scalar = TREE_OPERAND (scalar, 0);
3738 if (!VAR_P (scalar)
3739 || !is_global_var (scalar)
3740 || !TREE_READONLY (scalar)
3741 || !DECL_INITIAL (scalar)
3742 || TREE_CODE (DECL_INITIAL (scalar)) != CONSTRUCTOR)
3743 return NULL;
3745 return find_constructor_constant_at_offset (DECL_INITIAL (scalar), offset);
3748 /* Retrieve value from AGG_JFUNC for the given OFFSET or return NULL if there
3749 is none. BY_REF specifies whether the value has to be passed by reference
3750 or by value. */
3752 static tree
3753 ipa_find_agg_cst_from_jfunc_items (struct ipa_agg_jump_function *agg_jfunc,
3754 ipa_node_params *src_info,
3755 cgraph_node *src_node,
3756 HOST_WIDE_INT offset, bool by_ref)
3758 if (by_ref != agg_jfunc->by_ref)
3759 return NULL_TREE;
3761 for (const ipa_agg_jf_item &item : agg_jfunc->items)
3762 if (item.offset == offset)
3763 return ipa_agg_value_from_jfunc (src_info, src_node, &item);
3765 return NULL_TREE;
3768 /* Remove a reference to SYMBOL from the list of references of a node given by
3769 reference description RDESC. Return true if the reference has been
3770 successfully found and removed. */
3772 static bool
3773 remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
3775 struct ipa_ref *to_del;
3776 struct cgraph_edge *origin;
3778 origin = rdesc->cs;
3779 if (!origin)
3780 return false;
3781 to_del = origin->caller->find_reference (symbol, origin->call_stmt,
3782 origin->lto_stmt_uid, IPA_REF_ADDR);
3783 if (!to_del)
3784 return false;
3786 to_del->remove_reference ();
3787 if (dump_file)
3788 fprintf (dump_file, "ipa-prop: Removed a reference from %s to %s.\n",
3789 origin->caller->dump_name (), symbol->dump_name ());
3790 return true;
3793 /* If JFUNC has a reference description with refcount different from
3794 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
3795 NULL. JFUNC must be a constant jump function. */
3797 static struct ipa_cst_ref_desc *
3798 jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
3800 struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
3801 if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
3802 return rdesc;
3803 else
3804 return NULL;
3807 /* If the value of constant jump function JFUNC is an address of a function
3808 declaration, return the associated call graph node. Otherwise return
3809 NULL. */
3811 static symtab_node *
3812 symtab_node_for_jfunc (struct ipa_jump_func *jfunc)
3814 gcc_checking_assert (jfunc->type == IPA_JF_CONST);
3815 tree cst = ipa_get_jf_constant (jfunc);
3816 if (TREE_CODE (cst) != ADDR_EXPR
3817 || (TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL
3818 && TREE_CODE (TREE_OPERAND (cst, 0)) != VAR_DECL))
3819 return NULL;
3821 return symtab_node::get (TREE_OPERAND (cst, 0));
3825 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
3826 refcount and if it hits zero, remove reference to SYMBOL from the caller of
3827 the edge specified in the rdesc. Return false if either the symbol or the
3828 reference could not be found, otherwise return true. */
3830 static bool
3831 try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
3833 struct ipa_cst_ref_desc *rdesc;
3834 if (jfunc->type == IPA_JF_CONST
3835 && (rdesc = jfunc_rdesc_usable (jfunc))
3836 && --rdesc->refcount == 0)
3838 symtab_node *symbol = symtab_node_for_jfunc (jfunc);
3839 if (!symbol)
3840 return false;
3842 return remove_described_reference (symbol, rdesc);
3844 return true;
3847 /* Try to find a destination for indirect edge IE that corresponds to a simple
3848 call or a call of a member function pointer and where the destination is a
3849 pointer formal parameter described by jump function JFUNC. TARGET_TYPE is
3850 the type of the parameter to which the result of JFUNC is passed. If it can
3851 be determined, return the newly direct edge, otherwise return NULL.
3852 NEW_ROOT and NEW_ROOT_INFO is the node and its info that JFUNC lattices are
3853 relative to. */
3855 static struct cgraph_edge *
3856 try_make_edge_direct_simple_call (struct cgraph_edge *ie,
3857 struct ipa_jump_func *jfunc, tree target_type,
3858 struct cgraph_node *new_root,
3859 class ipa_node_params *new_root_info)
3861 struct cgraph_edge *cs;
3862 tree target = NULL_TREE;
3863 bool agg_contents = ie->indirect_info->agg_contents;
3864 tree scalar = ipa_value_from_jfunc (new_root_info, jfunc, target_type);
3865 if (agg_contents)
3867 if (scalar)
3868 target = ipa_find_agg_cst_from_init (scalar, ie->indirect_info->offset,
3869 ie->indirect_info->by_ref);
3870 if (!target && ie->indirect_info->guaranteed_unmodified)
3871 target = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3872 new_root,
3873 ie->indirect_info->offset,
3874 ie->indirect_info->by_ref);
3876 else
3877 target = scalar;
3878 if (!target)
3879 return NULL;
3880 cs = ipa_make_edge_direct_to_target (ie, target);
3882 if (cs && !agg_contents)
3884 bool ok;
3885 gcc_checking_assert (cs->callee
3886 && (cs != ie
3887 || jfunc->type != IPA_JF_CONST
3888 || !symtab_node_for_jfunc (jfunc)
3889 || cs->callee == symtab_node_for_jfunc (jfunc)));
3890 ok = try_decrement_rdesc_refcount (jfunc);
3891 gcc_checking_assert (ok);
3894 return cs;
3897 /* Return the target to be used in cases of impossible devirtualization. IE
3898 and target (the latter can be NULL) are dumped when dumping is enabled. */
3900 tree
3901 ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
3903 if (dump_file)
3905 if (target)
3906 fprintf (dump_file,
3907 "Type inconsistent devirtualization: %s->%s\n",
3908 ie->caller->dump_name (),
3909 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
3910 else
3911 fprintf (dump_file,
3912 "No devirtualization target in %s\n",
3913 ie->caller->dump_name ());
3915 tree new_target = builtin_decl_unreachable ();
3916 cgraph_node::get_create (new_target);
3917 return new_target;
3920 /* Try to find a destination for indirect edge IE that corresponds to a virtual
3921 call based on a formal parameter which is described by jump function JFUNC
3922 and if it can be determined, make it direct and return the direct edge.
3923 Otherwise, return NULL. CTX describes the polymorphic context that the
3924 parameter the call is based on brings along with it. NEW_ROOT and
3925 NEW_ROOT_INFO is the node and its info that JFUNC lattices are relative
3926 to. */
3928 static struct cgraph_edge *
3929 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
3930 struct ipa_jump_func *jfunc,
3931 class ipa_polymorphic_call_context ctx,
3932 struct cgraph_node *new_root,
3933 class ipa_node_params *new_root_info)
3935 tree target = NULL;
3936 bool speculative = false;
3938 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
3939 return NULL;
3941 gcc_assert (!ie->indirect_info->by_ref);
3943 /* Try to do lookup via known virtual table pointer value. */
3944 if (!ie->indirect_info->vptr_changed
3945 || opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively))
3947 tree vtable;
3948 unsigned HOST_WIDE_INT offset;
3949 tree t = NULL_TREE;
3950 if (jfunc->type == IPA_JF_CONST)
3951 t = ipa_find_agg_cst_from_init (ipa_get_jf_constant (jfunc),
3952 ie->indirect_info->offset, true);
3953 if (!t)
3954 t = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
3955 new_root,
3956 ie->indirect_info->offset, true);
3957 if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
3959 bool can_refer;
3960 t = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
3961 vtable, offset, &can_refer);
3962 if (can_refer)
3964 if (!t
3965 || fndecl_built_in_p (t, BUILT_IN_UNREACHABLE,
3966 BUILT_IN_UNREACHABLE_TRAP)
3967 || !possible_polymorphic_call_target_p
3968 (ie, cgraph_node::get (t)))
3970 /* Do not speculate builtin_unreachable, it is stupid! */
3971 if (!ie->indirect_info->vptr_changed)
3972 target = ipa_impossible_devirt_target (ie, target);
3973 else
3974 target = NULL;
3976 else
3978 target = t;
3979 speculative = ie->indirect_info->vptr_changed;
3985 ipa_polymorphic_call_context ie_context (ie);
3986 vec <cgraph_node *>targets;
3987 bool final;
3989 ctx.offset_by (ie->indirect_info->offset);
3990 if (ie->indirect_info->vptr_changed)
3991 ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3992 ie->indirect_info->otr_type);
3993 ctx.combine_with (ie_context, ie->indirect_info->otr_type);
3994 targets = possible_polymorphic_call_targets
3995 (ie->indirect_info->otr_type,
3996 ie->indirect_info->otr_token,
3997 ctx, &final);
3998 if (final && targets.length () <= 1)
4000 speculative = false;
4001 if (targets.length () == 1)
4002 target = targets[0]->decl;
4003 else
4004 target = ipa_impossible_devirt_target (ie, NULL_TREE);
4006 else if (!target && opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
4007 && !ie->speculative && ie->maybe_hot_p ())
4009 cgraph_node *n;
4010 n = try_speculative_devirtualization (ie->indirect_info->otr_type,
4011 ie->indirect_info->otr_token,
4012 ie->indirect_info->context);
4013 if (n)
4015 target = n->decl;
4016 speculative = true;
4020 if (target)
4022 if (!possible_polymorphic_call_target_p
4023 (ie, cgraph_node::get_create (target)))
4025 if (speculative)
4026 return NULL;
4027 target = ipa_impossible_devirt_target (ie, target);
4029 return ipa_make_edge_direct_to_target (ie, target, speculative);
4031 else
4032 return NULL;
4035 /* Update the param called notes associated with NODE when CS is being inlined,
4036 assuming NODE is (potentially indirectly) inlined into CS->callee.
4037 Moreover, if the callee is discovered to be constant, create a new cgraph
4038 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
4039 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
4041 static bool
4042 update_indirect_edges_after_inlining (struct cgraph_edge *cs,
4043 struct cgraph_node *node,
4044 vec<cgraph_edge *> *new_edges)
4046 class ipa_edge_args *top;
4047 struct cgraph_edge *ie, *next_ie, *new_direct_edge;
4048 struct cgraph_node *new_root;
4049 class ipa_node_params *new_root_info, *inlined_node_info;
4050 bool res = false;
4052 ipa_check_create_edge_args ();
4053 top = ipa_edge_args_sum->get (cs);
4054 new_root = cs->caller->inlined_to
4055 ? cs->caller->inlined_to : cs->caller;
4056 new_root_info = ipa_node_params_sum->get (new_root);
4057 inlined_node_info = ipa_node_params_sum->get (cs->callee->function_symbol ());
4059 for (ie = node->indirect_calls; ie; ie = next_ie)
4061 class cgraph_indirect_call_info *ici = ie->indirect_info;
4062 struct ipa_jump_func *jfunc;
4063 int param_index;
4065 next_ie = ie->next_callee;
4067 if (ici->param_index == -1)
4068 continue;
4070 /* We must check range due to calls with variable number of arguments: */
4071 if (!top || ici->param_index >= ipa_get_cs_argument_count (top))
4073 ici->param_index = -1;
4074 continue;
4077 param_index = ici->param_index;
4078 jfunc = ipa_get_ith_jump_func (top, param_index);
4080 auto_vec<cgraph_node *, 4> spec_targets;
4081 if (ie->speculative)
4082 for (cgraph_edge *direct = ie->first_speculative_call_target ();
4083 direct;
4084 direct = direct->next_speculative_call_target ())
4085 spec_targets.safe_push (direct->callee);
4087 if (!opt_for_fn (node->decl, flag_indirect_inlining))
4088 new_direct_edge = NULL;
4089 else if (ici->polymorphic)
4091 ipa_polymorphic_call_context ctx;
4092 ctx = ipa_context_from_jfunc (new_root_info, cs, param_index, jfunc);
4093 new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx,
4094 new_root,
4095 new_root_info);
4097 else
4099 tree target_type = ipa_get_type (inlined_node_info, param_index);
4100 new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
4101 target_type,
4102 new_root,
4103 new_root_info);
4106 /* If speculation was removed, then we need to do nothing. */
4107 if (new_direct_edge && new_direct_edge != ie
4108 && spec_targets.contains (new_direct_edge->callee))
4110 new_direct_edge->indirect_inlining_edge = 1;
4111 res = true;
4112 if (!new_direct_edge->speculative)
4113 continue;
4115 else if (new_direct_edge)
4117 new_direct_edge->indirect_inlining_edge = 1;
4118 if (new_edges)
4120 new_edges->safe_push (new_direct_edge);
4121 res = true;
4123 /* If speculative edge was introduced we still need to update
4124 call info of the indirect edge. */
4125 if (!new_direct_edge->speculative)
4126 continue;
4128 if (jfunc->type == IPA_JF_PASS_THROUGH
4129 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4131 if (ici->agg_contents
4132 && !ipa_get_jf_pass_through_agg_preserved (jfunc)
4133 && !ici->polymorphic)
4134 ici->param_index = -1;
4135 else
4137 ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc);
4138 if (ici->polymorphic
4139 && !ipa_get_jf_pass_through_type_preserved (jfunc))
4140 ici->vptr_changed = true;
4141 ipa_set_param_used_by_indirect_call (new_root_info,
4142 ici->param_index, true);
4143 if (ici->polymorphic)
4144 ipa_set_param_used_by_polymorphic_call (new_root_info,
4145 ici->param_index, true);
4148 else if (jfunc->type == IPA_JF_ANCESTOR)
4150 if (ici->agg_contents
4151 && !ipa_get_jf_ancestor_agg_preserved (jfunc)
4152 && !ici->polymorphic)
4153 ici->param_index = -1;
4154 else
4156 ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
4157 ici->offset += ipa_get_jf_ancestor_offset (jfunc);
4158 if (ici->polymorphic
4159 && !ipa_get_jf_ancestor_type_preserved (jfunc))
4160 ici->vptr_changed = true;
4161 ipa_set_param_used_by_indirect_call (new_root_info,
4162 ici->param_index, true);
4163 if (ici->polymorphic)
4164 ipa_set_param_used_by_polymorphic_call (new_root_info,
4165 ici->param_index, true);
4168 else
4169 /* Either we can find a destination for this edge now or never. */
4170 ici->param_index = -1;
4173 return res;
4176 /* Recursively traverse subtree of NODE (including node) made of inlined
4177 cgraph_edges when CS has been inlined and invoke
4178 update_indirect_edges_after_inlining on all nodes and
4179 update_jump_functions_after_inlining on all non-inlined edges that lead out
4180 of this subtree. Newly discovered indirect edges will be added to
4181 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
4182 created. */
4184 static bool
4185 propagate_info_to_inlined_callees (struct cgraph_edge *cs,
4186 struct cgraph_node *node,
4187 vec<cgraph_edge *> *new_edges)
4189 struct cgraph_edge *e;
4190 bool res;
4192 res = update_indirect_edges_after_inlining (cs, node, new_edges);
4194 for (e = node->callees; e; e = e->next_callee)
4195 if (!e->inline_failed)
4196 res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
4197 else
4198 update_jump_functions_after_inlining (cs, e);
4199 for (e = node->indirect_calls; e; e = e->next_callee)
4200 update_jump_functions_after_inlining (cs, e);
4202 return res;
4205 /* Combine two controlled uses counts as done during inlining. */
4207 static int
4208 combine_controlled_uses_counters (int c, int d)
4210 if (c == IPA_UNDESCRIBED_USE || d == IPA_UNDESCRIBED_USE)
4211 return IPA_UNDESCRIBED_USE;
4212 else
4213 return c + d - 1;
4216 /* Propagate number of controlled users from CS->caleee to the new root of the
4217 tree of inlined nodes. */
4219 static void
4220 propagate_controlled_uses (struct cgraph_edge *cs)
4222 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4223 if (!args)
4224 return;
4225 struct cgraph_node *new_root = cs->caller->inlined_to
4226 ? cs->caller->inlined_to : cs->caller;
4227 ipa_node_params *new_root_info = ipa_node_params_sum->get (new_root);
4228 ipa_node_params *old_root_info = ipa_node_params_sum->get (cs->callee);
4229 int count, i;
4231 if (!old_root_info)
4232 return;
4234 count = MIN (ipa_get_cs_argument_count (args),
4235 ipa_get_param_count (old_root_info));
4236 for (i = 0; i < count; i++)
4238 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4239 struct ipa_cst_ref_desc *rdesc;
4241 if (jf->type == IPA_JF_PASS_THROUGH
4242 && !ipa_get_jf_pass_through_refdesc_decremented (jf))
4244 int src_idx, c, d;
4245 src_idx = ipa_get_jf_pass_through_formal_id (jf);
4246 c = ipa_get_controlled_uses (new_root_info, src_idx);
4247 d = ipa_get_controlled_uses (old_root_info, i);
4249 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf)
4250 == NOP_EXPR || c == IPA_UNDESCRIBED_USE);
4251 c = combine_controlled_uses_counters (c, d);
4252 ipa_set_controlled_uses (new_root_info, src_idx, c);
4253 bool lderef = true;
4254 if (c != IPA_UNDESCRIBED_USE)
4256 lderef = (ipa_get_param_load_dereferenced (new_root_info, src_idx)
4257 || ipa_get_param_load_dereferenced (old_root_info, i));
4258 ipa_set_param_load_dereferenced (new_root_info, src_idx, lderef);
4261 if (c == 0 && !lderef && new_root_info->ipcp_orig_node)
4263 struct cgraph_node *n;
4264 struct ipa_ref *ref;
4265 tree t = new_root_info->known_csts[src_idx];
4267 if (t && TREE_CODE (t) == ADDR_EXPR
4268 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
4269 && (n = cgraph_node::get (TREE_OPERAND (t, 0)))
4270 && (ref = new_root->find_reference (n, NULL, 0,
4271 IPA_REF_ADDR)))
4273 if (dump_file)
4274 fprintf (dump_file, "ipa-prop: Removing cloning-created "
4275 "reference from %s to %s.\n",
4276 new_root->dump_name (),
4277 n->dump_name ());
4278 ref->remove_reference ();
4282 else if (jf->type == IPA_JF_CONST
4283 && (rdesc = jfunc_rdesc_usable (jf)))
4285 int d = ipa_get_controlled_uses (old_root_info, i);
4286 int c = rdesc->refcount;
4287 tree cst = ipa_get_jf_constant (jf);
4288 rdesc->refcount = combine_controlled_uses_counters (c, d);
4289 if (rdesc->refcount != IPA_UNDESCRIBED_USE
4290 && ipa_get_param_load_dereferenced (old_root_info, i)
4291 && TREE_CODE (cst) == ADDR_EXPR
4292 && VAR_P (TREE_OPERAND (cst, 0)))
4294 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4295 new_root->create_reference (n, IPA_REF_LOAD, NULL);
4296 if (dump_file)
4297 fprintf (dump_file, "ipa-prop: Address IPA constant will reach "
4298 "a load so adding LOAD reference from %s to %s.\n",
4299 new_root->dump_name (), n->dump_name ());
4301 if (rdesc->refcount == 0)
4303 gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
4304 && ((TREE_CODE (TREE_OPERAND (cst, 0))
4305 == FUNCTION_DECL)
4306 || VAR_P (TREE_OPERAND (cst, 0))));
4308 symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
4309 if (n)
4311 remove_described_reference (n, rdesc);
4312 cgraph_node *clone = cs->caller;
4313 while (clone->inlined_to
4314 && clone->ipcp_clone
4315 && clone != rdesc->cs->caller)
4317 struct ipa_ref *ref;
4318 ref = clone->find_reference (n, NULL, 0, IPA_REF_ADDR);
4319 if (ref)
4321 if (dump_file)
4322 fprintf (dump_file, "ipa-prop: Removing "
4323 "cloning-created reference "
4324 "from %s to %s.\n",
4325 clone->dump_name (),
4326 n->dump_name ());
4327 ref->remove_reference ();
4329 clone = clone->callers->caller;
4336 for (i = ipa_get_param_count (old_root_info);
4337 i < ipa_get_cs_argument_count (args);
4338 i++)
4340 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
4342 if (jf->type == IPA_JF_CONST)
4344 struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
4345 if (rdesc)
4346 rdesc->refcount = IPA_UNDESCRIBED_USE;
4348 else if (jf->type == IPA_JF_PASS_THROUGH)
4349 ipa_set_controlled_uses (new_root_info,
4350 jf->value.pass_through.formal_id,
4351 IPA_UNDESCRIBED_USE);
4355 /* Update jump functions and call note functions on inlining the call site CS.
4356 CS is expected to lead to a node already cloned by
4357 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
4358 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
4359 created. */
4361 bool
4362 ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
4363 vec<cgraph_edge *> *new_edges)
4365 bool changed;
4366 /* Do nothing if the preparation phase has not been carried out yet
4367 (i.e. during early inlining). */
4368 if (!ipa_node_params_sum)
4369 return false;
4370 gcc_assert (ipa_edge_args_sum);
4372 propagate_controlled_uses (cs);
4373 changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
4374 ipa_node_params_sum->remove (cs->callee);
4376 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
4377 if (args)
4379 bool ok = true;
4380 if (args->jump_functions)
4382 struct ipa_jump_func *jf;
4383 int i;
4384 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4385 if (jf->type == IPA_JF_CONST
4386 && ipa_get_jf_constant_rdesc (jf))
4388 ok = false;
4389 break;
4392 if (ok)
4393 ipa_edge_args_sum->remove (cs);
4395 if (ipcp_transformation_sum)
4396 ipcp_transformation_sum->remove (cs->callee);
4398 return changed;
4401 /* Ensure that array of edge arguments infos is big enough to accommodate a
4402 structure for all edges and reallocates it if not. Also, allocate
4403 associated hash tables is they do not already exist. */
4405 void
4406 ipa_check_create_edge_args (void)
4408 if (!ipa_edge_args_sum)
4409 ipa_edge_args_sum
4410 = (new (ggc_alloc_no_dtor<ipa_edge_args_sum_t> ())
4411 ipa_edge_args_sum_t (symtab, true));
4412 if (!ipa_vr_hash_table)
4413 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4416 /* Free all ipa_edge structures. */
4418 void
4419 ipa_free_all_edge_args (void)
4421 if (!ipa_edge_args_sum)
4422 return;
4424 ggc_delete (ipa_edge_args_sum);
4425 ipa_edge_args_sum = NULL;
4428 /* Free all ipa_node_params structures. */
4430 void
4431 ipa_free_all_node_params (void)
4433 if (ipa_node_params_sum)
4434 ggc_delete (ipa_node_params_sum);
4435 ipa_node_params_sum = NULL;
4438 /* Initialize IPA CP transformation summary and also allocate any necessary hash
4439 tables if they do not already exist. */
4441 void
4442 ipcp_transformation_initialize (void)
4444 if (!ipa_vr_hash_table)
4445 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
4446 if (ipcp_transformation_sum == NULL)
4448 ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab);
4449 ipcp_transformation_sum->disable_insertion_hook ();
4453 /* Release the IPA CP transformation summary. */
4455 void
4456 ipcp_free_transformation_sum (void)
4458 if (!ipcp_transformation_sum)
4459 return;
4461 ipcp_transformation_sum->~function_summary<ipcp_transformation *> ();
4462 ggc_free (ipcp_transformation_sum);
4463 ipcp_transformation_sum = NULL;
4466 /* Set the aggregate replacements of NODE to be AGGVALS. */
4468 void
4469 ipa_set_node_agg_value_chain (struct cgraph_node *node,
4470 vec<ipa_argagg_value, va_gc> *aggs)
4472 ipcp_transformation_initialize ();
4473 ipcp_transformation *s = ipcp_transformation_sum->get_create (node);
4474 s->m_agg_values = aggs;
4477 /* Hook that is called by cgraph.cc when an edge is removed. Adjust reference
4478 count data structures accordingly. */
4480 void
4481 ipa_edge_args_sum_t::remove (cgraph_edge *cs, ipa_edge_args *args)
4483 if (args->jump_functions)
4485 struct ipa_jump_func *jf;
4486 int i;
4487 FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
4489 struct ipa_cst_ref_desc *rdesc;
4490 try_decrement_rdesc_refcount (jf);
4491 if (jf->type == IPA_JF_CONST
4492 && (rdesc = ipa_get_jf_constant_rdesc (jf))
4493 && rdesc->cs == cs)
4494 rdesc->cs = NULL;
4499 /* Method invoked when an edge is duplicated. Copy ipa_edge_args and adjust
4500 reference count data strucutres accordingly. */
4502 void
4503 ipa_edge_args_sum_t::duplicate (cgraph_edge *src, cgraph_edge *dst,
4504 ipa_edge_args *old_args, ipa_edge_args *new_args)
4506 unsigned int i;
4508 new_args->jump_functions = vec_safe_copy (old_args->jump_functions);
4509 if (old_args->polymorphic_call_contexts)
4510 new_args->polymorphic_call_contexts
4511 = vec_safe_copy (old_args->polymorphic_call_contexts);
4513 for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
4515 struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
4516 struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
4518 dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
4520 if (src_jf->type == IPA_JF_CONST)
4522 struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
4524 if (!src_rdesc)
4525 dst_jf->value.constant.rdesc = NULL;
4526 else if (src->caller == dst->caller)
4528 /* Creation of a speculative edge. If the source edge is the one
4529 grabbing a reference, we must create a new (duplicate)
4530 reference description. Otherwise they refer to the same
4531 description corresponding to a reference taken in a function
4532 src->caller is inlined to. In that case we just must
4533 increment the refcount. */
4534 if (src_rdesc->cs == src)
4536 symtab_node *n = symtab_node_for_jfunc (src_jf);
4537 gcc_checking_assert (n);
4538 ipa_ref *ref
4539 = src->caller->find_reference (n, src->call_stmt,
4540 src->lto_stmt_uid,
4541 IPA_REF_ADDR);
4542 gcc_checking_assert (ref);
4543 dst->caller->clone_reference (ref, ref->stmt);
4545 ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4546 dst_rdesc->cs = dst;
4547 dst_rdesc->refcount = src_rdesc->refcount;
4548 dst_rdesc->next_duplicate = NULL;
4549 dst_jf->value.constant.rdesc = dst_rdesc;
4551 else
4553 src_rdesc->refcount++;
4554 dst_jf->value.constant.rdesc = src_rdesc;
4557 else if (src_rdesc->cs == src)
4559 struct ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
4560 dst_rdesc->cs = dst;
4561 dst_rdesc->refcount = src_rdesc->refcount;
4562 dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
4563 src_rdesc->next_duplicate = dst_rdesc;
4564 dst_jf->value.constant.rdesc = dst_rdesc;
4566 else
4568 struct ipa_cst_ref_desc *dst_rdesc;
4569 /* This can happen during inlining, when a JFUNC can refer to a
4570 reference taken in a function up in the tree of inline clones.
4571 We need to find the duplicate that refers to our tree of
4572 inline clones. */
4574 gcc_assert (dst->caller->inlined_to);
4575 for (dst_rdesc = src_rdesc->next_duplicate;
4576 dst_rdesc;
4577 dst_rdesc = dst_rdesc->next_duplicate)
4579 struct cgraph_node *top;
4580 top = dst_rdesc->cs->caller->inlined_to
4581 ? dst_rdesc->cs->caller->inlined_to
4582 : dst_rdesc->cs->caller;
4583 if (dst->caller->inlined_to == top)
4584 break;
4586 gcc_assert (dst_rdesc);
4587 dst_jf->value.constant.rdesc = dst_rdesc;
4590 else if (dst_jf->type == IPA_JF_PASS_THROUGH
4591 && src->caller == dst->caller)
4593 struct cgraph_node *inline_root = dst->caller->inlined_to
4594 ? dst->caller->inlined_to : dst->caller;
4595 ipa_node_params *root_info = ipa_node_params_sum->get (inline_root);
4596 int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
4598 int c = ipa_get_controlled_uses (root_info, idx);
4599 if (c != IPA_UNDESCRIBED_USE)
4601 c++;
4602 ipa_set_controlled_uses (root_info, idx, c);
4608 /* Analyze newly added function into callgraph. */
4610 static void
4611 ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
4613 if (node->has_gimple_body_p ())
4614 ipa_analyze_node (node);
4617 /* Hook that is called by summary when a node is duplicated. */
4619 void
4620 ipa_node_params_t::duplicate(cgraph_node *, cgraph_node *,
4621 ipa_node_params *old_info,
4622 ipa_node_params *new_info)
4624 new_info->descriptors = vec_safe_copy (old_info->descriptors);
4625 gcc_assert (new_info->lattices.is_empty ());
4626 new_info->ipcp_orig_node = old_info->ipcp_orig_node;
4627 new_info->known_csts = old_info->known_csts.copy ();
4628 new_info->known_contexts = old_info->known_contexts.copy ();
4630 new_info->analysis_done = old_info->analysis_done;
4631 new_info->node_enqueued = old_info->node_enqueued;
4632 new_info->versionable = old_info->versionable;
4635 /* Duplication of ipcp transformation summaries. */
4637 void
4638 ipcp_transformation_t::duplicate(cgraph_node *, cgraph_node *dst,
4639 ipcp_transformation *src_trans,
4640 ipcp_transformation *dst_trans)
4642 /* Avoid redundant work of duplicating vectors we will never use. */
4643 if (dst->inlined_to)
4644 return;
4645 dst_trans->m_agg_values = vec_safe_copy (src_trans->m_agg_values);
4646 dst_trans->m_vr = vec_safe_copy (src_trans->m_vr);
4649 /* Register our cgraph hooks if they are not already there. */
4651 void
4652 ipa_register_cgraph_hooks (void)
4654 ipa_check_create_node_params ();
4655 ipa_check_create_edge_args ();
4657 function_insertion_hook_holder =
4658 symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
4661 /* Unregister our cgraph hooks if they are not already there. */
4663 static void
4664 ipa_unregister_cgraph_hooks (void)
4666 if (function_insertion_hook_holder)
4667 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
4668 function_insertion_hook_holder = NULL;
4671 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4672 longer needed after ipa-cp. */
4674 void
4675 ipa_free_all_structures_after_ipa_cp (void)
4677 if (!optimize && !in_lto_p)
4679 ipa_free_all_edge_args ();
4680 ipa_free_all_node_params ();
4681 ipcp_sources_pool.release ();
4682 ipcp_cst_values_pool.release ();
4683 ipcp_poly_ctx_values_pool.release ();
4684 ipcp_agg_lattice_pool.release ();
4685 ipa_unregister_cgraph_hooks ();
4686 ipa_refdesc_pool.release ();
4690 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
4691 longer needed after indirect inlining. */
4693 void
4694 ipa_free_all_structures_after_iinln (void)
4696 ipa_free_all_edge_args ();
4697 ipa_free_all_node_params ();
4698 ipa_unregister_cgraph_hooks ();
4699 ipcp_sources_pool.release ();
4700 ipcp_cst_values_pool.release ();
4701 ipcp_poly_ctx_values_pool.release ();
4702 ipcp_agg_lattice_pool.release ();
4703 ipa_refdesc_pool.release ();
4706 /* Print ipa_tree_map data structures of all functions in the
4707 callgraph to F. */
4709 void
4710 ipa_print_node_params (FILE *f, struct cgraph_node *node)
4712 int i, count;
4713 class ipa_node_params *info;
4715 if (!node->definition)
4716 return;
4717 info = ipa_node_params_sum->get (node);
4718 fprintf (f, " function %s parameter descriptors:\n", node->dump_name ());
4719 if (!info)
4721 fprintf (f, " no params return\n");
4722 return;
4724 count = ipa_get_param_count (info);
4725 for (i = 0; i < count; i++)
4727 int c;
4729 fprintf (f, " ");
4730 ipa_dump_param (f, info, i);
4731 if (ipa_is_param_used (info, i))
4732 fprintf (f, " used");
4733 if (ipa_is_param_used_by_ipa_predicates (info, i))
4734 fprintf (f, " used_by_ipa_predicates");
4735 if (ipa_is_param_used_by_indirect_call (info, i))
4736 fprintf (f, " used_by_indirect_call");
4737 if (ipa_is_param_used_by_polymorphic_call (info, i))
4738 fprintf (f, " used_by_polymorphic_call");
4739 c = ipa_get_controlled_uses (info, i);
4740 if (c == IPA_UNDESCRIBED_USE)
4741 fprintf (f, " undescribed_use");
4742 else
4743 fprintf (f, " controlled_uses=%i %s", c,
4744 ipa_get_param_load_dereferenced (info, i)
4745 ? "(load_dereferenced)" : "");
4746 fprintf (f, "\n");
4750 /* Print ipa_tree_map data structures of all functions in the
4751 callgraph to F. */
4753 void
4754 ipa_print_all_params (FILE * f)
4756 struct cgraph_node *node;
4758 fprintf (f, "\nFunction parameters:\n");
4759 FOR_EACH_FUNCTION (node)
4760 ipa_print_node_params (f, node);
4763 /* Stream out jump function JUMP_FUNC to OB. */
4765 static void
4766 ipa_write_jump_function (struct output_block *ob,
4767 struct ipa_jump_func *jump_func)
4769 struct ipa_agg_jf_item *item;
4770 struct bitpack_d bp;
4771 int i, count;
4772 int flag = 0;
4774 /* ADDR_EXPRs are very comon IP invariants; save some streamer data
4775 as well as WPA memory by handling them specially. */
4776 if (jump_func->type == IPA_JF_CONST
4777 && TREE_CODE (jump_func->value.constant.value) == ADDR_EXPR)
4778 flag = 1;
4780 streamer_write_uhwi (ob, jump_func->type * 2 + flag);
4781 switch (jump_func->type)
4783 case IPA_JF_UNKNOWN:
4784 break;
4785 case IPA_JF_CONST:
4786 gcc_assert (
4787 EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
4788 stream_write_tree (ob,
4789 flag
4790 ? TREE_OPERAND (jump_func->value.constant.value, 0)
4791 : jump_func->value.constant.value, true);
4792 break;
4793 case IPA_JF_PASS_THROUGH:
4794 streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
4795 if (jump_func->value.pass_through.operation == NOP_EXPR)
4797 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4798 bp = bitpack_create (ob->main_stream);
4799 bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
4800 gcc_assert (!jump_func->value.pass_through.refdesc_decremented);
4801 streamer_write_bitpack (&bp);
4803 else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation)
4804 == tcc_unary)
4805 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4806 else
4808 stream_write_tree (ob, jump_func->value.pass_through.operand, true);
4809 streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
4811 break;
4812 case IPA_JF_ANCESTOR:
4813 streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
4814 streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
4815 bp = bitpack_create (ob->main_stream);
4816 bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
4817 bp_pack_value (&bp, jump_func->value.ancestor.keep_null, 1);
4818 streamer_write_bitpack (&bp);
4819 break;
4820 default:
4821 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4824 count = vec_safe_length (jump_func->agg.items);
4825 streamer_write_uhwi (ob, count);
4826 if (count)
4828 bp = bitpack_create (ob->main_stream);
4829 bp_pack_value (&bp, jump_func->agg.by_ref, 1);
4830 streamer_write_bitpack (&bp);
4833 FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, i, item)
4835 stream_write_tree (ob, item->type, true);
4836 streamer_write_uhwi (ob, item->offset);
4837 streamer_write_uhwi (ob, item->jftype);
4838 switch (item->jftype)
4840 case IPA_JF_UNKNOWN:
4841 break;
4842 case IPA_JF_CONST:
4843 stream_write_tree (ob, item->value.constant, true);
4844 break;
4845 case IPA_JF_PASS_THROUGH:
4846 case IPA_JF_LOAD_AGG:
4847 streamer_write_uhwi (ob, item->value.pass_through.operation);
4848 streamer_write_uhwi (ob, item->value.pass_through.formal_id);
4849 if (TREE_CODE_CLASS (item->value.pass_through.operation)
4850 != tcc_unary)
4851 stream_write_tree (ob, item->value.pass_through.operand, true);
4852 if (item->jftype == IPA_JF_LOAD_AGG)
4854 stream_write_tree (ob, item->value.load_agg.type, true);
4855 streamer_write_uhwi (ob, item->value.load_agg.offset);
4856 bp = bitpack_create (ob->main_stream);
4857 bp_pack_value (&bp, item->value.load_agg.by_ref, 1);
4858 streamer_write_bitpack (&bp);
4860 break;
4861 default:
4862 fatal_error (UNKNOWN_LOCATION,
4863 "invalid jump function in LTO stream");
4867 bp = bitpack_create (ob->main_stream);
4868 if (jump_func->m_vr)
4869 jump_func->m_vr->streamer_write (ob);
4870 else
4872 bp_pack_value (&bp, false, 1);
4873 streamer_write_bitpack (&bp);
4877 /* Read in jump function JUMP_FUNC from IB. */
4879 static void
4880 ipa_read_jump_function (class lto_input_block *ib,
4881 struct ipa_jump_func *jump_func,
4882 struct cgraph_edge *cs,
4883 class data_in *data_in,
4884 bool prevails)
4886 enum jump_func_type jftype;
4887 enum tree_code operation;
4888 int i, count;
4889 int val = streamer_read_uhwi (ib);
4890 bool flag = val & 1;
4892 jftype = (enum jump_func_type) (val / 2);
4893 switch (jftype)
4895 case IPA_JF_UNKNOWN:
4896 ipa_set_jf_unknown (jump_func);
4897 break;
4898 case IPA_JF_CONST:
4900 tree t = stream_read_tree (ib, data_in);
4901 if (flag && prevails)
4902 t = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
4903 ipa_set_jf_constant (jump_func, t, cs);
4905 break;
4906 case IPA_JF_PASS_THROUGH:
4907 operation = (enum tree_code) streamer_read_uhwi (ib);
4908 if (operation == NOP_EXPR)
4910 int formal_id = streamer_read_uhwi (ib);
4911 struct bitpack_d bp = streamer_read_bitpack (ib);
4912 bool agg_preserved = bp_unpack_value (&bp, 1);
4913 ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
4915 else if (TREE_CODE_CLASS (operation) == tcc_unary)
4917 int formal_id = streamer_read_uhwi (ib);
4918 ipa_set_jf_unary_pass_through (jump_func, formal_id, operation);
4920 else
4922 tree operand = stream_read_tree (ib, data_in);
4923 int formal_id = streamer_read_uhwi (ib);
4924 ipa_set_jf_arith_pass_through (jump_func, formal_id, operand,
4925 operation);
4927 break;
4928 case IPA_JF_ANCESTOR:
4930 HOST_WIDE_INT offset = streamer_read_uhwi (ib);
4931 int formal_id = streamer_read_uhwi (ib);
4932 struct bitpack_d bp = streamer_read_bitpack (ib);
4933 bool agg_preserved = bp_unpack_value (&bp, 1);
4934 bool keep_null = bp_unpack_value (&bp, 1);
4935 ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved,
4936 keep_null);
4937 break;
4939 default:
4940 fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
4943 count = streamer_read_uhwi (ib);
4944 if (prevails)
4946 jump_func->agg.items = NULL;
4947 vec_safe_reserve (jump_func->agg.items, count, true);
4949 if (count)
4951 struct bitpack_d bp = streamer_read_bitpack (ib);
4952 jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
4954 for (i = 0; i < count; i++)
4956 struct ipa_agg_jf_item item;
4957 item.type = stream_read_tree (ib, data_in);
4958 item.offset = streamer_read_uhwi (ib);
4959 item.jftype = (enum jump_func_type) streamer_read_uhwi (ib);
4961 switch (item.jftype)
4963 case IPA_JF_UNKNOWN:
4964 break;
4965 case IPA_JF_CONST:
4966 item.value.constant = stream_read_tree (ib, data_in);
4967 break;
4968 case IPA_JF_PASS_THROUGH:
4969 case IPA_JF_LOAD_AGG:
4970 operation = (enum tree_code) streamer_read_uhwi (ib);
4971 item.value.pass_through.operation = operation;
4972 item.value.pass_through.formal_id = streamer_read_uhwi (ib);
4973 if (TREE_CODE_CLASS (operation) == tcc_unary)
4974 item.value.pass_through.operand = NULL_TREE;
4975 else
4976 item.value.pass_through.operand = stream_read_tree (ib, data_in);
4977 if (item.jftype == IPA_JF_LOAD_AGG)
4979 struct bitpack_d bp;
4980 item.value.load_agg.type = stream_read_tree (ib, data_in);
4981 item.value.load_agg.offset = streamer_read_uhwi (ib);
4982 bp = streamer_read_bitpack (ib);
4983 item.value.load_agg.by_ref = bp_unpack_value (&bp, 1);
4985 break;
4986 default:
4987 fatal_error (UNKNOWN_LOCATION,
4988 "invalid jump function in LTO stream");
4990 if (prevails)
4991 jump_func->agg.items->quick_push (item);
4994 ipa_vr vr;
4995 vr.streamer_read (ib, data_in);
4996 if (vr.known_p ())
4998 if (prevails)
4999 ipa_set_jfunc_vr (jump_func, vr);
5001 else
5002 jump_func->m_vr = NULL;
5005 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
5006 relevant to indirect inlining to OB. */
5008 static void
5009 ipa_write_indirect_edge_info (struct output_block *ob,
5010 struct cgraph_edge *cs)
5012 class cgraph_indirect_call_info *ii = cs->indirect_info;
5013 struct bitpack_d bp;
5015 streamer_write_hwi (ob, ii->param_index);
5016 bp = bitpack_create (ob->main_stream);
5017 bp_pack_value (&bp, ii->polymorphic, 1);
5018 bp_pack_value (&bp, ii->agg_contents, 1);
5019 bp_pack_value (&bp, ii->member_ptr, 1);
5020 bp_pack_value (&bp, ii->by_ref, 1);
5021 bp_pack_value (&bp, ii->guaranteed_unmodified, 1);
5022 bp_pack_value (&bp, ii->vptr_changed, 1);
5023 streamer_write_bitpack (&bp);
5024 if (ii->agg_contents || ii->polymorphic)
5025 streamer_write_hwi (ob, ii->offset);
5026 else
5027 gcc_assert (ii->offset == 0);
5029 if (ii->polymorphic)
5031 streamer_write_hwi (ob, ii->otr_token);
5032 stream_write_tree (ob, ii->otr_type, true);
5033 ii->context.stream_out (ob);
5037 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
5038 relevant to indirect inlining from IB. */
5040 static void
5041 ipa_read_indirect_edge_info (class lto_input_block *ib,
5042 class data_in *data_in,
5043 struct cgraph_edge *cs,
5044 class ipa_node_params *info)
5046 class cgraph_indirect_call_info *ii = cs->indirect_info;
5047 struct bitpack_d bp;
5049 ii->param_index = (int) streamer_read_hwi (ib);
5050 bp = streamer_read_bitpack (ib);
5051 ii->polymorphic = bp_unpack_value (&bp, 1);
5052 ii->agg_contents = bp_unpack_value (&bp, 1);
5053 ii->member_ptr = bp_unpack_value (&bp, 1);
5054 ii->by_ref = bp_unpack_value (&bp, 1);
5055 ii->guaranteed_unmodified = bp_unpack_value (&bp, 1);
5056 ii->vptr_changed = bp_unpack_value (&bp, 1);
5057 if (ii->agg_contents || ii->polymorphic)
5058 ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
5059 else
5060 ii->offset = 0;
5061 if (ii->polymorphic)
5063 ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
5064 ii->otr_type = stream_read_tree (ib, data_in);
5065 ii->context.stream_in (ib, data_in);
5067 if (info && ii->param_index >= 0)
5069 if (ii->polymorphic)
5070 ipa_set_param_used_by_polymorphic_call (info,
5071 ii->param_index , true);
5072 ipa_set_param_used_by_indirect_call (info,
5073 ii->param_index, true);
5077 /* Stream out NODE info to OB. */
5079 static void
5080 ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
5082 int node_ref;
5083 lto_symtab_encoder_t encoder;
5084 ipa_node_params *info = ipa_node_params_sum->get (node);
5085 int j;
5086 struct cgraph_edge *e;
5087 struct bitpack_d bp;
5089 encoder = ob->decl_state->symtab_node_encoder;
5090 node_ref = lto_symtab_encoder_encode (encoder, node);
5091 streamer_write_uhwi (ob, node_ref);
5093 streamer_write_uhwi (ob, ipa_get_param_count (info));
5094 for (j = 0; j < ipa_get_param_count (info); j++)
5095 streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
5096 bp = bitpack_create (ob->main_stream);
5097 gcc_assert (info->analysis_done
5098 || ipa_get_param_count (info) == 0);
5099 gcc_assert (!info->node_enqueued);
5100 gcc_assert (!info->ipcp_orig_node);
5101 for (j = 0; j < ipa_get_param_count (info); j++)
5103 /* TODO: We could just not stream the bit in the undescribed case. */
5104 bool d = (ipa_get_controlled_uses (info, j) != IPA_UNDESCRIBED_USE)
5105 ? ipa_get_param_load_dereferenced (info, j) : true;
5106 bp_pack_value (&bp, d, 1);
5107 bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
5109 streamer_write_bitpack (&bp);
5110 for (j = 0; j < ipa_get_param_count (info); j++)
5112 streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
5113 stream_write_tree (ob, ipa_get_type (info, j), true);
5115 for (e = node->callees; e; e = e->next_callee)
5117 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5119 if (!args)
5121 streamer_write_uhwi (ob, 0);
5122 continue;
5125 streamer_write_uhwi (ob,
5126 ipa_get_cs_argument_count (args) * 2
5127 + (args->polymorphic_call_contexts != NULL));
5128 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5130 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5131 if (args->polymorphic_call_contexts != NULL)
5132 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5135 for (e = node->indirect_calls; e; e = e->next_callee)
5137 ipa_edge_args *args = ipa_edge_args_sum->get (e);
5138 if (!args)
5139 streamer_write_uhwi (ob, 0);
5140 else
5142 streamer_write_uhwi (ob,
5143 ipa_get_cs_argument_count (args) * 2
5144 + (args->polymorphic_call_contexts != NULL));
5145 for (j = 0; j < ipa_get_cs_argument_count (args); j++)
5147 ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
5148 if (args->polymorphic_call_contexts != NULL)
5149 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
5152 ipa_write_indirect_edge_info (ob, e);
5156 /* Stream in edge E from IB. */
5158 static void
5159 ipa_read_edge_info (class lto_input_block *ib,
5160 class data_in *data_in,
5161 struct cgraph_edge *e, bool prevails)
5163 int count = streamer_read_uhwi (ib);
5164 bool contexts_computed = count & 1;
5166 count /= 2;
5167 if (!count)
5168 return;
5169 if (prevails
5170 && (e->possibly_call_in_translation_unit_p ()
5171 /* Also stream in jump functions to builtins in hope that they
5172 will get fnspecs. */
5173 || fndecl_built_in_p (e->callee->decl, BUILT_IN_NORMAL)))
5175 ipa_edge_args *args = ipa_edge_args_sum->get_create (e);
5176 vec_safe_grow_cleared (args->jump_functions, count, true);
5177 if (contexts_computed)
5178 vec_safe_grow_cleared (args->polymorphic_call_contexts, count, true);
5179 for (int k = 0; k < count; k++)
5181 ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
5182 data_in, prevails);
5183 if (contexts_computed)
5184 ipa_get_ith_polymorhic_call_context (args, k)->stream_in
5185 (ib, data_in);
5188 else
5190 for (int k = 0; k < count; k++)
5192 struct ipa_jump_func dummy;
5193 ipa_read_jump_function (ib, &dummy, e,
5194 data_in, prevails);
5195 if (contexts_computed)
5197 class ipa_polymorphic_call_context ctx;
5198 ctx.stream_in (ib, data_in);
5204 /* Stream in NODE info from IB. */
5206 static void
5207 ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node,
5208 class data_in *data_in)
5210 int k;
5211 struct cgraph_edge *e;
5212 struct bitpack_d bp;
5213 bool prevails = node->prevailing_p ();
5214 ipa_node_params *info
5215 = prevails ? ipa_node_params_sum->get_create (node) : NULL;
5217 int param_count = streamer_read_uhwi (ib);
5218 if (prevails)
5220 ipa_alloc_node_params (node, param_count);
5221 for (k = 0; k < param_count; k++)
5222 (*info->descriptors)[k].move_cost = streamer_read_uhwi (ib);
5223 if (ipa_get_param_count (info) != 0)
5224 info->analysis_done = true;
5225 info->node_enqueued = false;
5227 else
5228 for (k = 0; k < param_count; k++)
5229 streamer_read_uhwi (ib);
5231 bp = streamer_read_bitpack (ib);
5232 for (k = 0; k < param_count; k++)
5234 bool load_dereferenced = bp_unpack_value (&bp, 1);
5235 bool used = bp_unpack_value (&bp, 1);
5237 if (prevails)
5239 ipa_set_param_load_dereferenced (info, k, load_dereferenced);
5240 ipa_set_param_used (info, k, used);
5243 for (k = 0; k < param_count; k++)
5245 int nuses = streamer_read_hwi (ib);
5246 tree type = stream_read_tree (ib, data_in);
5248 if (prevails)
5250 ipa_set_controlled_uses (info, k, nuses);
5251 (*info->descriptors)[k].decl_or_type = type;
5254 for (e = node->callees; e; e = e->next_callee)
5255 ipa_read_edge_info (ib, data_in, e, prevails);
5256 for (e = node->indirect_calls; e; e = e->next_callee)
5258 ipa_read_edge_info (ib, data_in, e, prevails);
5259 ipa_read_indirect_edge_info (ib, data_in, e, info);
5263 /* Write jump functions for nodes in SET. */
5265 void
5266 ipa_prop_write_jump_functions (void)
5268 struct output_block *ob;
5269 unsigned int count = 0;
5270 lto_symtab_encoder_iterator lsei;
5271 lto_symtab_encoder_t encoder;
5273 if (!ipa_node_params_sum || !ipa_edge_args_sum)
5274 return;
5276 ob = create_output_block (LTO_section_jump_functions);
5277 encoder = ob->decl_state->symtab_node_encoder;
5278 ob->symbol = NULL;
5279 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5280 lsei_next_function_in_partition (&lsei))
5282 cgraph_node *node = lsei_cgraph_node (lsei);
5283 if (node->has_gimple_body_p ()
5284 && ipa_node_params_sum->get (node) != NULL)
5285 count++;
5288 streamer_write_uhwi (ob, count);
5290 /* Process all of the functions. */
5291 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
5292 lsei_next_function_in_partition (&lsei))
5294 cgraph_node *node = lsei_cgraph_node (lsei);
5295 if (node->has_gimple_body_p ()
5296 && ipa_node_params_sum->get (node) != NULL)
5297 ipa_write_node_info (ob, node);
5299 streamer_write_char_stream (ob->main_stream, 0);
5300 produce_asm (ob, NULL);
5301 destroy_output_block (ob);
5304 /* Read section in file FILE_DATA of length LEN with data DATA. */
5306 static void
5307 ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
5308 size_t len)
5310 const struct lto_function_header *header =
5311 (const struct lto_function_header *) data;
5312 const int cfg_offset = sizeof (struct lto_function_header);
5313 const int main_offset = cfg_offset + header->cfg_size;
5314 const int string_offset = main_offset + header->main_size;
5315 class data_in *data_in;
5316 unsigned int i;
5317 unsigned int count;
5319 lto_input_block ib_main ((const char *) data + main_offset,
5320 header->main_size, file_data);
5322 data_in =
5323 lto_data_in_create (file_data, (const char *) data + string_offset,
5324 header->string_size, vNULL);
5325 count = streamer_read_uhwi (&ib_main);
5327 for (i = 0; i < count; i++)
5329 unsigned int index;
5330 struct cgraph_node *node;
5331 lto_symtab_encoder_t encoder;
5333 index = streamer_read_uhwi (&ib_main);
5334 encoder = file_data->symtab_node_encoder;
5335 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5336 index));
5337 gcc_assert (node->definition);
5338 ipa_read_node_info (&ib_main, node, data_in);
5340 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5341 len);
5342 lto_data_in_delete (data_in);
5345 /* Read ipcp jump functions. */
5347 void
5348 ipa_prop_read_jump_functions (void)
5350 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5351 struct lto_file_decl_data *file_data;
5352 unsigned int j = 0;
5354 ipa_check_create_node_params ();
5355 ipa_check_create_edge_args ();
5356 ipa_register_cgraph_hooks ();
5358 while ((file_data = file_data_vec[j++]))
5360 size_t len;
5361 const char *data
5362 = lto_get_summary_section_data (file_data, LTO_section_jump_functions,
5363 &len);
5364 if (data)
5365 ipa_prop_read_section (file_data, data, len);
5369 /* Return true if the IPA-CP transformation summary TS is non-NULL and contains
5370 useful info. */
5371 static bool
5372 useful_ipcp_transformation_info_p (ipcp_transformation *ts)
5374 if (!ts)
5375 return false;
5376 if (!vec_safe_is_empty (ts->m_agg_values)
5377 || !vec_safe_is_empty (ts->m_vr))
5378 return true;
5379 return false;
5382 /* Write into OB IPA-CP transfromation summary TS describing NODE. */
5384 void
5385 write_ipcp_transformation_info (output_block *ob, cgraph_node *node,
5386 ipcp_transformation *ts)
5388 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
5389 int node_ref = lto_symtab_encoder_encode (encoder, node);
5390 streamer_write_uhwi (ob, node_ref);
5392 streamer_write_uhwi (ob, vec_safe_length (ts->m_agg_values));
5393 for (const ipa_argagg_value &av : ts->m_agg_values)
5395 struct bitpack_d bp;
5397 stream_write_tree (ob, av.value, true);
5398 streamer_write_uhwi (ob, av.unit_offset);
5399 streamer_write_uhwi (ob, av.index);
5401 bp = bitpack_create (ob->main_stream);
5402 bp_pack_value (&bp, av.by_ref, 1);
5403 bp_pack_value (&bp, av.killed, 1);
5404 streamer_write_bitpack (&bp);
5407 streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
5408 for (const ipa_vr &parm_vr : ts->m_vr)
5409 parm_vr.streamer_write (ob);
5412 /* Stream in the aggregate value replacement chain for NODE from IB. */
5414 static void
5415 read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
5416 data_in *data_in)
5418 unsigned int count, i;
5419 ipcp_transformation_initialize ();
5420 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5422 count = streamer_read_uhwi (ib);
5423 if (count > 0)
5425 vec_safe_grow_cleared (ts->m_agg_values, count, true);
5426 for (i = 0; i <count; i++)
5428 ipa_argagg_value *av = &(*ts->m_agg_values)[i];;
5430 av->value = stream_read_tree (ib, data_in);
5431 av->unit_offset = streamer_read_uhwi (ib);
5432 av->index = streamer_read_uhwi (ib);
5434 bitpack_d bp = streamer_read_bitpack (ib);
5435 av->by_ref = bp_unpack_value (&bp, 1);
5436 av->killed = bp_unpack_value (&bp, 1);
5440 count = streamer_read_uhwi (ib);
5441 if (count > 0)
5443 vec_safe_grow_cleared (ts->m_vr, count, true);
5444 for (i = 0; i < count; i++)
5446 ipa_vr *parm_vr;
5447 parm_vr = &(*ts->m_vr)[i];
5448 parm_vr->streamer_read (ib, data_in);
5453 /* Write all aggregate replacement for nodes in set. */
5455 void
5456 ipcp_write_transformation_summaries (void)
5458 struct output_block *ob;
5459 unsigned int count = 0;
5460 lto_symtab_encoder_t encoder;
5462 ob = create_output_block (LTO_section_ipcp_transform);
5463 encoder = ob->decl_state->symtab_node_encoder;
5464 ob->symbol = NULL;
5466 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5468 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5469 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5470 if (!cnode)
5471 continue;
5472 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5473 if (useful_ipcp_transformation_info_p (ts)
5474 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5475 count++;
5478 streamer_write_uhwi (ob, count);
5480 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
5482 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
5483 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
5484 if (!cnode)
5485 continue;
5486 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5487 if (useful_ipcp_transformation_info_p (ts)
5488 && lto_symtab_encoder_encode_body_p (encoder, cnode))
5489 write_ipcp_transformation_info (ob, cnode, ts);
5491 streamer_write_char_stream (ob->main_stream, 0);
5492 produce_asm (ob, NULL);
5493 destroy_output_block (ob);
5496 /* Read replacements section in file FILE_DATA of length LEN with data
5497 DATA. */
5499 static void
5500 read_replacements_section (struct lto_file_decl_data *file_data,
5501 const char *data,
5502 size_t len)
5504 const struct lto_function_header *header =
5505 (const struct lto_function_header *) data;
5506 const int cfg_offset = sizeof (struct lto_function_header);
5507 const int main_offset = cfg_offset + header->cfg_size;
5508 const int string_offset = main_offset + header->main_size;
5509 class data_in *data_in;
5510 unsigned int i;
5511 unsigned int count;
5513 lto_input_block ib_main ((const char *) data + main_offset,
5514 header->main_size, file_data);
5516 data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
5517 header->string_size, vNULL);
5518 count = streamer_read_uhwi (&ib_main);
5520 for (i = 0; i < count; i++)
5522 unsigned int index;
5523 struct cgraph_node *node;
5524 lto_symtab_encoder_t encoder;
5526 index = streamer_read_uhwi (&ib_main);
5527 encoder = file_data->symtab_node_encoder;
5528 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
5529 index));
5530 read_ipcp_transformation_info (&ib_main, node, data_in);
5532 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
5533 len);
5534 lto_data_in_delete (data_in);
5537 /* Read IPA-CP aggregate replacements. */
5539 void
5540 ipcp_read_transformation_summaries (void)
5542 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
5543 struct lto_file_decl_data *file_data;
5544 unsigned int j = 0;
5546 while ((file_data = file_data_vec[j++]))
5548 size_t len;
5549 const char *data
5550 = lto_get_summary_section_data (file_data, LTO_section_ipcp_transform,
5551 &len);
5552 if (data)
5553 read_replacements_section (file_data, data, len);
5557 /* Adjust the aggregate replacements in TS to reflect any parameter removals
5558 which might have already taken place. If after adjustments there are no
5559 aggregate replacements left, the m_agg_values will be set to NULL. In other
5560 cases, it may be shrunk. */
5562 static void
5563 adjust_agg_replacement_values (cgraph_node *node, ipcp_transformation *ts)
5565 clone_info *cinfo = clone_info::get (node);
5566 if (!cinfo || !cinfo->param_adjustments)
5567 return;
5569 auto_vec<int, 16> new_indices;
5570 cinfo->param_adjustments->get_updated_indices (&new_indices);
5571 bool removed_item = false;
5572 unsigned dst_index = 0;
5573 unsigned count = ts->m_agg_values->length ();
5574 for (unsigned i = 0; i < count; i++)
5576 ipa_argagg_value *v = &(*ts->m_agg_values)[i];
5577 gcc_checking_assert (v->index >= 0);
5579 int new_idx = -1;
5580 if ((unsigned) v->index < new_indices.length ())
5581 new_idx = new_indices[v->index];
5583 if (new_idx >= 0)
5585 v->index = new_idx;
5586 if (removed_item)
5587 (*ts->m_agg_values)[dst_index] = *v;
5588 dst_index++;
5590 else
5591 removed_item = true;
5594 if (dst_index == 0)
5596 ggc_free (ts->m_agg_values);
5597 ts->m_agg_values = NULL;
5599 else if (removed_item)
5600 ts->m_agg_values->truncate (dst_index);
5602 return;
5605 /* Dominator walker driving the ipcp modification phase. */
5607 class ipcp_modif_dom_walker : public dom_walker
5609 public:
5610 ipcp_modif_dom_walker (struct ipa_func_body_info *fbi,
5611 vec<ipa_param_descriptor, va_gc> *descs,
5612 ipcp_transformation *ts, bool *sc)
5613 : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
5614 m_ts (ts), m_something_changed (sc) {}
5616 edge before_dom_children (basic_block) final override;
5617 bool cleanup_eh ()
5618 { return gimple_purge_all_dead_eh_edges (m_need_eh_cleanup); }
5620 private:
5621 struct ipa_func_body_info *m_fbi;
5622 vec<ipa_param_descriptor, va_gc> *m_descriptors;
5623 ipcp_transformation *m_ts;
5624 bool *m_something_changed;
5625 auto_bitmap m_need_eh_cleanup;
5628 edge
5629 ipcp_modif_dom_walker::before_dom_children (basic_block bb)
5631 gimple_stmt_iterator gsi;
5632 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5634 gimple *stmt = gsi_stmt (gsi);
5635 tree rhs, val, t;
5636 HOST_WIDE_INT bit_offset;
5637 poly_int64 size;
5638 int index;
5639 bool by_ref, vce;
5641 if (!gimple_assign_load_p (stmt))
5642 continue;
5643 rhs = gimple_assign_rhs1 (stmt);
5644 if (!is_gimple_reg_type (TREE_TYPE (rhs)))
5645 continue;
5647 vce = false;
5648 t = rhs;
5649 while (handled_component_p (t))
5651 /* V_C_E can do things like convert an array of integers to one
5652 bigger integer and similar things we do not handle below. */
5653 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
5655 vce = true;
5656 break;
5658 t = TREE_OPERAND (t, 0);
5660 if (vce)
5661 continue;
5663 if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index,
5664 &bit_offset, &size, &by_ref))
5665 continue;
5666 unsigned unit_offset = bit_offset / BITS_PER_UNIT;
5667 ipa_argagg_value_list avl (m_ts);
5668 tree v = avl.get_value (index, unit_offset, by_ref);
5670 if (!v
5671 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), size))
5672 continue;
5674 gcc_checking_assert (is_gimple_ip_invariant (v));
5675 if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v)))
5677 if (fold_convertible_p (TREE_TYPE (rhs), v))
5678 val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v);
5679 else if (TYPE_SIZE (TREE_TYPE (rhs))
5680 == TYPE_SIZE (TREE_TYPE (v)))
5681 val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v);
5682 else
5684 if (dump_file)
5686 fprintf (dump_file, " const ");
5687 print_generic_expr (dump_file, v);
5688 fprintf (dump_file, " can't be converted to type of ");
5689 print_generic_expr (dump_file, rhs);
5690 fprintf (dump_file, "\n");
5692 continue;
5695 else
5696 val = v;
5698 if (dump_file && (dump_flags & TDF_DETAILS))
5700 fprintf (dump_file, "Modifying stmt:\n ");
5701 print_gimple_stmt (dump_file, stmt, 0);
5703 gimple_assign_set_rhs_from_tree (&gsi, val);
5704 update_stmt (stmt);
5706 if (dump_file && (dump_flags & TDF_DETAILS))
5708 fprintf (dump_file, "into:\n ");
5709 print_gimple_stmt (dump_file, stmt, 0);
5710 fprintf (dump_file, "\n");
5713 *m_something_changed = true;
5714 if (maybe_clean_eh_stmt (stmt))
5715 bitmap_set_bit (m_need_eh_cleanup, bb->index);
5717 return NULL;
5720 /* If IPA-CP discovered a constant in parameter PARM at OFFSET of a given SIZE
5721 - whether passed by reference or not is given by BY_REF - return that
5722 constant. Otherwise return NULL_TREE. The is supposed to be used only
5723 after clone materialization and transformation is done (because it asserts
5724 that killed constants have been pruned). */
5726 tree
5727 ipcp_get_aggregate_const (struct function *func, tree parm, bool by_ref,
5728 HOST_WIDE_INT bit_offset, HOST_WIDE_INT bit_size)
5730 cgraph_node *node = cgraph_node::get (func->decl);
5731 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5733 if (!ts || !ts->m_agg_values)
5734 return NULL_TREE;
5736 int index = ts->get_param_index (func->decl, parm);
5737 if (index < 0)
5738 return NULL_TREE;
5740 ipa_argagg_value_list avl (ts);
5741 unsigned unit_offset = bit_offset / BITS_PER_UNIT;
5742 const ipa_argagg_value *av = avl.get_elt (index, unit_offset);
5743 if (!av || av->by_ref != by_ref)
5744 return NULL_TREE;
5745 gcc_assert (!av->killed);
5746 tree v = av->value;
5747 if (!v
5748 || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), bit_size))
5749 return NULL_TREE;
5751 return v;
5754 /* Return true if we have recorded VALUE and MASK about PARM.
5755 Set VALUE and MASk accordingly. */
5757 bool
5758 ipcp_get_parm_bits (tree parm, tree *value, widest_int *mask)
5760 cgraph_node *cnode = cgraph_node::get (current_function_decl);
5761 ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
5762 if (!ts
5763 || vec_safe_length (ts->m_vr) == 0
5764 || !ipa_supports_p (TREE_TYPE (parm)))
5765 return false;
5767 int i = ts->get_param_index (current_function_decl, parm);
5768 if (i < 0)
5769 return false;
5770 clone_info *cinfo = clone_info::get (cnode);
5771 if (cinfo && cinfo->param_adjustments)
5773 i = cinfo->param_adjustments->get_original_index (i);
5774 if (i < 0)
5775 return false;
5778 vec<ipa_vr, va_gc> &vr = *ts->m_vr;
5779 if (!vr[i].known_p ())
5780 return false;
5781 value_range tmp;
5782 vr[i].get_vrange (tmp);
5783 if (tmp.undefined_p () || tmp.varying_p ())
5784 return false;
5785 irange_bitmask bm;
5786 bm = tmp.get_bitmask ();
5787 *mask = widest_int::from (bm.mask (), TYPE_SIGN (TREE_TYPE (parm)));
5788 *value = wide_int_to_tree (TREE_TYPE (parm), bm.value ());
5789 return true;
5792 /* Update value range of formal parameters of NODE as described in TS. */
5794 static void
5795 ipcp_update_vr (struct cgraph_node *node, ipcp_transformation *ts)
5797 if (vec_safe_is_empty (ts->m_vr))
5798 return;
5799 const vec<ipa_vr, va_gc> &vr = *ts->m_vr;
5800 unsigned count = vr.length ();
5801 if (!count)
5802 return;
5804 auto_vec<int, 16> new_indices;
5805 bool need_remapping = false;
5806 clone_info *cinfo = clone_info::get (node);
5807 if (cinfo && cinfo->param_adjustments)
5809 cinfo->param_adjustments->get_updated_indices (&new_indices);
5810 need_remapping = true;
5812 auto_vec <tree, 16> parm_decls;
5813 push_function_arg_decls (&parm_decls, node->decl);
5815 for (unsigned i = 0; i < count; ++i)
5817 tree parm;
5818 int remapped_idx;
5819 if (need_remapping)
5821 if (i >= new_indices.length ())
5822 continue;
5823 remapped_idx = new_indices[i];
5824 if (remapped_idx < 0)
5825 continue;
5827 else
5828 remapped_idx = i;
5830 parm = parm_decls[remapped_idx];
5832 gcc_checking_assert (parm);
5833 tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
5835 if (!ddef || !is_gimple_reg (parm))
5836 continue;
5838 if (vr[i].known_p ())
5840 value_range tmp;
5841 vr[i].get_vrange (tmp);
5843 if (!tmp.undefined_p () && !tmp.varying_p ())
5845 if (dump_file)
5847 fprintf (dump_file, "Setting value range of param %u "
5848 "(now %i) ", i, remapped_idx);
5849 tmp.dump (dump_file);
5850 fprintf (dump_file, "]\n");
5852 set_range_info (ddef, tmp);
5854 if (POINTER_TYPE_P (TREE_TYPE (parm))
5855 && opt_for_fn (node->decl, flag_ipa_bit_cp))
5857 irange_bitmask bm = tmp.get_bitmask ();
5858 unsigned tem = bm.mask ().to_uhwi ();
5859 unsigned HOST_WIDE_INT bitpos = bm.value ().to_uhwi ();
5860 unsigned align = tem & -tem;
5861 unsigned misalign = bitpos & (align - 1);
5863 if (align > 1)
5865 if (dump_file)
5867 fprintf (dump_file,
5868 "Adjusting mask for param %u to ", i);
5869 print_hex (bm.mask (), dump_file);
5870 fprintf (dump_file, "\n");
5873 if (dump_file)
5874 fprintf (dump_file,
5875 "Adjusting align: %u, misalign: %u\n",
5876 align, misalign);
5878 unsigned old_align, old_misalign;
5879 struct ptr_info_def *pi = get_ptr_info (ddef);
5880 bool old_known = get_ptr_info_alignment (pi, &old_align,
5881 &old_misalign);
5883 if (old_known && old_align > align)
5885 if (dump_file)
5887 fprintf (dump_file,
5888 "But alignment was already %u.\n",
5889 old_align);
5890 if ((old_misalign & (align - 1)) != misalign)
5891 fprintf (dump_file,
5892 "old_misalign (%u) and misalign "
5893 "(%u) mismatch\n",
5894 old_misalign, misalign);
5896 continue;
5899 if (dump_file
5900 && old_known
5901 && ((misalign & (old_align - 1)) != old_misalign))
5902 fprintf (dump_file,
5903 "old_misalign (%u) and misalign (%u) "
5904 "mismatch\n",
5905 old_misalign, misalign);
5907 set_ptr_info_alignment (pi, align, misalign);
5910 else if (dump_file && INTEGRAL_TYPE_P (TREE_TYPE (parm)))
5912 irange &r = as_a<irange> (tmp);
5913 irange_bitmask bm = r.get_bitmask ();
5914 unsigned prec = TYPE_PRECISION (TREE_TYPE (parm));
5915 if (wi::ne_p (bm.mask (), wi::shwi (-1, prec)))
5917 fprintf (dump_file,
5918 "Adjusting mask for param %u to ", i);
5919 print_hex (bm.mask (), dump_file);
5920 fprintf (dump_file, "\n");
5928 /* IPCP transformation phase doing propagation of aggregate values. */
5930 unsigned int
5931 ipcp_transform_function (struct cgraph_node *node)
5933 struct ipa_func_body_info fbi;
5934 int param_count;
5936 gcc_checking_assert (cfun);
5937 gcc_checking_assert (current_function_decl);
5939 if (dump_file)
5940 fprintf (dump_file, "Modification phase of node %s\n",
5941 node->dump_name ());
5943 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5944 if (!ts
5945 || (vec_safe_is_empty (ts->m_agg_values)
5946 && vec_safe_is_empty (ts->m_vr)))
5947 return 0;
5949 ts->maybe_create_parm_idx_map (cfun->decl);
5950 ipcp_update_vr (node, ts);
5951 if (vec_safe_is_empty (ts->m_agg_values))
5952 return 0;
5953 param_count = count_formal_params (node->decl);
5954 if (param_count == 0)
5955 return 0;
5957 adjust_agg_replacement_values (node, ts);
5958 if (vec_safe_is_empty (ts->m_agg_values))
5960 if (dump_file)
5961 fprintf (dump_file, " All affected aggregate parameters were either "
5962 "removed or converted into scalars, phase done.\n");
5963 return 0;
5965 if (dump_file)
5967 fprintf (dump_file, " Aggregate replacements:");
5968 ipa_argagg_value_list avs (ts);
5969 avs.dump (dump_file);
5972 fbi.node = node;
5973 fbi.info = NULL;
5974 fbi.bb_infos = vNULL;
5975 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
5976 fbi.param_count = param_count;
5977 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
5979 vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
5980 vec_safe_grow_cleared (descriptors, param_count, true);
5981 ipa_populate_param_decls (node, *descriptors);
5982 bool modified_mem_access = false;
5983 calculate_dominance_info (CDI_DOMINATORS);
5984 ipcp_modif_dom_walker walker (&fbi, descriptors, ts, &modified_mem_access);
5985 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
5986 free_dominance_info (CDI_DOMINATORS);
5987 bool cfg_changed = walker.cleanup_eh ();
5989 int i;
5990 struct ipa_bb_info *bi;
5991 FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
5992 free_ipa_bb_info (bi);
5993 fbi.bb_infos.release ();
5995 ts->remove_argaggs_if ([](const ipa_argagg_value &v)
5997 return v.killed;
6000 vec_free (descriptors);
6001 if (cfg_changed)
6002 delete_unreachable_blocks_update_callgraph (node, false);
6004 return modified_mem_access ? TODO_update_ssa_only_virtuals : 0;
6007 /* Record that current function return value range is VAL. */
6009 void
6010 ipa_record_return_value_range (value_range val)
6012 cgraph_node *n = cgraph_node::get (current_function_decl);
6013 if (!ipa_return_value_sum)
6015 if (!ipa_vr_hash_table)
6016 ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
6017 ipa_return_value_sum = new (ggc_alloc_no_dtor <ipa_return_value_sum_t> ())
6018 ipa_return_value_sum_t (symtab, true);
6019 ipa_return_value_sum->disable_insertion_hook ();
6021 ipa_return_value_sum->get_create (n)->vr = ipa_get_value_range (val);
6022 if (dump_file && (dump_flags & TDF_DETAILS))
6024 fprintf (dump_file, "Recording return range ");
6025 val.dump (dump_file);
6026 fprintf (dump_file, "\n");
6030 /* Return true if value range of DECL is known and if so initialize RANGE. */
6032 bool
6033 ipa_return_value_range (value_range &range, tree decl)
6035 cgraph_node *n = cgraph_node::get (decl);
6036 if (!n || !ipa_return_value_sum)
6037 return false;
6038 enum availability avail;
6039 n = n->ultimate_alias_target (&avail);
6040 if (avail < AVAIL_AVAILABLE)
6041 return false;
6042 if (n->decl != decl && !useless_type_conversion_p (TREE_TYPE (decl), TREE_TYPE (n->decl)))
6043 return false;
6044 ipa_return_value_summary *v = ipa_return_value_sum->get (n);
6045 if (!v)
6046 return false;
6047 v->vr->get_vrange (range);
6048 return true;
6051 /* Reset all state within ipa-prop.cc so that we can rerun the compiler
6052 within the same process. For use by toplev::finalize. */
6054 void
6055 ipa_prop_cc_finalize (void)
6057 if (function_insertion_hook_holder)
6058 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
6059 function_insertion_hook_holder = NULL;
6061 if (ipa_edge_args_sum)
6062 ggc_delete (ipa_edge_args_sum);
6063 ipa_edge_args_sum = NULL;
6065 if (ipa_node_params_sum)
6066 ggc_delete (ipa_node_params_sum);
6067 ipa_node_params_sum = NULL;
6070 /* Return true if the two pass_through components of two jump functions are
6071 known to be equivalent. AGG_JF denotes whether they are part of aggregate
6072 functions or not. The function can be used before the IPA phase of IPA-CP
6073 or inlining because it cannot cope with refdesc changes these passes can
6074 carry out. */
6076 static bool
6077 ipa_agg_pass_through_jf_equivalent_p (ipa_pass_through_data *ipt1,
6078 ipa_pass_through_data *ipt2,
6079 bool agg_jf)
6082 gcc_assert (agg_jf ||
6083 (!ipt1->refdesc_decremented && !ipt2->refdesc_decremented));
6084 if (ipt1->operation != ipt2->operation
6085 || ipt1->formal_id != ipt2->formal_id
6086 || (!agg_jf && (ipt1->agg_preserved != ipt2->agg_preserved)))
6087 return false;
6088 if (((ipt1->operand != NULL_TREE) != (ipt2->operand != NULL_TREE))
6089 || (ipt1->operand
6090 && !values_equal_for_ipcp_p (ipt1->operand, ipt2->operand)))
6091 return false;
6092 return true;
6095 /* Return true if the two aggregate jump functions are known to be equivalent.
6096 The function can be used before the IPA phase of IPA-CP or inlining because
6097 it cannot cope with refdesc changes these passes can carry out. */
6099 static bool
6100 ipa_agg_jump_functions_equivalent_p (ipa_agg_jf_item *ajf1,
6101 ipa_agg_jf_item *ajf2)
6103 if (ajf1->offset != ajf2->offset
6104 || ajf1->jftype != ajf2->jftype
6105 || !types_compatible_p (ajf1->type, ajf2->type))
6106 return false;
6108 switch (ajf1->jftype)
6110 case IPA_JF_CONST:
6111 if (!values_equal_for_ipcp_p (ajf1->value.constant,
6112 ajf2->value.constant))
6113 return false;
6114 break;
6115 case IPA_JF_PASS_THROUGH:
6117 ipa_pass_through_data *ipt1 = &ajf1->value.pass_through;
6118 ipa_pass_through_data *ipt2 = &ajf2->value.pass_through;
6119 if (!ipa_agg_pass_through_jf_equivalent_p (ipt1, ipt2, true))
6120 return false;
6122 break;
6123 case IPA_JF_LOAD_AGG:
6125 ipa_load_agg_data *ila1 = &ajf1->value.load_agg;
6126 ipa_load_agg_data *ila2 = &ajf2->value.load_agg;
6127 if (!ipa_agg_pass_through_jf_equivalent_p (&ila1->pass_through,
6128 &ila2->pass_through, true))
6129 return false;
6130 if (ila1->offset != ila2->offset
6131 || ila1->by_ref != ila2->by_ref
6132 || !types_compatible_p (ila1->type, ila2->type))
6133 return false;
6135 break;
6136 default:
6137 gcc_unreachable ();
6139 return true;
6142 /* Return true if the two jump functions are known to be equivalent. The
6143 function can be used before the IPA phase of IPA-CP or inlining because it
6144 cannot cope with refdesc changes these passes can carry out. */
6146 bool
6147 ipa_jump_functions_equivalent_p (ipa_jump_func *jf1, ipa_jump_func *jf2)
6149 if (jf1->type != jf2->type)
6150 return false;
6152 switch (jf1->type)
6154 case IPA_JF_UNKNOWN:
6155 break;
6156 case IPA_JF_CONST:
6158 tree cst1 = ipa_get_jf_constant (jf1);
6159 tree cst2 = ipa_get_jf_constant (jf2);
6160 if (!values_equal_for_ipcp_p (cst1, cst2))
6161 return false;
6163 ipa_cst_ref_desc *rd1 = jfunc_rdesc_usable (jf1);
6164 ipa_cst_ref_desc *rd2 = jfunc_rdesc_usable (jf2);
6165 if (rd1 && rd2)
6167 gcc_assert (rd1->refcount == 1
6168 && rd2->refcount == 1);
6169 gcc_assert (!rd1->next_duplicate && !rd2->next_duplicate);
6171 else if (rd1)
6172 return false;
6173 else if (rd2)
6174 return false;
6176 break;
6177 case IPA_JF_PASS_THROUGH:
6179 ipa_pass_through_data *ipt1 = &jf1->value.pass_through;
6180 ipa_pass_through_data *ipt2 = &jf2->value.pass_through;
6181 if (!ipa_agg_pass_through_jf_equivalent_p (ipt1, ipt2, false))
6182 return false;
6184 break;
6185 case IPA_JF_ANCESTOR:
6187 ipa_ancestor_jf_data *ia1 = &jf1->value.ancestor;
6188 ipa_ancestor_jf_data *ia2 = &jf2->value.ancestor;
6190 if (ia1->formal_id != ia2->formal_id
6191 || ia1->agg_preserved != ia2->agg_preserved
6192 || ia1->keep_null != ia2->keep_null
6193 || ia1->offset != ia2->offset)
6194 return false;
6196 break;
6197 default:
6198 gcc_unreachable ();
6201 if (((jf1->m_vr != nullptr) != (jf2->m_vr != nullptr))
6202 || (jf1->m_vr && !jf1->m_vr->equal_p (*jf2->m_vr)))
6203 return false;
6205 unsigned alen = vec_safe_length (jf1->agg.items);
6206 if (vec_safe_length (jf2->agg.items) != alen)
6207 return false;
6209 if (!alen)
6210 return true;
6212 if (jf1->agg.by_ref != jf2->agg.by_ref)
6213 return false;
6215 for (unsigned i = 0 ; i < alen; i++)
6216 if (!ipa_agg_jump_functions_equivalent_p (&(*jf1->agg.items)[i],
6217 &(*jf2->agg.items)[i]))
6218 return false;
6220 return true;
6223 #include "gt-ipa-prop.h"